PowerShell and security auditing

PowerShell and security auditing



Welcome habanero! I want to share with you a way that can facilitate routine routine system administration Win system using PowerShell.
One day I faced the daily task of tracking users who use the terminal server as a workstation. I think I'm not only expressing my opinion, saying that "event Viewer" is part of the Windows administrative tools, is not the most convenient means of tracking the situation on the server. Yes there is a filter by which to filter out only the events, but there is no convenient way which changes the display format of this information. As a result, and had the idea of using PowerShell to parse the security log events.

For a list of events we need the command Get-EventLog one of the parameters which is the name of the journal, in our case security.

image

Command displays the contents of the whole log, that fundamentally does not suit me. But it's not as bad what you see in the screenshot, not just text, but it is a objects, with properties where you can do anything within the capabilities of PowerShell. Get properties of these objects allows the cmdlet Get-Member. By running at the command line, Get-EventLog security | Get-Member, we will get a result list of properties of all the objects output by Get-EventLog.

image

Knowing the list of properties, you can manipulate the results of the work of Get-EventLog. For example, to list all events for today, the easiest way would be to use the parameters of Get-EventLog, namely the -after. Full list of parameters can be found here. In the result, we get the command Get-EventLog security-after (Get-date-hour 0-minute 0 -second 0), where the Get-Date cmdlet produces the current date and time, but the parameters hour, minute and second specify the output time from the beginning of the current day. As a result, we get a list of events occurring today. Better, but still not the same.
I need to get a list of all users who logon to the server by RDP Protocol, which led me to the study of values and EventID EntryType. Next, I will not a complete list of these values.

EventID Values

Every event entering the system is complemented by specific entry type, a list of which will be listed below.

the
    the
  • 528 — a user Successfully logged on to the computer.
  • the
  • 529 — Failure login. Not the right username or password.
  • the
  • 530 error login. Attempt logon with a user account outside of the allowed time.
  • the
  • 531 — failure of the login. Attempt to login using disabled user account.
  • the
  • 532 — Failure login. Attempt to login using the old user account.
  • the
  • 533 — Failure login. Attempt to login a user who cannot log on to this computer.
  • the
  • 534 — Failure login. The login attempt to the system with indication of unauthorized entry type.
  • the
  • 535 — Refusing login. The validity of the password for the specified account has expired.
  • the
  • 536 — Failure login. The Net Logon service is disabled.
  • the
  • 537 — failure of the login. Attempt login failed for other reasons (In some cases, the cause of failure login can be unknown).
  • the
  • 538 — the logoff Process of the user of the system is complete.
  • the
  • 539 — Failure login. During the attempt to logon the user account is locked.
  • the
  • 540 — a user Successfully logged on to the network.
  • the
  • 541-Completed the basic authentication mode in the IKE Protocol between the local computer and the listed peer identity (establishing a security Association), or quick mode has established a data channel.
  • the
  • 543 — Main mode was terminated.(The reason for this could be the end of the time limit on the security Association expiring (the default is 8 hours), policy changes, or peer termination).
  • the
  • 544 — Failure main mode authentication due to the fact that the partner did not provide a valid certificate or is not confirmed the authenticity of the signature.
  • the
  • 545 — the failure of the primary mode of authentication for Kerberos failure or invalid password.
  • the
  • 546 — Failure to create a reliable connection, IKE, caused by the receipt from the partner of the unacceptable proposals. A packet was received that contains incorrect data.
  • the
  • 547 — Failure during the procedure, a connection is established IKE.
  • the
  • 548 — Failure login. The security ID (SID) from a trusted domain does not match the SID of the domain account for the client.
  • the
  • 549 — Failure login. All SIDS corresponding to untrusted namespaces were filtered out during an authentication across forests.
  • the
  • 550 — the notification Message that could indicate a possible denial of service attack.
  • the
  • 551 User initiated logoff process from the system.
  • the
  • 552 — a User successfully logged on to a computer using explicit credentials while already logged on as another user.
  • 682 — a User has reconnected to a disconnected terminal server session. the

  • 683 — a User disconnected from a terminal server session without exiting the system (This event is generated when the user connected to terminal server session through the network. It appears on the terminal server).

the Value of EntryType

the
    the
  • 2 — Interactive. A user successfully logged on to the computer.
  • the
  • 3 — Network. The user or computer logged on to this computer through the network.
  • the
  • 4 — Batch. Batch logon type is used by batch servers, the execution of processes which is carried out on behalf of a user without their direct intervention.
  • the
  • 5 Service. The service is started Service Control Manager.
  • the
  • 7 — Unlock. This workstation was unlocked.
  • the
  • 8 — NetworkCleartext. A user logged on to this computer from the network. The user password passed to the authentication package in its necessitavano form. Built-in authentication packages all hash credentials before sending them across the network. Credentials are not transmitted over the network in clear text.
  • the
  • 9 — NewCredentials. A caller cloned its current token and specified new credentials for outbound connections. A new session logon has the same local identity, but uses different credentials for other network connections.
  • the
  • 10 — RemoteInteractive. The user performed a remote login to this computer using Terminal Services or Remote Desktop.
  • the
  • 11 — CachedInteractive. The user logged on to this computer with network credentials that were stored locally on the computer. The domain controller was not used to validate credentials.


This information is drawn largely from that source. From the findings it can be concluded that we need an event with EventID = 528 and EntryType = 10 that would correspond to log on to the computer via RDP. Change our team.
Get-EventLog security -message "*logon Type:?10*" -after (Get-date-hour 0-minute 0 -second 0) | ?{$_.eventid -eq 528 }

Option -message fully reflect the message of our event, which contains the "Entry type" (Type"input", because I have Russian version of the 2003rd), using the patterns we set the search string of interest to us.

Because I have not found the cmdlet parameters Get_EventLog EventID, then had to use the object's properties:
$_ means the object itself which appears initially
-eq means equal value, in our case 528

The output is the following:
image

In General, what you need, but only now appears to us is not the same information. We will fix it. For me important are the three parameters of the object, this: time, user name, IP address. In the future, let us create an object and put into it the required data. I created a script “test.ps1 script” because the team as a whole will be difficult to gain.

$Events = Get-EventLog security -message "*logon Type:?10*" -after (get-date-hour 0-minute 0 -second 0) | ?{$_.eventid -eq 528 }

$Data = New-Object System.Management.Automation.PSObject
$Data | Add-Member NoteProperty Time ($null)
$Data | Add-Member NoteProperty UserName ($null)
$Data | Add-Member NoteProperty Address ($null)

$Events | %{

$Data.time = $_.TimeGenerated

$message = $_.message.split("`n") | %{$_.trimstart()} | %{$_.trimend()}

$Data.UserName = ($message | ?{$_ -like "User:*"} | %{$_ -replace "^.+:."} )
$Data.Address = ($message | ?{$_ -like "source network Address:*"} | %{$_ -replace "^.+:."})

$data

}


Let us examine this code a little closer.
$Events = Get-EventLog security -message "*logon Type:?10*" -after (get-date-hour 0-minute 0 -second 0) | ?{$_.eventid -eq 528 } — a recorded the results of sampling events in a variable that would later be comfortable with it.

Next, let's create the template for our future table containing three values: time, user name and address.
$Data = New-Object System.Management.Automation.PSObject
$Data | Add-Member NoteProperty Time ($null)
$Data | Add-Member NoteProperty UserName ($null)
$Data | Add-Member NoteProperty Address ($null
)


$Events | %{} — iterate over each object, which will be the results of selection

$Data.time = $_.TimeGenerated — a recorded time
$message = $_.message.split("`n") | %{$_.trimstart()} | %{$_.trimend()} — variable a recorded message an array of strings separated by newline ('n), function trimstart(), trimend() remove all unnecessary characters in the end and the beginning of the string, the split function breaks a string.
$Data.UserName = ($message | ?{$_ -like "User:*"} | %{$_ -replace "^.+:."} )
$Data.Address = ($message | ?{$_ -like "source network Address:*"} | %{$_ -replace "^.+:."})
Then in the newly formed array looking for a match on the string "User:" and "source network Address:", and -replace in the future removes these regular expressions, leaving the information itself.

Run the script with the command .\test.ps1. (See how to run PS script you have to specify the path, even if it is in the current working directory):
image

If the script does not start, then most likely your PoSh is not configured to run scripts. Run the command Set-ExecutionPolicy RemoteSignet .

Looks pretty good, but I think you can improve the script. For convenience, introduce the ability to specify parameters, and row highlight color for the mask IP address.

the param ($key1,$val1,$val2,$val3,$val4,$val5,$val6)

if ($val1 -eq $null) {$val1=0};

$mydate = Get-date-hour 0-minute 0 -second 0;

if ($key1 -eq "year") { $mydate = (Get-date-hour 0-minute 0 -second 0-day 1-month 1); $mydate = $mydate.addyears(-$val1); };

if ($key1 -eq "month") { $mydate = (Get-date-hour 0-minute 0 -second 0-day 1); $mydate = $mydate.addmonths(-$val1); };

if ($key1 -eq "day") { $mydate = $mydate.adddays(-$val1) };

if ($key1 -eq "date") { $mydate = (Get-date-hour 0-minute 0 -second 0-day $val1 -month $val2 -year $val3); }; # here we implement the ability to set the interval

if ($val4 -eq $null) {$Events = Get-EventLog security -message "*logon Type:?10*" -after ($mydate) | ?{$_.eventid -eq 528 }}
if ($val4 -ne $null) {$Events = Get-EventLog security -message "*logon Type:?10*" -after ($mydate) -before (get-date-hour 0-minute 0 -second 0-day $val4 -month $val5 -year $val6) | ?{$_.eventid -eq 528 }}
$Data = New-Object System.Management.Automation.PSObject
$Data | Add-Member NoteProperty Time ($null)
$Data | Add-Member NoteProperty UserName ($null)
$Data | Add-Member NoteProperty Address ($null)

$Events | %{

$Data.time = $_.TimeGenerated

$message = $_.message.split("`n") | %{$_.trimstart()} | %{$_.trimend()}

$Data.UserName = ($message | ?{$_ -like "User:*"} | %{$_ -replace "^.+:."} )
$Data.Address = ($message | ?{$_ -like "source network Address:*"} | %{$_ -replace "^.+:."})

$textcolor = $host.ui.rawui.foregroundcolor

$host.ui.rawui.foregroundcolor = "red"

if ($data.address-like "192.168.0*") {$host.ui.rawui.foregroundcolor = "DarkGreen"}
if ($data.address-like "10.*") {$host.ui.rawui.foregroundcolor = "yellow"}

$data

$host.ui.rawui.foregroundcolor = $textcolor

}


the param ($key1,$val1,$val2,$val3,$val4,$val5,$val6) — specifies the parameters passed to the script.

if ($key1 -eq "day") { $mydate = $mydate.adddays(-$val1) };; check the passed parameters for compliance with the key if the key matches, then the corrected date according to the specified parameters. In this case, as a parameter to the key "day" argument which we will translate the date into a certain number of days ago. Ie log will be shown for a certain number of days, the remaining conditions are similar, per month and per year. If you specify the key date for the origin is taken to be the specific date indicated by a space, e.g. "01 05 2011" if we had the same with a space will specify another date, then the screen will display a certain period of time specified in these dates. For color, it was originally planned to use the Write-Host cmdlet, which has parameters -backgroundcolor and -foregroundcolor, but in the end had to abandon it because it doesn't work with output objects.
image

I did display the internal LAN atom green, yellow exterior and all other unknown addresses are red, for clarity.

And if you set {$_.eventid -eq 529 } then the result will be all login attempts with incorrect passwords.

image

The list came out pretty long, useful a couple of times a day to check and block at firewall such villains.

The result is a script with minimal modification can be adapted for convenient display of any information contained in the event Log.
Article based on information from habrahabr.ru

Комментарии

Популярные сообщения из этого блога

Address FIAS in the PostgreSQL environment. Part 4. EPILOGUE

PostgreSQL: Analytics for DBA

Audit Active Directory tools with Powershell releases. Part 1