Unlocking the Power of Sysmon Event Logs: How to Parse and Analyze Security Data
Transforming Raw Log Data into Actionable Insights for Enhanced Security
Imagine you are a security analyst and you have just been given a pair of Sysmon event log files. What would you do? Where do you start?
Understanding how to parse and analyze Windows event logs is a crucial skill when it comes to identifying malicious behavior. In this tutorial I will give you the tools and knowledge you will need to take an event log parse it into a JSON format and then use the tools chainsaw and jq to gain valuable insights into what took place on the system. In this tutorial we will be working two Sysmon event logs from two different systems. So first let’s find out what we can expect to find in a Sysmon log.
What information is in a Windows Sysmon Log
The Sysmon log contains many events that are of great importance none more than Event ID 1: ProcessCreate. According to Microsoft this event provides extended information about a newly created process. It will contain fields such as the ParentProcess which is the process which created it. It will also get the full Commandline of the parent and child process to include their ProcessGuid’s. ProcessGuid’s are unique identifiers for each process that you can use to investigate what that process did. For example, if you found a process that kicked off situational awareness commands such as whoami and tasklist you could search it’s ProcessGuid to identify other processes it may have instantiated. Other fields of interest are as follows:
Hashes: MD5, SHA256 and IMPHASH
UtcTime
LogonGuid
OriginalFileName
Event ID 2: A process changed a file creation time
Fields of interest for this event are:
Image
ProcessGuid
TargetFilename
PreviousCreationUtcTime
CreationUtcTime
User
ProcessGuid
Event ID 3: Network Connection
Fields of interest for this event are:
Image
DestinationIp
DestinationPort
DestinationHostname
SourceIp
User
ProcessGuid
Event ID 4: Sysmon service state changed
Fields of interest for this event are:
UtcTime
State
Version
Event ID 5: Process terminated
Fields of interest for this event are:
Image
ProcessGuid
UtcTime
User
Event ID 6: Driver loaded
Fields of interest for this event are:
UtcTime
ImageLoaded
Hashes
Signature
SignatureStatus
Signed
Event ID 7 : Image loaded
Fields of interest for this event are:
Image
ProcessGuid
ImageLoaded
Description
Company
OriginalFilename
Hashes
Signed
Signature
User
UtcTime
Event ID 8: CreateRemote Thread
Fields of interest for this event are:
SourceImage
TargetProcessGuid
SourceUser
UtcTime
SourceProcessGuid
TargetUser
TargetImage
Event ID 9: RawAccessRead
Fields of interest for this event are:
Image
ProcessGuid
Device
User
UtcTime
Event ID 10: ProcessAccess
Fields of interest for this event are:
SourceImage
SourceProcessGuid
TargetImage
TargetProcessGuid
UtcTime
GrantedAccess
CallTrace
SourceUser
TargetUser
Event ID 11: FileCreateFields of interest for this event are:
Image
ProcessGuid
TargetFilename
UtcTime
CreationUtcTime
Event ID 12: RegistryEvent (Object create and delete)
Fields of interest for this event are:
Image
ProcessGuid
TargetObject
EventType
User
Event ID 13: RegistryEvent (Value Set)
Fields of interest for this event are:
Image
ProcessGuid
TargetObject
EventType
User
Event ID 14: RegistryEvent (Key and Value Rename)
Fields of interest for this event are:
Image
ProcessGuid
TargetObject
EventType
User
Event ID 15: FileCreateStreamHash
Fields of interest for this event are:
Image
ProcessGuid
TargetFilename
UtcTime
CreationUtcTime
User
Hash
Event ID 16: ServiceConfigurationChange
Fields of interest for this event are:
Configuration
ConfigurationFileHash
UtcTime
Event ID 17: PipeEvent (Pipe created)
Fields of interest for this event are:
Image
ProcessGuid
PipeName
User
UtcTime
Event ID 18: PipeEvent (Pipe connected)
Fields of interest for this event are:
Image
ProcessGuid
PipeName
User
UtcTime
Event ID 19: WmiEvent (WmiEventFilter activity detected)
Fields of interest for this event are:
EventType
Operation
UtcTime
User
Name
Query
Event ID 20: WmiEvent (WmiEventConsumer activity detected)
Fields of interest for this event are:
EventType
Operation
UtcTime
User
Name
Type
Destination
Event ID 21: WmiEvent (WmiEventConsumerToFilter activity detected)
Fields of interest for this event are:
EventType
Operation
UtcTime
User
Consumer
Filter
Event ID 22: DNSEvent (DNS query)
Fields of interest for this event are:
Image
ProcessGuid
QueryName
UtcTime
User
Event ID 23: FileDelete (File Delete archived)
Fields of interest for this event are:
Image
ProcessGuid
User
TargetFilename
Hashes
IsExecutable
Event ID 24: ClipboardChange (New content in the clipboard)
Fields of interest for this event are:
Image
ProcessGuid
ClientInfo
Hashes
Archived
UtcTime
Event ID 25: ProcessTampering (Process image change)
Fields of interest for this event are:
Image
ProcessGuid
UtcTime
Type
Event ID 26: FileDeleteDetected (File Delete logged)
Fields of interest for this event are:
Image
ProcessGuid
UtcTime
TargetFilename
Hashes
IsExecutable
Event ID 27: FileBlockExecutable
Fields of interest for this event are:
Image
ProcessGuid
UtcTime
User
Image
TargetFilename
Hashes
Event ID 28: FileBlockShredding
Fields of interest for this event are:
Image
ProcessGuid
UtcTime
TargetFilename
Hashes
IsExecutable
Event ID 29: FileExecutableDetected
Fields of interest for this event are:
Image
ProcessGuid
UtcTime
TargetFilename
Hashes
Now that we have some understanding of the type of data we can expect to see lets get to the good stuff where we will parse the files and start to analyze some data!
VM Setup
In your hypervisor of choice install a Windows VM. Windows 10 or 11 will suffice, just ensure that it has the Windows Subsystem for Linux (WSL).
Install the following tools:
chainsaw is a powerful forensic tool created by WithSecure that allows you to run custom rules or Sigma rules to find threats in files. We will use the default rules which come with the tool.
JQ - Install this in the WSL shell
7z - Install this in the WSL shell
dos2unix - Install this in the WSL shell
Download evtx files from here
Using Chainsaw’s Hunt Operator
Once you have downloaded and extracted your two Sysmon EVTX files we will run the tool chainsaw against. The first command we will run is the hunt command using the chainsaw and Sigma rules. This is a great way to get a quick idea of what may be going on in the log.
C:\Forensic_Program_Files\chainsaw\chainsaw.exe hunt -r C:\Forensic_Program_Files\chainsaw\rules\ -m C:\Forensic_Program_Files\chainsaw\mappings\sigma-event-logs-all.yml -s C:\Forensic_Program_Files\chainsaw\sigma\ .\sysmon_files\
Once this has completed you will have a text based table you can look through.
A couple entries down you can immediately see that mshta.exe was used to download a weird .hta file and then this .hta file kicked off PowerShell to run an encoded command. Your spidey senses should tingling now!
We also are seeing suspicious situational awareness commands being run on atreides.dune.local - tasklist and systeminfo.
We also found a new executable named spcvs.exe running from the users Downloads folder.
wmic using process call create to run spcvs.exe remotely.
On harkonnen.dune.local we see wmiprvse.exe being used to spawn and run C:\spcvs.exe.
So we can see right off the bat we have a major problem. It appears both of our machines are infected. Another clue we may be dealing with Metasploit’s Meterpreter is the fact the OriginalFilename of a weird looking file running from AppData\Local\Temp is ab.exe and the Product is Apache HTTP Server. This is a hallmark of Metasploit.
So without much work using chainsaw’s built in hunt functionality it is safe to say both of our computers are infected.
Using Chainsaw’s Search Operator
Now that we are comfortable using the hunt operator lets start using the search operator to look at individual event ID’s. Before we start searching our logs we need to understand the layout of how chainsaw parses our EVTX files into JSON. Run this command:
C:\Forensic_Program_Files\chainsaw\chainsaw.exe dump .\sysmon_files\ --json |more
We can see that all the data we care about is nested inside of Event\System and Event\EventData.
Look closely at the very first character on line 1, character 1. It is a [
So in order to get to the data we care about once we create our JSON file we must use Event.System or Event.EventData. The following command will carve out all of our Event ID 1: ProcessCreate logs and put it in a JSON file name sysmon_1.
C:\Forensic_Program_Files\chainsaw\chainsaw.exe search -t 'Event.System.EventID: =1' .\sysmon_files\ --json > sysmon_1.json
Now move to your WSL shell and I will show you how to do some basic stacking and parsing on this file.
A common error you might see is:
parse error: Invalid numeric literal at line 1, column 3
, this is because you used your Windows shell to create the JSON file. The easy fix is to either do all your JSON file creation in the Linux shell or you can run dos2unix on the json file as follows:dos2unix sysmon_1.json
dos2unix: converting UTF-16LE file sysmon_1.json to UTF-8 Unix format...
This converts the file from UTF-16LE to UTF-8
Now you can run:
cat sysmon_1.json | jq '.[].Event | .EventData.Image' | sort | uniq -c | sort -nr
This command will drill down into the ProcessCreate field and sort and group all the Images that were run.
Quickly scrolling through you can see the processes that were found using the hunt operator such as:
whoami
mshta
fhNAqmdh
OblMlXyO
systeminfo
spcvs
Lets now grab the hash of our suspicious process and run it through VirusTotal to see if this is a legitimate process. To do this we will use select with jq.
cat sysmon_1.json | jq '.[].Event | select(.EventData.Image == "C:\\spcvs.exe")'
It appears we have 3 instances and all hashes match. So grab the MD5 of any entry and submit it to VirusTotal and lets see what we get.
Uh-oh no matches were found! So what does this tell us? It appears our suspicious executable has never been seen before by VirusTotal. That in and of itself is could be interesting, but in combination with the OriginalFileName being ab.exe and it reporting it’s Apache it appears we are dealing with Meterpreter.
"EventData": {
"RuleName": "-",
"UtcTime": "2021-11-04 19:20:47.841",
"ProcessGuid": "",
"ProcessId": 2948,
"Image": "C:\\spcvs.exe",
"FileVersion": "2.2.14",
"Description": "ApacheBench command line utility",
"Product": "Apache HTTP Server",
"Company": "Apache Software Foundation",
"OriginalFileName": "ab.exe",
"CommandLine": "c:\\spcvs.exe",
"CurrentDirectory": "C:\\Windows\\system32\\",
"User": "DUNE\\Administrator",
"LogonGuid": "75C73FF4-328F-6184-6C8F-8B0000000000",
"LogonId": "0x8b8f6c",
"TerminalSessionId": 0,
"IntegrityLevel": "High",
"Hashes": "MD5=50CA1A8781D3A8103A9FC480824AF535,SHA256=FCD3A9D06AAA43DD54F5012FEACB07006CD2B997386FC726A2E260DF73412885,IMPHASH=481F47BBB2C9C21E108D65F52B04C448",
"ParentProcessGuid": "75C73FF4-C0CF-6182-5500-000000000900",
"ParentProcessId": 3772,
"ParentImage": "C:\\Windows\\System32\\wbem\\WmiPrvSE.exe",
"ParentCommandLine": "C:\\Windows\\system32\\wbem\\wmiprvse.exe",
"ParentUser": "NT AUTHORITY\\NETWORK SERVICE"
}
Something else to take note of is that the Parent Process is wmiprvse.exe which is indicative of possible lateral movement using wmic process call create. Let’s see if we can find that. Both of the commands below will find the wmic processes that ran ‘process call create’
cat sysmon_1.json | jq '.[].Event | select(.System.EventID == 1) | .EventData.CommandLine | select(contains("process call create"))’
C:\Forensic_Program_Files\chainsaw\chainsaw.exe search -t 'Event.System.EventID: =1' -e 'process call create' .\sysmon_files\
Now I hope you are starting to realize that when you have a little creativity using chainsaw on Sysmon logs using the hunt and search arguments is a powerful way to get quick forensic insights. Now let’s dump out all of our events to a JSON file and look at some of the other juicy data Sysmon can tell us.
Using Chainsaw’s Dump Operator
An excellent first strategy when you are working with the full sysmon log is to get a sorted count of each event ID, especially since we are working with a JSON file of two systems. Run this command to view our event ID’s:
cat sysmon_all.json | jq '.[].Event | .System.EventID' | sort | uniq -c | sort -nr
What immediately jumps out to me is there is only one instance of Event ID 8: CreateRemoteThread. This is a way malware can inject their code into other processes. So I will note that down and look at it.
cat sysmon_all.json | jq '.[].Event | select(.System.EventID == 8)'
It appears our malicious process from earlier C:\spcvs.exe has injected itself into svchost.exe to try and blend in.
Now what we can do from here is take the TargetProcessGuid in step i and see if the compromised svchost process has been up to anything nefarious by searching that Guid as ParentProcessGuid.
cat sysmon_all.json | jq '.[].Event | select(.EventData.ParentProcessGuid == "75C73FF4-C12B-6182-8A00-000000000900")'
Nothing is returned, but if something did we could start pivoting and see what those processes did as well.
Next lets look at Event ID 13: RegistryEvent (Value set) and see if we can find any sort of persistence.
cat sysmon_all.json | jq '.[].Event | select(.System.EventID == 13) | .EventData.TargetObject' | sort | uniq -c | sort -nr
So here all we are doing is grabbing Event ID 13 and getting the TargetObject field and stacking it. Scrolling through I can see to suspicious entries:
"HKLM\\System\\CurrentControlSet\\Services\\cklghj\\ImagePath"
"HKLM\\System\\CurrentControlSet\\Services\\cklghj\\Start"
Now we can take that weird service name, cklghj and search all of our logs for it using chainsaw.
C:\Forensic_Program_Files\chainsaw\chainsaw.exe search -t 'Event.System.EventID: =13' -i -e 'cklghj' .\sysmon_files\
In the details field of the second event we can see classic GetSystem artifacts to escalate privileges.
EventData:
RuleName: T1031,T1050
EventType: SetValue
UtcTime: 2021-11-04 19:26:44.717
ProcessGuid: 75C73FF4-C0C9-6182-0B00-000000000900
ProcessId: 656
Image: C:\Windows\system32\services.exe
TargetObject: HKLM\System\CurrentControlSet\Services\cklghj\ImagePath
User: NT AUTHORITY\SYSTEM
Now for the last event I will work through we will look at Event ID 3 to view the network connections.
In a noisy environment or if you are working with a lot of Sysmon files this will be tons of data, but by stacking on .EventData.Image field bad behavior will rise to the top. Additionally when you use the stacking technique the more data you have the easier it will become to find malicious behavior. Why is this you ask? It is because malware should be rare in an environment. For example, C:\Users\latreides\Downloads\spcvs.exe making network connections is weird. Odds are that will probably happening on a few computers, so if you are stacking data from a hundred computers that will stick out. Now enough theory lets see the command I used to stack the data.
cat sysmon_all.json | jq '.[].Event | select(.System.EventID == 3) | .EventData.Image' | sort | uniq -c | sort -nr
Here we can see network connections from
spcvs.exe
WMIC.exe
powershell.exe
From here to investigate you just continue to follow the same workflow to peel back the layers of the onion.
So I hope you enjoyed this tutorial on how I like to approach “Fast Forensics“ using chainsaw, Sysmon and jq. This is an excellent way to quickly rip out indicators of compromise (IoC’s) to ingest in your other security tools so you can scope, contain and eradicate a compromise.
References:
https://learn.microsoft.com/en-us/sysinternals/downloads/sysmon
https://www.blackhillsinfosec.com/a-sysmon-event-id-breakdown/
https://github.com/WithSecureLabs/chainsaw