Query XML Event Log Data Using XPath in Windows Server 2012 R2

In a previous Ask the Admin, Creating Custom Views in Windows Server 2012 R2 Event Viewer on the Petri IT Knowledgebase, I showed you how to make Event Viewer a more useful tool by creating custom views. Today I’m going to demonstrate how to create more complex filters to make your custom views even more valuable.

Filtering the Event Logs

The core System, Application, and Security event logs contain lots of information that needs to be filtered before it becomes beneficial. In order to do that effectively, it’s also necessary to have some understanding of the data that events contain. For instance, we know the Event ID 4624 indicates that an account was successfully logged on, but this information only becomes really useful if we can identify particular types of logon that should be raised as suspicious.

Let’s consider an example where we want to raise all Remote Desktop logons as suspect. Event ID 4624 also contains data that shows the Logon Type, and when this value is 10 it indicates a logon using Remote Desktop. But when looking at the Security log in Event Viewer, it’s impossible to separate Remote Desktop logons from any other kind of logon without opening each event and looking for the logon type in the event data.

Similarly when creating a custom view in Event Viewer using the Filter tab, there’s no means of viewing only logon events of a certain logon type. To do that, we need to enter an XPath query on the XML tab to query the XML event data. Even something relatively simple, such as filtering all User Account Management events from the Forwarded Events log isn’t possible without writing your own custom filter on the XML tab. You’ll see on the Filter tab that you can’t select a task category, such as User Account Management, unless you filter events By source, which precludes selecting the Forwarded Events log.

Create Custom Views using XPath

Open Event Viewer and create a new custom view as outlined in Creating Custom Views in Windows Server 2012 R2 Event Viewer. Switch to the XML tab and check Edit query manually at the bottom of the dialog. Now paste the code below into the XPath form and click OK.

Creating a custom filter on the XPath form in Event Viewer (Image Credit: Russell Smith)
Creating a custom filter on the XPath form in Event Viewer (Image Credit: Russell Smith)
<QueryList>
  <Query Id="0" Path="ForwardedEvents">
    <Select Path="ForwardedEvents">*[System[Provider[@Name='Microsoft-Windows-Security-Auditing'] 
and Task = 13824 and TimeCreated[timediff(@SystemTime) &lt;= 86400000]]]</Select>
  </Query>
</QueryList>

The above XPath statement queries the Forwarded Events log for User Account Management events from the last 24 hours. Most of this query I built up using the GUI menus on the Filter tab, and then I switched to the XML tab to tweak the XPath statement to my liking.

Let’s create a custom view that shows us all Remote Desktop logons from the Security log.

<QueryList>
  <Query Id="0" Path="Security">
    <Select Path="Security">*[System[(Level=4 or Level=0) and (EventID=4624 or EventID=4634)]] and 
*[EventData[Data[@Name='LogonType']='10']] and (*[EventData[Data[5]='10']] or 
*[EventData[Data[@Name='AuthenticationPackageName']='Negotiate']])</Select>
  </Query>
</QueryList>

The query looks for event IDs 4624 or 4634, logon and logoff respectively, in the Security log where the Logon Type data field is set to 10.

A custom view to show Remote Desktop logons only (Image Credit: Russell Smith)
A custom view to show Remote Desktop logons only (Image Credit: Russell Smith)

Finally, here’s a query that looks for successful NTLM logons that are made by non-domain users, with the exception of anonymous logons. The exclamation mark in the query indicates NOT, so NOT AD, which is the NetBIOS name of my domain. This query can show up potential Pass-the-Hash attacks in domain environments.

<QueryList>
  <Query Id="0" Path="Security">
    <Select Path="Security">*[System[(Level=4 or Level=0) and (EventID=4624)]] and 
*[EventData[Data[@Name='LogonType'] and (Data='3')]] and 
*[EventData[Data[@Name='AuthenticationPackageName'] ='NTLM']] and 
*[EventData[Data[@Name='TargetUserName'] !='ANONYMOUS LOGON']] and 
*[EventData[Data[@Name='TargetDomainName'] !='AD']]</Select>
   </Query>
</QueryList>