Writing a Sysmon config from scratch is a weeks-long exercise. Two community configs — SwiftOnSecurity and sysmon-modular — represent years of accumulated tuning work. Understanding what they choose to log (and what they exclude) teaches you how experienced detection engineers think about signal-to-noise trade-offs.
🔍 Read a config before you understand it
Download SwiftOnSecurity’s sysmon-config.xml from GitHub (github.com/SwiftOnSecurity/sysmon-config). Find the NetworkConnect section. Count: how many include rules vs exclude rules are there? What patterns do the exclude rules share?
Then read on to understand the philosophy behind those choices.
Attempt this before reading on. Getting stuck is the point.
SwiftOnSecurity: Balanced Permissiveness
The SwiftOnSecurity config follows a philosophy of inclusive logging with targeted exclusions :
Process Create (Event 1): Log everything, exclude known-noisy-but-benign processes (antivirus, update services, system components)
Network Connect (Event 3): Exclude common benign connections (browsers, Windows Update, known system processes) — log the rest
Process Access (Event 10): Include all LSASS access — high-value, low-false-positive
Registry (Events 12/13/14): Include known persistence registry paths (Run keys, startup folders, Winlogon)
Why exclude by image path, not process name?
The SwiftOnSecurity config typically excludes by full image path:
< Image condition = "is" >C:\Windows\system32\svchost.exe</ Image >
Not just:
< Image condition = "end with" >svchost.exe</ Image >
The reason: an attacker can name their malware svchost.exe and drop it in a user-writable path (C:\Users\jdoe\AppData\Local\svchost.exe). A full-path exclude would still log it. An endswith exclude would silently suppress it.
Full-path exclusions are safer than name-only exclusions
Any Sysmon exclude rule that matches only on process name (endswith/contains the binary name) can be defeated by an attacker who names their malicious tool after a legitimate Windows binary. Exclude rules should always include the full path condition where possible, and ideally also check the signature/signer of the binary.
sysmon-modular: ATT&CK-Aligned Modules
Olaf Hartong’s sysmon-modular is organized differently — each XML file targets a specific ATT&CK technique or detection goal:
sysmon-modular/
├── 1_process_creation/ ← Event 1 rules
│ ├── include_attrib_abuse.xml ← T1564.004 (hidden files via attrib)
│ ├── include_lolbas.xml ← Living off the land binaries
│ ├── include_powershell.xml ← PowerShell execution patterns
│ └── exclude_known_good.xml
├── 3_network_connection/ ← Event 3 rules
│ ├── include_suspicious_ports.xml
│ └── exclude_browsers.xml
├── 10_process_access/ ← Event 10 rules
│ ├── include_lsass.xml ← T1003.001
│ └── include_sam_access.xml ← T1003.002
├── ...
└── sysmonconfig.xml ← Merged output
Building a custom config with sysmon-modular
# The repo includes a merge script
python sysmon_merge.py \
-- include 1_process_creation / include_lolbas.xml \
-- include 1_process_creation / include_powershell.xml \
-- include 10_process_access / include_lsass.xml \
-- exclude 3_network_connection / exclude_browsers.xml \
-- output my_sysmonconfig.xml
This approach lets you:
Add coverage for a newly discovered technique by adding one module
Remove a noisy module without touching the rest of the config
Track config changes in git with meaningful diffs (a new module = new ATT&CK coverage)
Worked Example
Reading a sysmon-modular LSASS protection rule <!-- 10_process_access/include_lsass.xml -->
< RuleGroup name = "LSASS Access" groupRelation = "or" >
< ProcessAccess onmatch = "include" >
< Rule groupRelation = "and" >
< TargetImage condition = "is" >C:\Windows\system32\lsass.exe</ TargetImage >
< GrantedAccess condition = "contains" >0x10</ GrantedAccess >
</ Rule >
< Rule groupRelation = "and" >
< TargetImage condition = "is" >C:\Windows\system32\lsass.exe</ TargetImage >
< GrantedAccess condition = "is" >0x1010</ GrantedAccess >
</ Rule >
< Rule groupRelation = "and" >
< TargetImage condition = "is" >C:\Windows\system32\lsass.exe</ TargetImage >
< GrantedAccess condition = "is" >0x1FFFFF</ GrantedAccess >
</ Rule >
</ ProcessAccess >
</ RuleGroup > What each GrantedAccess value targets:
0x10 = PROCESS_VM_READ — read process memory (Mimikatz, ProcDump)
0x1010 = PROCESS_VM_READ | PROCESS_QUERY_LIMITED_INFORMATION — common Mimikatz pattern
0x1FFFFF = all access rights — ProcDump /ma flag
The rule is an OR of three AND conditions — it fires if any of the access patterns is observed. This is a high-confidence, low-FP rule because there are very few legitimate reasons for non-system processes to read LSASS memory with these specific access masks.
Know what your config doesn't cover
The most important thing to know about any Sysmon config — SwiftOnSecurity or sysmon-modular — is not what it detects, but what it misses. Check which event types have no include rules (effectively disabled) and which exclude rules suppress entire categories. Every suppressed event type is a detection blind spot. Run the config against EVTX-ATTACK-SAMPLES to see which technique samples generate events and which don’t.
SwiftOnSecurity sysmon-config— GitHub
sysmon-modular— GitHub
Retrieval Practice
Your team wants to add detection for DLL side-loading (T1574.002) to their Sysmon config. Which Sysmon event type covers this, and what fields would a detection rule use?
Reveal answer
Sysmon Event ID 7 (Image Load) records DLL loading. For DLL side-loading: a malicious DLL placed alongside a legitimate executable is loaded when the legitimate executable runs. The detection pattern: Event 7 where ImageLoaded path is in an unusual location (user-writable directory like AppData, Desktop, Downloads) AND the loading process (Image) is a legitimate application (e.g., OneDrive.exe, Slack.exe). Also check: Signed=false (unsigned DLL loaded by a signed process) or SignatureStatus=false. In sysmon-modular, add the 7_image_load/include_dll_sideloading.xml module to your config.
Retrieval Practice
A developer argues that enabling Sysmon Event ID 7 (Image Load) will flood the SIEM with DLL load events from every process. How do you respond, and what tuning approach preserves signal while managing volume?
Reveal answer
They're correct that Event 7 is the highest-volume Sysmon event — a typical process loads dozens of DLLs on startup. However, you don't need to log all DLL loads — only suspicious ones. Use an include-only config for Event 7 with conditions: (1) Signed=false (unsigned DLLs are unusual for legitimate software), (2) ImageLoaded path in user-writable locations (AppData, Temp, Downloads), or (3) ImageLoaded path does not start with C:\\Windows\\ or C:\\Program Files\\. This reduces Event 7 volume by 95%+ while preserving coverage for the DLL injection and side-loading patterns that matter.