Get-WinEvent
Understanding the importance of mass analysis of Windows Event Logs and Sysmon logs is pivotal in the realm of cybersecurity, especially in Incident Response (IR) and threat hunting scenarios. These logs hold invaluable information about the state of your systems, user activities, potential threats, system changes, and troubleshooting information. However, these logs can also be voluminous and unwieldy. For large-scale organizations, it's not uncommon to generate millions of logs each day. Hence, to distill useful information from these logs, we require efficient tools and techniques to analyze these logs en masse.
One of these tools is the the Get-WinEvent cmdlet in PowerShell.
To quickly identify the available logs, we can leverage the -ListLog
By specifying *
as the parameter value, we retrieve all logs without applying any filtering criteria
The |
character is a pipe operator. It is used to pass the output of one command (in this case, the Get-WinEvent
command) to another command (in this case, the Select-Object
command).
By executing the following command, we can retrieve the list of logs and display essential properties such as LogName
, RecordCount
, IsClassicLog
, IsEnabled
, LogMode
, and LogType
.
Get-WinEvent -ListLog * | Select-Object LogName, RecordCount, IsClassicLog, IsEnabled, LogMode, LogType | Format-Table -AutoSize
Additionally, we can explore the event log providers associated with each log using the -ListProvider
parameter. Event log providers serve as the sources of events within the logs. Executing the following command allows us to retrieve the list of providers and their respective linked logs.
Get-WinEvent -ListProvider * | Format-Table -AutoSize
Retrieving events from the System log
Get-WinEvent -LogName 'System' -MaxEvents 50 | Select-Object TimeCreated, ID, ProviderName, LevelDisplayName, Message | Format-Table -AutoSize
Retrieving events from Microsoft-Windows-WinRM/Operational
Get-WinEvent -LogName 'Microsoft-Windows-WinRM/Operational' -MaxEvents 30 | Select-Object TimeCreated, ID, ProviderName, LevelDisplayName, Message | Format-Table -AutoSize
To retrieve the oldest events, instead of manually sorting the results, we can utilize the -Oldest
parameter with the Get-WinEvent cmdlet
Get-WinEvent -LogName 'Microsoft-Windows-WinRM/Operational' -Oldest -MaxEvents 30
Retrieving events from .evtx Files
If you have an exported .evtx
file from another computer or you have backed up an existing log, you can utilize the Get-WinEvent cmdlet to read and query those logs. This capability is particularly useful for auditing purposes or when you need to analyze logs within scripts.
you need to provide the log file's path using the
-Path
parameter e.g 'C:\Tools\chainsaw\EVTX-ATTACK-SAMPLES\Execution\exec_sysmon_1_lolbin_pcalua.evtx' file
Get-WinEvent -Path 'C:\Tools\chainsaw\EVTX-ATTACK-SAMPLES\Execution\exec_sysmon_1_lolbin_pcalua.evtx' -MaxEvents 5 | Select-Object TimeCreated, ID, ProviderName, LevelDisplayName, Message | Format-Table -AutoSize
Filtering events with FilterHashtable
we can use the -FilterHashtable
parameter, which enables us to define specific conditions for the logs we want to retrieve.
Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-Sysmon/Operational'; ID=1,3} | Select-Object TimeCreated, ID, ProviderName, LevelDisplayName, Message | Format-Table -AutoSize
For exported events the equivalent command is the following.
Get-WinEvent -FilterHashtable @{Path='C:\Tools\chainsaw\EVTX-ATTACK-SAMPLES\Execution\sysmon_mshta_sharpshooter_stageless_meterpreter.evtx'; ID=1,3} | Select-Object TimeCreated, ID, ProviderName, LevelDisplayName, Message | Format-Table -AutoSize
If we want the get event logs based on a date range (
5/28/23 - 6/2/2023
), this can be done as follows.
startDate = (Get-Date -Year 2023 -Month 5 -Day 28).Date
endDate = (Get-Date -Year 2023 -Month 6 -Day 3).Date
Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-Sysmon/Operational'; ID=1,3; StartTime=$startDate; EndTime=$endDate} | Select-Object TimeCreated, ID, ProviderName, LevelDisplayName, Message | Format-Table -AutoSize
Filtering events with FilterHashtable & XML
Consider an intrusion detection scenario where a suspicious network connection to a particular IP (52.113.194.132
) has been identified. With Sysmon installed, you can use Event ID 3 (Network Connection) logs to investigate the potential threat.
Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-Sysmon/Operational'; ID=3} | `ForEach-Object {
$xml = [xml]$.ToXml()
$eventData = $xml.Event.EventData.Data
New-Object PSObject -Property @{
SourceIP = $eventData | Where-Object {$.Name -eq "SourceIp"} | Select-Object -ExpandProperty '#text'
DestinationIP = $eventData | Where-Object {$.Name -eq "DestinationIp"} | Select-Object -ExpandProperty '#text'
ProcessGuid = $eventData | Where-Object {$.Name -eq "ProcessGuid"} | Select-Object -ExpandProperty '#text'
ProcessId = $eventData | Where-Object {$.Name -eq "ProcessId"} | Select-Object -ExpandProperty '#text'
}
} | Where-Object {$.DestinationIP -eq "52.113.194.132"}
Filtering events with FilterXPath
To use XPath queries with Get-WinEvent, we need to use the -FilterXPath
parameter
This allows us to craft an XPath query to filter the event logs.
For instance, if we want to get Process Creation (Sysmon Event ID 1) events in the Sysmon log to identify installation of any Sysinterals tool we can use the command below. Note: During the installation of a Sysinternals tool the user must accept the presented EULA. The acceptance action involves the registry key included in the command below.
Get-WinEvent -LogName 'Microsoft-Windows-Sysmon/Operational' -FilterXPath "*[EventData[Data[@Name='Image']='C:\Windows\System32\reg.exe']] and *[EventData[Data[@Name='CommandLine']='"C:\Windows\system32\reg.exe
" ADD HKCU\Software\Sysinternals /v EulaAccepted /t REG_DWORD /d 1 /f']]" | Select-Object TimeCreated, ID, ProviderName, LevelDisplayName, Message | Format-Table -AutoSize
Note: Image
and CommandLine
can be identified by browsing the XML representation of any Sysmon event with ID 1 through, for example, Event Viewer
Lastly, suppose we want to investigate any network connections to a particular suspicious IP address (52.113.194.132
) that Sysmon has logged. To do that we could use the following command.
Get-WinEvent -LogName 'Microsoft-Windows-Sysmon/Operational' -FilterXPath "*[System[EventID=3] and EventData[Data[@Name='DestinationIp']='52.113.194.132']]"
Filtering events based on property values
The -Property *
parameter, when used with Select-Object
, instructs the command to select all properties of the objects passed to it. In the context of the Get-WinEvent command, these properties will include all available information about the event. Let's see an example that will present us with all properties of Sysmon event ID 1 logs.
Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-Sysmon/Operational'; ID=1} -MaxEvents 1 | Select-Object -Property *
Let's now see an example of a command that retrieves Process Create
events from the Microsoft-Windows-Sysmon/Operational
log, checks the parent command line of each event for the string -enc
, and then displays all properties of any matching events as a list.
Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-Sysmon/Operational'; ID=1} | Where-Object {$_.Properties[21].Value -like "-enc"} | Format-List
| Where-Object {$_.Properties[21].Value -like "-enc"}: This portion of the command further filters the retrieved events. The '|' character (pipe operator) passes the output of the previous command (i.e., the filtered events) to the 'Where-Object' cmdlet. The 'Where-Object' cmdlet filters the output based on the script block that
$: In the script block, $ refers to the current object in the pipeline, i.e., each individual event that was retrieved and passed from the previous command.
.Properties[21].Value: The Properties property of a "Process Create" Sysmon event is an array containing various data about the event. The specific index 21 corresponds to the ParentCommandLine property of the event, which holds the exact command line used to start the process.
-like "-enc": This is a comparison operator that matches strings based on a wildcard string, where * represents any sequence of characters. In this case, it's looking for any command lines that contain -enc anywhere within them. The -enc string might be part of suspicious commands, for example, it's a common parameter in PowerShell commands to denote an encoded command which could be used to obfuscate malicious scripts. | Format-List: Finally, the output of the previous command (the events that meet the specified condition) is passed to the Format-List cmdlet. This cmdlet displays the properties of the input objects as a list, making it easier to read and analyze.
Assessment:
Utilize the Get-WinEvent cmdlet to traverse all event logs located within the "C:\Tools\chainsaw\EVTX-ATTACK-SAMPLES\Lateral Movement" directory and determine when the \*\PRINT share was added. Enter the time of the identified event in the format HH:MM:SS as your answer.
solution:
A quick google on A network share object was added shows Windows Security Log Event ID 5142
using the following command
Get-WinEvent -Path "C:\Tools\chainsaw\EVTX-ATTACK-SAMPLES\Lateral Movement\net_share_drive_5142.evtx" -MaxEvents 50 | Select-Object TimeCreated, ID, ProviderName, LevelDisplayName, Message | Format-Table -AutoSize
Results:
TimeCreated Id ProviderName LevelDisplayName Message
3/17/2019 12:30:30 PM 5142 Microsoft-Windows-Security-Auditing Information A network share object was added....
3/17/2019 12:26:42 PM 1102 Microsoft-Windows-Eventlog Information The audit log was cleared....
Last updated