Sysmon Deployment & Tuning
Overview
Sysmon (System Monitor) is a Windows system service and kernel driver from Sysinternals that logs security-relevant events to the Windows event log under Microsoft-Windows-Sysmon/Operational. Unlike native Windows audit policy events, Sysmon events include enriched fields: full command lines, image hashes, parent process information, and network connection metadata — all correlated by a unique ProcessGuid that persists across the process lifetime.
A well-tuned Sysmon deployment dramatically increases detection fidelity for the techniques documented in this wiki: process injection, DLL hijacking, persistence via registry or Startup folders, and C2 network activity.
Sysmon’s value is entirely in its configuration. A default installation with no config file generates almost no events. The config is an XML file that specifies which events to log and which to exclude — a poorly written config floods the SIEM with noise, while a good one produces targeted, high-signal events with minimal volume.
Installation
# Install with a custom config .Sysmon64.exe -accepteula -i sysmon-config.xml # Update an existing config without reinstalling .Sysmon64.exe -c sysmon-config.xml # Check the current config .Sysmon64.exe -c # Uninstall (removes the driver and service) .Sysmon64.exe -u # Verify the service is running Get-Service Sysmon64 | Select-Object Status, StartType # Event log location Get-WinEvent -LogName "Microsoft-Windows-Sysmon/Operational" -MaxEvents 10
# Install with a custom config
.Sysmon64.exe -accepteula -i sysmon-config.xml
# Update an existing config without reinstalling
.Sysmon64.exe -c sysmon-config.xml
# Check the current config
.Sysmon64.exe -c
# Uninstall (removes the driver and service)
.Sysmon64.exe -u
# Verify the service is running
Get-Service Sysmon64 | Select-Object Status, StartType
# Event log location
Get-WinEvent -LogName "Microsoft-Windows-Sysmon/Operational" -MaxEvents 10Configuration skeleton
<SysmonConfig version="4.82">
<HashAlgorithms>MD5,SHA256,IMPHASH</HashAlgorithms>
<CheckRevocation/>
<EventFiltering>
<!-- EID 1: Process creation -->
<RuleGroup name="ProcessCreate" groupRelation="or">
<ProcessCreate onmatch="exclude">
<Image condition="is">C:WindowsSystem32svchost.exe</Image>
<Image condition="is">C:WindowsSystem32 askhostw.exe</Image>
</ProcessCreate>
</RuleGroup>
<!-- EID 3: Network connections -->
<RuleGroup name="NetworkConnect" groupRelation="or">
<NetworkConnect onmatch="include">
<InitiatedTcp condition="is">true</InitiatedTcp>
<DestinationPort condition="is">443</DestinationPort>
<DestinationPort condition="is">80</DestinationPort>
<DestinationPort condition="is">53</DestinationPort>
</NetworkConnect>
</RuleGroup>
<!-- EID 7: Image load - log unsigned DLL loads -->
<RuleGroup name="ImageLoad" groupRelation="or">
<ImageLoad onmatch="include">
<Signed condition="is">false</Signed>
<ImageLoaded condition="contains">AppData</ImageLoaded>
<ImageLoaded condition="contains">Temp</ImageLoaded>
</ImageLoad>
</RuleGroup>
<!-- EID 10: Process access - injection via OpenProcess -->
<RuleGroup name="ProcessAccess" groupRelation="or">
<ProcessAccess onmatch="include">
<GrantedAccess condition="is">0x1F0FFF</GrantedAccess>
<GrantedAccess condition="is">0x1010</GrantedAccess>
<GrantedAccess condition="is">0x143A</GrantedAccess>
</ProcessAccess>
</RuleGroup>
<!-- EID 11: File create in Startup / Temp -->
<RuleGroup name="FileCreate" groupRelation="or">
<FileCreate onmatch="include">
<TargetFilename condition="contains">Startup</TargetFilename>
<TargetFilename condition="end with">.lnk</TargetFilename>
<TargetFilename condition="end with">.ps1</TargetFilename>
</FileCreate>
</RuleGroup>
<!-- EID 12/13: Registry persistence -->
<RuleGroup name="RegistryEvent" groupRelation="or">
<RegistryEvent onmatch="include">
<TargetObject condition="contains">Run</TargetObject>
<TargetObject condition="contains">RunOnce</TargetObject>
<TargetObject condition="contains">Image File Execution Options</TargetObject>
</RegistryEvent>
</RuleGroup>
<!-- EID 22: DNS queries -->
<RuleGroup name="DnsQuery" groupRelation="or">
<DnsQuery onmatch="exclude">
<Image condition="is">C:WindowsSystem32svchost.exe</Image>
</DnsQuery>
</RuleGroup>
<!-- EID 25: Process tampering (hollowing, module stomping) -->
<RuleGroup name="ProcessTampering" groupRelation="or">
<ProcessTampering onmatch="include">
<Type condition="is">Image is replaced</Type>
<Type condition="is">Image is locked</Type>
</ProcessTampering>
</RuleGroup>
</EventFiltering>
</SysmonConfig><SysmonConfig version="4.82">
<HashAlgorithms>MD5,SHA256,IMPHASH</HashAlgorithms>
<CheckRevocation/>
<EventFiltering>
<!-- EID 1: Process creation -->
<RuleGroup name="ProcessCreate" groupRelation="or">
<ProcessCreate onmatch="exclude">
<Image condition="is">C:WindowsSystem32svchost.exe</Image>
<Image condition="is">C:WindowsSystem32 askhostw.exe</Image>
</ProcessCreate>
</RuleGroup>
<!-- EID 3: Network connections -->
<RuleGroup name="NetworkConnect" groupRelation="or">
<NetworkConnect onmatch="include">
<InitiatedTcp condition="is">true</InitiatedTcp>
<DestinationPort condition="is">443</DestinationPort>
<DestinationPort condition="is">80</DestinationPort>
<DestinationPort condition="is">53</DestinationPort>
</NetworkConnect>
</RuleGroup>
<!-- EID 7: Image load - log unsigned DLL loads -->
<RuleGroup name="ImageLoad" groupRelation="or">
<ImageLoad onmatch="include">
<Signed condition="is">false</Signed>
<ImageLoaded condition="contains">AppData</ImageLoaded>
<ImageLoaded condition="contains">Temp</ImageLoaded>
</ImageLoad>
</RuleGroup>
<!-- EID 10: Process access - injection via OpenProcess -->
<RuleGroup name="ProcessAccess" groupRelation="or">
<ProcessAccess onmatch="include">
<GrantedAccess condition="is">0x1F0FFF</GrantedAccess>
<GrantedAccess condition="is">0x1010</GrantedAccess>
<GrantedAccess condition="is">0x143A</GrantedAccess>
</ProcessAccess>
</RuleGroup>
<!-- EID 11: File create in Startup / Temp -->
<RuleGroup name="FileCreate" groupRelation="or">
<FileCreate onmatch="include">
<TargetFilename condition="contains">Startup</TargetFilename>
<TargetFilename condition="end with">.lnk</TargetFilename>
<TargetFilename condition="end with">.ps1</TargetFilename>
</FileCreate>
</RuleGroup>
<!-- EID 12/13: Registry persistence -->
<RuleGroup name="RegistryEvent" groupRelation="or">
<RegistryEvent onmatch="include">
<TargetObject condition="contains">Run</TargetObject>
<TargetObject condition="contains">RunOnce</TargetObject>
<TargetObject condition="contains">Image File Execution Options</TargetObject>
</RegistryEvent>
</RuleGroup>
<!-- EID 22: DNS queries -->
<RuleGroup name="DnsQuery" groupRelation="or">
<DnsQuery onmatch="exclude">
<Image condition="is">C:WindowsSystem32svchost.exe</Image>
</DnsQuery>
</RuleGroup>
<!-- EID 25: Process tampering (hollowing, module stomping) -->
<RuleGroup name="ProcessTampering" groupRelation="or">
<ProcessTampering onmatch="include">
<Type condition="is">Image is replaced</Type>
<Type condition="is">Image is locked</Type>
</ProcessTampering>
</RuleGroup>
</EventFiltering>
</SysmonConfig>Key event IDs reference
| EID | Event | Key fields | Primary use |
|---|---|---|---|
| 1 | Process Create | CommandLine, ParentImage, Hashes | Execution, injection, LOLBins |
| 2 | File Creation Time | TargetFilename | Timestomping detection |
| 3 | Network Connect | Initiated, DestIP, DestPort, Image | C2, lateral movement |
| 6 | Driver Load | ImageLoaded, Signed | Kernel-mode implants |
| 7 | Image Load | ImageLoaded, Signed, Company | DLL injection, side-loading |
| 8 | CreateRemoteThread | SourceImage, TargetImage | Classic injection |
| 10 | ProcessAccess | GrantedAccess, TargetImage | OpenProcess injection |
| 11 | FileCreate | TargetFilename | Drops, Startup persistence |
| 12/13/14 | RegistryEvent | TargetObject, Details | Registry persistence |
| 17/18 | PipeEvent | PipeName | Named pipe C2 (SMB) |
| 22 | DNS Query | QueryName, QueryResults | DNS C2, phishing |
| 23 | FileDelete | TargetFilename | Anti-forensics |
| 25 | ProcessTampering | Type (Image is replaced) | Hollowing, stomping |
| 26 | FileDeleteDetected | TargetFilename | Ransomware, cleanup |
Tuning workflow
# Count events per EventID to find noisy categories
Get-WinEvent -LogName "Microsoft-Windows-Sysmon/Operational" |
Group-Object Id | Sort-Object Count -Descending |
Select-Object Name, Count | Format-Table
# Find the noisiest processes for EID 1 (process create)
Get-WinEvent -LogName "Microsoft-Windows-Sysmon/Operational" -FilterXPath "*[System[EventID=1]]" |
ForEach-Object {
([xml]$_.ToXml()).Event.EventData.Data |
Where-Object {$_.Name -eq 'Image'} | Select-Object '#text'
} | Group-Object '#text' | Sort-Object Count -Descending | Select-Object -First 20
# Find all EID 10 (process access) grouped by GrantedAccess mask
Get-WinEvent -LogName "Microsoft-Windows-Sysmon/Operational" -FilterXPath "*[System[EventID=10]]" |
ForEach-Object {
([xml]$_.ToXml()).Event.EventData.Data |
Where-Object {$_.Name -eq 'GrantedAccess'} | Select-Object '#text'
} | Group-Object '#text' | Sort-Object Count -Descending# Count events per EventID to find noisy categories
Get-WinEvent -LogName "Microsoft-Windows-Sysmon/Operational" |
Group-Object Id | Sort-Object Count -Descending |
Select-Object Name, Count | Format-Table
# Find the noisiest processes for EID 1 (process create)
Get-WinEvent -LogName "Microsoft-Windows-Sysmon/Operational" -FilterXPath "*[System[EventID=1]]" |
ForEach-Object {
([xml]$_.ToXml()).Event.EventData.Data |
Where-Object {$_.Name -eq 'Image'} | Select-Object '#text'
} | Group-Object '#text' | Sort-Object Count -Descending | Select-Object -First 20
# Find all EID 10 (process access) grouped by GrantedAccess mask
Get-WinEvent -LogName "Microsoft-Windows-Sysmon/Operational" -FilterXPath "*[System[EventID=10]]" |
ForEach-Object {
([xml]$_.ToXml()).Event.EventData.Data |
Where-Object {$_.Name -eq 'GrantedAccess'} | Select-Object '#text'
} | Group-Object '#text' | Sort-Object Count -DescendingDeployment at scale
# Deploy via Group Policy startup script or PDQ Deploy
# 1. Stage Sysmon64.exe and sysmon-config.xml in a network share
# 2. Run on all endpoints:
$sysmon = "\\share\tools\Sysmon64.exe"
$config = "\\share\tools\sysmon-config.xml"
if (-not (Get-Service Sysmon64 -ErrorAction SilentlyContinue)) {
Start-Process $sysmon -ArgumentList "-accepteula -i $config" -Wait
} else {
Start-Process $sysmon -ArgumentList "-c $config" -Wait
}
# Verify events are flowing (should have recent EID 1 events)
$count = (Get-WinEvent -LogName "Microsoft-Windows-Sysmon/Operational" `
-MaxEvents 10 -ErrorAction SilentlyContinue).Count
Write-Host "Sysmon event count (last 10): $count"# Deploy via Group Policy startup script or PDQ Deploy
# 1. Stage Sysmon64.exe and sysmon-config.xml in a network share
# 2. Run on all endpoints:
$sysmon = "\\share\tools\Sysmon64.exe"
$config = "\\share\tools\sysmon-config.xml"
if (-not (Get-Service Sysmon64 -ErrorAction SilentlyContinue)) {
Start-Process $sysmon -ArgumentList "-accepteula -i $config" -Wait
} else {
Start-Process $sysmon -ArgumentList "-c $config" -Wait
}
# Verify events are flowing (should have recent EID 1 events)
$count = (Get-WinEvent -LogName "Microsoft-Windows-Sysmon/Operational" `
-MaxEvents 10 -ErrorAction SilentlyContinue).Count
Write-Host "Sysmon event count (last 10): $count"Detection
High-value Sysmon detection rules (inline)
Three Sigma-ready patterns using Sysmon events:
Injection via OpenProcess (EID 10):
GrantedAccess: '0x1F0FFF'
TargetImage|not|startswith: 'C:\Windows\System32\'
LNK file created in Startup by non-explorer process (EID 11):
TargetFilename|contains: '\Start Menu\Programs\Startup\'
TargetFilename|endswith: '.lnk'
Image|not|contains: 'explorer'
DNS query to DGA-looking domain (EID 22):
QueryName|re: '^[a-z0-9]{10,}\.(xyz|top|tk|ml|ga|cf)$'