-1

I am trying to return an event log entry from the Windows security log using xPath (in PowerShell, in Event Viewer UI) and not succeeding.

This query doesn't work, as it returns zero results event though there is are appropriate entries in the log:

Get-WinEvent -FilterXPath "*[EventData[Data[@Name='CommandLine']='-ExecutionPolicy ByPass -File Do-Something.ps1']]" -LogName Security

The syntax of the query seems fine as changing the query value will return the expected results:

Get-WinEvent -FilterXPath "*[EventData[Data[@Name='CommandLine']='\??\C:\Windows\system32\conhost.exe 0xffffffff -ForceV1']]" -LogName Security

Same results if formatted as -FilterXML.

Alternative query strategy works, though is not efficient at all with big logs:

Get-WinEvent -LogName Security | Where-Object -Property Message -match '-ExecutionPolicy ByPass -File Do-Something.ps1'

So it seems that there is something in the xPath query value that is not quite kosher. I don't know what it is. What am I missing?

Here is EventData for the desired hit:

- <Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
- <System>
  <Provider Name="Microsoft-Windows-Security-Auditing" Guid="{54849625-5478-4994-a5ba-3e3b0328c30d}" /> 
  <EventID>4688</EventID> 
  <Version>2</Version> 
  <Level>0</Level> 
  <Task>13312</Task> 
  <Opcode>0</Opcode> 
  <Keywords>0x8020000000000000</Keywords> 
  <TimeCreated SystemTime="2020-02-19T15:17:13.982780900Z" /> 
  <EventRecordID>SCRUBBED</EventRecordID> 
  <Correlation /> 
  <Execution ProcessID="4" ThreadID="256" /> 
  <Channel>Security</Channel> 
  <Computer>SCRUBBED</Computer> 
  <Security /> 
  </System>
- <EventData>
  <Data Name="SubjectUserSid">SCRUBBED</Data> 
  <Data Name="SubjectUserName">SCRUBBED</Data> 
  <Data Name="SubjectDomainName">SCRUBBED</Data> 
  <Data Name="SubjectLogonId">SCRUBBED</Data> 
  <Data Name="NewProcessId">SCRUBBED</Data> 
  <Data Name="NewProcessName">C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe</Data> 
  <Data Name="TokenElevationType">%%1937</Data> 
  <Data Name="ProcessId">0x41c</Data> 
  <Data Name="CommandLine">-ExecutionPolicy ByPass -File Do-Something.ps1</Data> 
  <Data Name="TargetUserSid">S-1-0-0</Data> 
  <Data Name="TargetUserName">-</Data> 
  <Data Name="TargetDomainName">-</Data> 
  <Data Name="TargetLogonId">0x0</Data> 
  <Data Name="ParentProcessName">C:\Windows\System32\gpscript.exe</Data> 
  <Data Name="MandatoryLabel">SCRUBBED</Data> 
  </EventData>
  </Event>

Here is EventData for the other hit that works but isn't interesting to me:

- <Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
- <System>
  <Provider Name="Microsoft-Windows-Security-Auditing" Guid="{54849625-5478-4994-a5ba-3e3b0328c30d}" /> 
  <EventID>4688</EventID> 
  <Version>2</Version> 
  <Level>0</Level> 
  <Task>13312</Task> 
  <Opcode>0</Opcode> 
  <Keywords>0x8020000000000000</Keywords> 
  <TimeCreated SystemTime="2020-02-19T15:21:21.753690000Z" /> 
  <EventRecordID>SCRUBBED</EventRecordID> 
  <Correlation /> 
  <Execution ProcessID="4" ThreadID="96" /> 
  <Channel>Security</Channel> 
  <Computer>SCRUBBED</Computer> 
  <Security /> 
  </System>
- <EventData>
  <Data Name="SubjectUserSid">SCRUBBED</Data> 
  <Data Name="SubjectUserName">SCRUBBED</Data> 
  <Data Name="SubjectDomainName">SCRUBBED</Data> 
  <Data Name="SubjectLogonId">SCRUBBED</Data> 
  <Data Name="NewProcessId">SCRUBBED</Data> 
  <Data Name="NewProcessName">C:\Windows\System32\conhost.exe</Data> 
  <Data Name="TokenElevationType">%%1936</Data> 
  <Data Name="ProcessId">0x690</Data> 
  <Data Name="CommandLine">\??\C:\Windows\system32\conhost.exe 0xffffffff -ForceV1</Data> 
  <Data Name="TargetUserSid">S-1-0-0</Data> 
  <Data Name="TargetUserName">-</Data> 
  <Data Name="TargetDomainName">-</Data> 
  <Data Name="TargetLogonId">0x0</Data> 
  <Data Name="ParentProcessName">C:\Program Files\Windows Defender\MpCmdRun.exe</Data> 
  <Data Name="MandatoryLabel">SCRUBBED</Data> 
  </EventData>
  </Event>
Julian
  • 13
  • 3

2 Answers2

0

Enabling command line process auditing here to reproduce this: https://learn.microsoft.com/en-us/windows-server/identity/ad-ds/manage/component-updates/command-line-process-auditing

Searching for the NewProcessName first:

$a = Get-WinEvent -FilterXPath "*[EventData[Data[@Name='NewProcessName']='C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe']]" Security

And looking at the xml:

$a[1] | foreach { $xml = [xml]$_.toxml(); $xml.event.eventdata.data }

Name               #text
----               -----
SubjectUserSid     S-1-5-21-1528843147-373324174-1919417755-1001
SubjectUserName    admin
SubjectDomainName  DESKTOP-JQ7B7RP
SubjectLogonId     0x31db1a
NewProcessId       0x7c4
NewProcessName     C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
TokenElevationType %%1937
ProcessId          0x19d4
CommandLine         -ExecutionPolicy ByPass -File do-something.ps1
TargetUserSid      S-1-0-0
TargetUserName     -
TargetDomainName   -
TargetLogonId      0x0
ParentProcessName  C:\Windows\System32\gpscript.exe
MandatoryLabel     S-1-16-12288

It looks like there's strangely a space at the beginning and the end of the CommandLine property. The xml text is trimmed in event viewer. The spaces are still there with $xml.save('file.xml').

$a[1] | foreach { $xml = [xml]$_.toxml(); $xml.event.eventdata.data } | 
  where '#text' -match bypass | % { 'x' + $_.'#text' + 'x' }

x -ExecutionPolicy ByPass -File do-something.ps1 x

I ran this script as a group policy powershell login script.

Thus after adding the extra spaces, the nested predicate xpath becomes:

Get-WinEvent -FilterXPath "*[EventData[Data[@Name='CommandLine']=' -executionpolicy bypass -file do-something.ps1 ']]" Security


   ProviderName: Microsoft-Windows-Security-Auditing

TimeCreated                     Id LevelDisplayName Message
-----------                     -- ---------------- -------
2/21/2020 3:16:13 PM          4688 Information      A new process has been created....
2/21/2020 3:16:06 PM          4688 Information      A new process has been created....
2/21/2020 3:03:24 PM          4688 Information      A new process has been created....
2/21/2020 2:54:16 PM          4688 Information      A new process has been created....

Alternative less "nested" xpath expressions. Functions like text() or substring() can't be used with windows logs, or "//" or "/Event", for some reason.

get-winevent security -FilterXPath "*/EventData/Data[@Name='CommandLine']=' -ExecutionPolicy ByPass -File Do-Something.ps1 '"
get-winevent security -FilterXPath "*/*/*[@Name='CommandLine']=' -ExecutionPolicy ByPass -File Do-Something.ps1 '"
get-winevent security -FilterXPath "Event/EventData/Data[@Name='CommandLine']=' -ExecutionPolicy ByPass -File Do-Something.ps1 '"

In powershell 6 and above this can be reduced to:

get-winevent @{logname = 'security'; commandline = ' -executionpolicy bypass -file do-something.ps1 ' }
js2010
  • 23,033
  • 6
  • 64
  • 66
  • Yeah, you have to explicitly enable command-line contents logging to get this information (in this case, through a group policy setting). Unfortunately, I'm stuck on PS 5.1 right now. – Julian Feb 21 '20 at 16:51
  • What's the group policy setting? – js2010 Feb 21 '20 at 16:59
  • Computer Configuration\Administrative Templates\System\Audit Process Creation\Include command line in process creation events is enabled. This, in tandem with Computer Configuration\Windows Settings\Security Settings\Advanced Audit Policy Configuration\Detailed Tracking\Audit Process Creation configured to Success. – Julian Feb 24 '20 at 14:30
  • Winner winner chicken dinner. – Julian Feb 24 '20 at 15:08
0

Try to see if this works:

Get-WinEvent -LogName Security -FilterXPath "//Event//Data[@Name='CommandLine'][text()='-ExecutionPolicy ByPass -File Do-Something.ps1']"
Jack Fleeting
  • 24,385
  • 6
  • 23
  • 45
  • It doesn't work. I think it has to return the Event node. – js2010 Feb 19 '20 at 17:58
  • @js2010 - If the Event node is the target, than it doesn't work indeed. Maybe OP should clarify a little more what exactly he's looking for... – Jack Fleeting Feb 19 '20 at 18:11
  • it's just the way filtering the windows logs works; it's a little different than xpath with a file. – js2010 Feb 19 '20 at 18:40
  • @js2010 - Maybe changing the xpath expression to `//Event[//Data[@Name='CommandLine'][text()='-ExecutionPolicy ByPass -File Do-Something.ps1']]` will do the trick? – Jack Fleeting Feb 19 '20 at 18:56
  • 1
    Yes, it should return the event object that contains the search string in data node named CommandLine. MS uses a cut-down version of XPath 1.0 for event log filtering. I think it's because of this that @JackFleeting's modified queries won't work unfortunately. – Julian Feb 21 '20 at 16:38
  • 1
    @julian RIght, I don't think you can use // or text() or /Event. This works for me. It turns out there was a space at the beginning and end in the original xml, that the event viewer removes. `"*/EventData/Data[@Name='CommandLine']=' -ExecutionPolicy ByPass -File Do-Something.ps1 '"` – js2010 Feb 22 '20 at 16:20
  • @Julian At least it's case insensitive. – js2010 Feb 24 '20 at 15:07
  • You're kidding @js2010. Now that I look at the UI, there are spaces before and after but not in the UI XML. Thanks for helping me track this down. – Julian Feb 24 '20 at 15:08