PowerShell and Security Auditing

PowerShell and Security Auditing



Greetings to habranarod! I want to share with you a way that can facilitate the routine routine of system administration of a Win system using PowerShell.
One fine day, I faced the task of daily monitoring the activity of users who use the terminal server as workstations. I think I will express not only my opinion, saying that "Event Viewer", which is part of the Windows administration tools, is not the most convenient way to monitor the situation on the server. Yes there is a filter by which you can filter out only the events of interest to us, but there is no convenient way that changes the display format of this information. As a result, the idea came up using PowerShell to parse security log events.

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

image

The command displays the contents of the entire log, which fundamentally does not suit me. But everything is not so bad, what you see in the screenshot is not just text, but quite objects, with the properties of which you can do anything you want within the framework of PowerShell. Get the properties of these objects allows the Get-Member cmdlet. By executing on the command line Get-EventLog security | Get-Member, we get a list of properties of all objects displayed by Get-EventLog.

image

Knowing the list of properties, you can manipulate the results of Get-EventLog. For example, to get a list of all the events for today, the easiest way would be to use the parameters of the Get-EventLog cmdlet, namely the parameter -after. A complete list of parameters can be found here . As a result, we get a command Get-EventLog security -after (Get-date -hour 0 -minute 0 -second 0)where the Get-Date cmdlet displays the current date and time, but the hour, minute, and second parameters specify the time output from the beginning of the current day. As a result, we get a list of events that happened today. Already better, but still not that.
I need to get a list of all users who logged into the server using the RPD protocol, which led me to study the values ​​of EventID and EntryType. Next, I will provide an incomplete list of these values.

EventID Values

Each login event is complemented by a specific login type, a list of which will be listed below.

  • 528 - Successful user login to the computer.
  • 529 - Login failure. Invalid username or password.
  • 530 - Login failure. An attempt was made to log in with a user account outside the valid time interval.
  • 531 - Login failure. Attempted to log in using a disabled user account.
  • 532 - Login failure. An attempt was made to log in using an outdated user account.
  • 533 - Login failure. An attempt was made to log on to a user who is not allowed to log on to this computer.
  • 534 - Login failure. Attempted login with an unauthorized login type.
  • 535 - Login failure. The password for the specified account has expired.
  • 536 - Login failure. Net Logon service is disabled.
  • 537 - Login failure. An attempt to enter the system failed for other reasons (In some cases, the reason for the refusal to enter the system may not be known).
  • 538 - The user logout process is completed.
  • 539 - Login failure. During the login attempt, the user account is locked.
  • 540 - Successful user login to the network.
  • 541 - The basic IKE authentication mode between the local computer and the registered peer identity (establishing a reliable association) is completed, or the fast mode has established a data channel.
  • 542 - The data channel is disabled.
  • 543 - The main mode is disabled. (The reason for this may be the end of the time interval limiting the duration of a reliable connection (default is 8 hours), a policy change, or peer termination).
  • 544 - Failure of the basic authentication mode due to the fact that the partner did not provide a valid certificate or the signature is not authenticated.
  • 545 - Primary authentication mode failed due to Kerberos failure or invalid password.
  • 546 - Failure to create a reliable IKE connection caused by an unacceptable offer from a partner. Receive a packet containing invalid data.
  • 547 - Failure during the IKE connection establishment procedure.
  • 548 - Login failure. The reliability identifier (SID) received from the trusted domain does not match the SID of the domain account for the client.
  • 549 - Login failure. All SIDs corresponding to untrusted namespaces were filtered out during forest authentication.
  • 550 - Notification message, which may indicate a possible attack on the service.
  • 551 - The user initiated the logout process.
  • 552 - The user successfully logged on to the computer using the correct credentials, despite the fact that before that he was logged in as another user.
  • 682 - The user is reconnected to a disconnected terminal server session.
  • 683 - The user is disconnected from the terminal server session without logging out (This event is generated when the user is connected to the terminal server session through the network. It appears on the terminal server).

EntryType Values

  • 2 - Interactive. Successful user login to the computer.
  • 3 - Network. The user or computer logged onto the computer through the network.
  • 4 - Batch. The batch type of entry is used by batch servers, the execution of processes on which is carried out on behalf of the user, but without his direct intervention.
  • 5 - Service. The service is started by Service Control Manager.
  • 7 - Unlock. This workstation is unlocked.
  • 8 - NetworkCleartext. The user logged on to the computer through the network. The user password has been passed to the authentication packet in its unshed form. Integrated authentication packs all hashed accounts before sending them over the network. Credentials are not transmitted over the network in clear text.
  • 9 - NewCredentials. The visitor cloned his current token and specified new accounts for outgoing connections. The new login session has the same local identity, but uses different accounts for network connections.
  • 10 - RemoteInteractive. A user has logged on to this computer remotely using Terminal Services or Remote Desktop.
  • 11 - CachedInteractive. A user logged on to this computer with network credentials that were stored locally on the computer. The domain controller was not used to verify credentials.


This information is drawn mainly from this source . From the information obtained, we can conclude that we need an event with EventID = 528 and EntryType = 10, which will correspond to the input to the computer through RDP. Let's change our team a bit.
Get-EventLog security -message "*Тип входа:?10*" -after (Get-date -hour 0 -minute 0 -second 0) | ?{$_.eventid -eq 528 }

The parameter -messagefully reflects the message of our event, which contains the "Entry type" ("Input Type", since I have the Russian version of 2003), through the templates we set the search for the line of interest to us.

Since I did not find Get_EventLog in the parameters of the cmdlet -EventID, I had to use the properties of the object’s properties: it
$_means the object itself that appears originally
-eqmeans equality to the value, in our case 528

The result of execution will be the following:

image

In general, what is needed, but only the wrong information is displayed to us. We will correct it. Three parameters of the object are relevant for me, these are: time, username, IP address. In the future, create an object, and enter the data of interest to us. I created the script “test.ps1”, because the whole team will be problematic to type. Let's take a closer look at this code. - we enter the results of the sample of events into a variable, so that it would be convenient to work with it in the future. Next, create a “template” for our future table containing three values: time, username and address. ) - we will go through each object that will be in the selection results - we enter the time

$Events = Get-EventLog security -message "*Тип входа:?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 "Пользователь:*"} | %{$_ -replace "^.+:."} )
$Data.Address = ($message | ?{$_ -like "Адрес сети источника:*"} | %{$_ -replace "^.+:."})

$data

}



$Events = Get-EventLog security -message "*Тип входа:?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()}- in the message variable we enter an array of lines that are separated by a line break character ('n), the trimstart (), trimend () functions remove all the extra characters at the end and at the beginning of the line, the split function separates the line. Next, in the newly formed array, we look for matches on the line "User:" and "Source network address:", and -replace further removes these regular expressions, leaving the information itself. Run the script with the command . (As you can see, to run the PS script you have to specify the path, even if it is in the current working folder): If the script did not start, then most likely your PoSh is not configured to run scripts. Run the command .
$Data.UserName = ($message | ?{$_ -like "Пользователь:*"} | %{$_ -replace "^.+:."} )
$Data.Address = ($message | ?{$_ -like "Адрес сети источника:*"} | %{$_ -replace "^.+:."})


.\test.ps1
image

Set-ExecutionPolicy RemoteSignet

It looks pretty good, but I think you can improve the script. For convenience, we’ll add the ability to set parameters to it, and highlight lines with color using the IP address mask. - defines the parameters passed to the script.

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); }; # здесь реализуем возможность задания интервала

if ($val4 -eq $null) {$Events = Get-EventLog security -message "*Тип входа:?10*" -after ($mydate) | ?{$_.eventid -eq 528 }}
if ($val4 -ne $null) {$Events = Get-EventLog security -message "*Тип входа:?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 "Пользователь:*"} | %{$_ -replace "^.+:."} )
$Data.Address = ($message | ?{$_ -like "Адрес сети источника:*"} | %{$_ -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

}


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

if ($key1 -eq "day") { $mydate = $mydate.adddays(-$val1) };; we check the transferred parameters for compliance with the key, if the key matches, then we adjust the date according to the specified parameters. In this case, the “day” key is passed as a parameter with the argument of which we will translate the date a certain number of days ago. Those. a log will be displayed for a certain number of days, the remaining conditions are fulfilled by analogy, for a month and for a year. If the “date” key is specified, then the specific date specified with a space is taken as the starting point, for example, “01 05 2011”, if we also indicate a different date with a space, a certain period indicated on these dates will be displayed on the screen. To output information in color, it was originally planned to use the Write-Host cmdlet, which has the parameters -backgroundcolor and -foregroundcolor, but in the end I had to abandon it because it is not friends with the output of objects.

image

I made the display of the internal local network a green color, the external yellow and all other unfamiliar addresses red, for clarity.

And if you ask, {$_.eventid -eq 529 }the result will be all login attempts with the wrong passwords.

image

The list was pretty long, it’s useful to check and block such villains on the firewall a couple of times a day.

As a result, the script, with minimal modification, can be adapted to conveniently display any information contained in the Event Log.

Also popular now: