Wednesday, June 26, 2024
HomePowershellMonitoring Down Consumer Logons with PowerShell and XPath

Monitoring Down Consumer Logons with PowerShell and XPath


When working with Home windows occasion logs, particularly the Safety log, there is likely to be cases the place you could extract particular data from occasions.

However you’ll discover out, it’s not as straightforward as you’d anticipate.

Not too long ago, I wanted to question Home windows occasions from the Safety occasion log for consumer logon occasions (Occasion ID 4624 to be particular). However not all occasions, simply occasions matching a particular username syntax of domain_name/username.

Be part of me on a journey of Home windows occasion logs, XML and XPath as we parse Home windows occasion logs with PowerShell. To show, let’s stroll by means of an instance.

Question the Occasion Log with Get-WinEvent

You first want to tug no less than one Home windows occasion. Since I’m working with consumer logon occasions, I’ll pull only one occasion for instance with occasion ID 4624.

$eventRecord = Get-WinEvent -MaxEvents 1 -FilterHashtable @{LogName="Safety";ID=4624}

Performed! You now have an System.Diagnostics.Eventing.Reader.EventLogRecord object.

Convert the Occasion Document to XML

Now, this tutorial can be fairly brief if I simply wanted to filter on primary properties like Id or TimeCreated however sadly, I must filter data from an occasion’s Message subject. Get-WinEvent doesn’t create a pleasant object for us to question. As an alternative, you could construct your personal.

To take action, you could first convert the file to XML utilizing the ToXml() methodology.

The ToXml() methodology converts your entire occasion object to an XML string.

$xmlEventRecord = $eventRecord.ToXml()

Except you’re a sadomasochist and like to make use of regex, you could get this right into a structured format to question parts inside it. Fortunate for us, you’ll be able to simply solid XML strings to Xml.Doc sorts utilizing the [xml] sort accelerator.

$xmlEventRecord = [xml]$eventRecord.ToXml()

Parse the XML to Extract Area and Username

The XML format of the occasion comprises numerous parts, and we have to navigate by means of these to seek out TargetUserName and TargetDomainName. We’ll use XPath queries to attain this.

💡 Home windows occasion logs don’t have full XPath help. They use a subset of XML 1.0 that’s severely restricted within the features you should use.

On each XmlDocument object, you’ve got a SelectSingleNode() methodology that lets you go an XPath question to to seek out parts within the doc however you could provide you with the XPath question first.

When constructing XPath queries, you could first work out the “path” to the entity you’re querying or no less than the node that holds the worth you’re after. On this case, the weather we’re after are in EventEventData saved as a Knowledge node with Identify attributes with values of TargetUserName and TargetDomainName that we’re after.

<Occasion xmlns="http://schemas.microsoft.com/win/2004/08/occasions/occasion">
    <System>
        <Supplier Identify="Microsoft-Home windows-Safety-Auditing" Guid='{54849625-5478-4994-a5ba-3e3b0328c30d}'/>
        <EventID>4624</EventID>
        <Model>2</Model>
        <Stage>0</Stage>
        <Job>12544</Job>
        <Opcode>0</Opcode>
        <Key phrases>0x8020000000000000</Key phrases>
        <TimeCreated SystemTime="2024-06-07T17:23:16.5812423Z"/>
        <EventRecordID>260494</EventRecordID>
        <Correlation/>
        <Execution ProcessID='768' ThreadID='1708'/>
        <Channel>Safety</Channel>
        <Laptop>ATA-Devo-SRV-01.atadevo.native</Laptop>
        <Safety/>
    </System>
    <EventData>
        <Knowledge Identify="SubjectUserSid">S-1-5-18</Knowledge>
        <Knowledge Identify="SubjectUserName">ATA-DEVO-SRV-01$</Knowledge>
        <Knowledge Identify="SubjectDomainName">ATADEVO</Knowledge>
        <Knowledge Identify="SubjectLogonId">0x3e7</Knowledge>
        <Knowledge Identify="TargetUserSid">S-1-5-21-3909178112-971454023-1868345993-500</Knowledge>
        <Knowledge Identify="TargetUserName">atadevoadmin</Knowledge>
        <Knowledge Identify="TargetDomainName">ATADEVO</Knowledge>
        <Knowledge Identify="TargetLogonId">0x546f80</Knowledge>
        <Knowledge Identify="LogonType">7</Knowledge>
        <Knowledge Identify="LogonProcessName">Negotiat</Knowledge>
        <Knowledge Identify="AuthenticationPackageName">Negotiate</Knowledge>
        <Knowledge Identify="WorkstationName">ATA-DEVO-SRV-01</Knowledge>
        <Knowledge Identify="LogonGuid"> { 97292dbd-b376-1168-64b5-b750cafa6348 }</Knowledge>
        <Knowledge Identify="TransmittedServices">-</Knowledge>
        <Knowledge Identify="LmPackageName">-</Knowledge>
        <Knowledge Identify="KeyLength">0</Knowledge>
        <Knowledge Identify="ProcessId">0x300</Knowledge>
        <Knowledge Identify="ProcessName">C:WindowsSystem32lsass.exe</Knowledge>
        <Knowledge Identify="IpAddress">-</Knowledge>
        <Knowledge Identify="IpPort">-</Knowledge>
        <Knowledge Identify="ImpersonationLevel">%%1833</Knowledge>
        <Knowledge Identify="RestrictedAdminMode">-</Knowledge>
        <Knowledge Identify="TargetOutboundUserName">-</Knowledge>
        <Knowledge Identify="TargetOutboundDomainName">-</Knowledge>
        <Knowledge Identify="VirtualAccount">%%1843</Knowledge>
        <Knowledge Identify="TargetLinkedLogonId">0x0</Knowledge>
        <Knowledge Identify="ElevatedToken">%%1842</Knowledge>
    </EventData>
</Occasion>

Should you don’t work with XPath too typically, you’re first inclination would in all probability be to do one thing like this:

$xmlEventRecord.SelectSingleNode("//Knowledge[@Name="TargetUserName"]")

The XPath question is sound. It’s on the lookout for all Knowledge nodes with an attribute of Identify and a price of TargetUserName. However, it gained’t work. Why? This XML use a namespace.

xmlns="http://schemas.microsoft.com/win/2004/08/occasions/occasion

XML namespaces are used for offering uniquely named parts and attributes in an XML doc. An XML occasion could comprise component or attribute names from a couple of XML vocabulary. If every vocabulary is given a namespace, the paradox between identically named parts or attributes could be resolved.

To question an XML doc that makes use of a namespace, you could first outline an XmlNamespaceManager after which add that namespace to it.

$eventNamespace = New-Object System.Xml.XmlNamespaceManager($xmlEventRecord.NameTable)
$eventNamespace.AddNamespace("evt", "http://schemas.microsoft.com/win/2004/08/occasions/occasion")

Upon getting the namespace outlined, you could then use that namespace within the SelectSingleNode() question.

$xmlEventRecord.SelectSingleNode("//evt:Knowledge[@Name="TargetUserName']", $eventNamespace)

At this level, it’s best to have the ability to extract the XML node.

Discovering the Textual content Worth

The SelectSingleNode() methodology is not going to return a easy string that you simply’ll want. As an alternative, it returns an System.Xml.XmlElement object which you’ll must extract the node worth from. To do this, you should use your acquainted PowerShell dot notation to reference the InnerText property.

$xmlEventRecord.SelectSingleNode("//evt:Knowledge[@Name="TargetUserName"]", $eventNamespace).InnerText

As soon as you understand how to seek out the textual content worth, you’re again into acquainted PowerShell territory. At this level, you simply must extract each of the strings (TargetUserName and TargetDomainName) on this case and concatenate them collectively.

$targetUserName = $xmlEventRecord.SelectSingleNode("//evt:Knowledge[@Name="TargetUserName"]", $eventNamespace).InnerText
$targetDomainName = $xmlEventRecord.SelectSingleNode("//evt:Knowledge[@Name="TargetDomainName"]", $eventNamespace).InnerText
$domainUser = "$targetDomainName$targetUserName"

Lastly, mix the extracted TargetUserName and TargetDomainName to kind the DomainNameUsername format.

And also you’re performed!

Conclusion and Script

Should you’re constructing any PowerShell scripts querying Home windows occasion logs, likelihood is you’re going to must particularly if you wish to question the Message subject.

Right here’s the whole script if you wish to copy and paste.

# Step 1: Question the Safety log for Occasion ID 4624
$eventRecord = Get-WinEvent -MaxEvents 1 -FilterHashtable @{LogName="Safety";ID=4624}

# Step 2: Convert the occasion file to XML
$xmlEventRecord = [xml]$eventRecord.ToXml()

# Step 3: Outline the namespace supervisor
$eventNamespace = New-Object System.Xml.XmlNamespaceManager($xmlEventRecord.NameTable)
$eventNamespace.AddNamespace("evt", "<http://schemas.microsoft.com/win/2004/08/occasions/occasion>")

# Step 4: Extract TargetUserName and TargetDomainName utilizing XPath
$targetUserName = $xmlEventRecord.SelectSingleNode("//evt:Knowledge[@Name="TargetUserName"]", $eventNamespace).InnerText
$targetDomainName = $xmlEventRecord.SelectSingleNode("//evt:Knowledge[@Name="TargetDomainName"]", $eventNamespace).InnerText

# Step 5: Mix DomainName and UserName
$domainUser = "$targetDomainName$targetUserName"
$domainUser
RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments