Thursday, February 27, 2014

Avoiding XPath: Part IV

 Full source  of my unpolished cruft is far below.  If you are going to pull fields out of the Message in Windows Event log without Xpath or XML, how are you going to do it in Powershell 4.0? I will remind you of what the Message field looks like:


Message              : The Windows Filtering Platform has permitted a connection.

                       Application Information:
                           Process ID:        3116
                           Application Name:    \device\harddiskvolume3\users\rferrisx\appdata\local\chromium\application\chrome.exe

                       Network Information:
                           Direction:        Outbound
                           Source Address:        192.168.0.11
                           Source Port:        2094
                           Destination Address:    8.247.65.200
                           Destination Port:        80
                           Protocol:        6

                       Filter Information:
                           Filter Run-Time ID:    211332
                           Layer Name:        Connect
                           Layer Run-Time ID:    48

So I can get to these fields with 'properties':




get-winevent -max 1 | Select Id,@{l='Properties';e={$_.Properties.get_value()}} | ft * -auto -wrap

  Id Properties
  -- ----------
5156 {3116, \device\harddiskvolume3\users\rferrisx\appdata\local\chromium\application\chrome.exe, %%14593, 192.168.0.11...}

(or)
PS C:\ps1>  (get-winevent -max 1).properties | ft  * -auto -wrap


                                               Value
                                               -----
                                                 128
\device\harddiskvolume3\windows\system32\svchost.exe
                                             %%14592
                                     255.255.255.255
                                                  67
                                             0.0.0.0
                                                  68
                                                   0
                                              212554
                                             %%14610
                                                  44
                                             S-1-0-0
                                             S-1-0-0



I can do this recursively with the key syntax ('Properties[3]') where I effectively subset out the fourth field (e.g. 0..3):

$b2=($b | where ID -eq "5156")
Event5156=0..($b2.count -1) | % {foreach ($i in ([array]$b2[$PSItem].Properties)[3])  {[array]@{$b2[$PSItem].RecordID=$i.get_value()}}}

From which follows:


$E5156 = ($EventArray).Event5156.GetEnumerator()| % {New-Object PSObject -Property ([ordered]@{RecordID=$($_.Keys);IPs=$($_.Values)})}

Which gives me:
 $E5156[0..10]


                                         RecordID IPs                                            
                                         -------- ---                                            
                                         66428320 127.0.0.1                                      
                                         66428319 192.168.0.11                                  
                                         66428318 192.168.0.11                                  
                                         66428316 192.168.0.11                                  
                                         66428314 192.168.0.11                                  
                                         66428312 192.168.0.11                                  
                                         66428310 192.168.0.11                                  
                                         66428308 192.168.0.11                                  
                                         66428306 192.168.0.11                                  
                                         66428304 192.168.0.11                                  
                                         66428302 192.168.0.11



If I capture the 'Source' field  ('Application Name' for 4688 but 'SourceIP' for 5156,5157,5158)  I do this:

$x2 = $EventArray.Event4688 + $EventArray.Event5156 + $EventArray.Event5157 + $EventArray.Event5158 | sort Keys

I can then do this:


$OT2 = $x2.GetEnumerator()| % {New-Object PSObject -Property ([ordered]@{RecordID = $($_.Keys);Source = $($_.Values)})}

Which gives me:
$OT2[0..10]

                                         RecordID Source                                        
                                         -------- ------                                        
                                         66408533 192.168.0.11                                  
                                         66408534 192.168.0.11                                  
                                         66408535 ::1                                            
                                         66408536 192.168.0.11                                  
                                         66408537 0.0.0.0                                        
                                         66408538 192.168.0.11                                  
                                         66408539 0.0.0.0                                        
                                         66408540 192.168.0.11                                  
                                         66408541 0.0.0.0                                        
                                         66408542 0.0.0.0                                        
                                         66408543 255.255.255.255



#Start  script********************************
function gwe {
$computer=hostname
$Global:enddate=[DateTime]::Now
$Global:startdate=([DateTime]::Now).AddHours(-24)
Get-Winevent -computername $computer  -FilterHashtable @{
           LogName = "security"; `
           EndTime = $Enddate ; `
      StartTime = $Startdate; `
   }}

function gwe# {
$computer=hostname
$Global:enddate=[DateTime]::Now
$Global:startdate=([DateTime]::Now).AddHours(-24)
Get-Winevent -computername $computer  -FilterHashtable @{
           LogName = "security"; `
           EndTime = $Enddate ; `
      StartTime = $Startdate;
  ID = @("4688","5156","5157","5158") }}

write " Start Date: $StartDate"
write " End Date: $EndDate "
write "Grabbing the entire Security Log for the last $(($Enddate - $Startdate).days) days."
$a=gwe
write " All Event Totals:"
$a.get_id() | group -no | sort -desc Count
write "Grabbing sorted count of EventIDs from the Security Log: "4688","5156","5157","5158" for the last $(($Enddate - $Startdate).days) days."
$b=gwe#
write " Filtered Events Totals:"
$b.get_id() | group -no | sort -desc Count

$b1=($b | where ID -eq "4688")
$b2=($b | where ID -eq "5156")
$b3=($b | where ID -eq "5157")
$b4=($b | where ID -eq "5158")

write " All Events = $($a.count)"
write " Filtered Events = $($b1.count + $b2.count + $b3.count + $b4.count)"

# Chooses Source IP Address for Firewall Events: 5156,5157,5158
# Chooses Application Name for Process start Events 4688
write " Creating Accumulating Variable 'EventArray' with these specific Properties: Events,Event4688,Event5156,Event5157,Event5158."
rv -ea 0 EventArray
[Array]$EventArray+=[PSCustomObject]@{
Events=0..($b.count -1) | % {foreach ($i in ([array]$b[$PSItem]))  {[array]@{$b[$PSItem].RecordID=$b[$PSItem].ID}}} ;
Event4688=0..($b1.count -1) | % {foreach ($i in ([array]$b1[$PSItem].Properties)[5])  {[array]@{$b1[$PSItem].RecordID=$i.get_value()}}} ; `
Event5156=0..($b2.count -1) | % {foreach ($i in ([array]$b2[$PSItem].Properties)[3])  {[array]@{$b2[$PSItem].RecordID=$i.get_value()}}} ; `
Event5157=0..($b3.count -1) | % {foreach ($i in ([array]$b3[$PSItem].Properties)[3])  {[array]@{$b3[$PSItem].RecordID=$i.get_value()}}} ; `
Event5158=0..($b4.count -1) | % {foreach ($i in ([array]$b4[$PSItem].Properties)[2])  {[array]@{$b4[$PSItem].RecordID=$i.get_value()}}} ; `
} | Select Events,Event4688,Event5156,Event5157,Event5158

# Create some hashtables for later analysis
write " Creating these hashtables x1 - x5 x1:RecordID+EventID x2:RecordID+Source."
$x1 = $EventArray.Events | sort Keys
$x2 = $EventArray.Event4688 + $EventArray.Event5156 + $EventArray.Event5157 + $EventArray.Event5158 | sort Keys
$x3 = [ordered]@{$x1=$x2} # combine all hashes to create pscustom object below 'EventArray0'.
$x3ID =$x3.Values.Keys
$x4 =($x3.Keys | sort -unique Keys).Values
$x5 = ($x3.Values | sort -unique Keys).Values

write " Creating Accumulating Variable 'EventArray0' with these PSCustomObjects: RecordID,EventID,Source."
rv -ea 0 EventArray0
[Array]$EventArray0+=[PSCustomObject]@{
RecordID=$x3ID;
EventID=$x4;
Source=$x5;
} | Select RecordID,EventID,Source

#END Script *************************************

#Some sample investigative uses:
#$EventArray0.RecordID | out-file EA0.RecordID.txt
#$EventArray0.EventID | out-file EA0.EventID.txt
#$EventArray0.Source | out-file EA0.Source.txt

#$E5156 = ($EventArray).Event5156.GetEnumerator()| % {New-Object PSObject -Property ([ordered]@{RecordID=$($_.Keys);IPs=$($_.Values)})}
#$E5156 | Export-CSV E5156.csv -NoTypeInformation

#$OT1 = $x1.GetEnumerator()| % {New-Object PSObject -Property ([ordered]@{RecordID = $($_.Keys);EventID = $($_.Values)})}
#$OT2 = $x2.GetEnumerator()| % {New-Object PSObject -Property ([ordered]@{RecordID = $($_.Keys);Source = $($_.Values)})}
#$OT1 | Export-CSV OT1.csv -NoTypeInformation
#$OT2 | Export-CSV OT1.csv -NoTypeInformation

#($x2).Values | group -NoElement | sort -Descending Count | ft -AutoSize
#rv c
#foreach  ($i in (($x2 | where Values -eq "192.168.0.11").Keys)) {[Array]$c+=(($b | where RecordID -eq $i).Message | findstr /C:"Destination Address:").replace("Destination Address:","")}

1 comment: