Sigma detection rules for Windows, written from scratch and validated against real attack telemetry rather than synthetic tests.
Every rule in this repo is checked against EVTX-ATTACK-SAMPLES — 278 Windows event log captures of genuine attacker activity, labelled by MITRE ATT&CK technique. A rule only counts here if it fires on a real capture.
The usual home SOC lab is a hypervisor, a Windows VM, an agent and a simulated attack. Most of the effort goes into infrastructure, and the resulting detections are only ever tested against the handful of commands you ran yourself.
Working directly on a public corpus of real attack logs inverts that: no VM to maintain, and the rules are graded against telemetry produced by actual tooling — mimikatz, Meterpreter, Impacket, Atomic Red Team — including the messy parts a hand-run test never reproduces.
3 rules, all passing sigma check with no errors or validation issues.
17 detections across 15 distinct attack captures.
| Rule | ATT&CK | Severity | Hits | Caught in the wild |
|---|---|---|---|---|
| Suspicious LSASS Process Access | T1003.001 | critical | 10 | mimikatz, Meterpreter hashdump, MalSeclogon, Atomic Red Team |
| PowerShell Encoded Command | T1059.001, T1027 | high | 3 | Meterpreter payloads over PsExec/SMB, IIS credential discovery |
| Schtasks Persistence | T1053.005 | medium | 4 | mshta pulling a payload from a URL, execution from a shadow copy |
Full breakdown, regenerated on every run: docs/ATTACK-COVERAGE.md
The rules are also translated into Splunk SPL (3 of 3) and KQL for Microsoft Defender XDR
(2 of 3) — see converted/. The conversions that failed are documented there too,
because each failure maps to a real telemetry gap: for example, the Windows Security log carries
no OriginalFileName, so renamed-binary protection disappears in environments that collect only
native Security events.
Detect the mechanism, not the tool. The LSASS rule keys on the process access mask
(0x1010, 0x1410, 0x1f0fff, …) rather than on file names or hashes. Reading LSASS memory is
unavoidable for credential theft, so the rule catches four separate tools without naming a
single one — and a renamed binary does not evade it.
Renaming is cheap, so don't rely on file names. Where Sysmon provides OriginalFileName
from the PE header, rules match on it alongside Image, since renaming a file on disk does not
change what the header says.
Scope a rule to what it claims to detect. The first version of the PowerShell rule fired on
evasion flags such as -NoProfile on their own. Checked against the corpus, two of its five hits
were powershell.exe -s -NoLogo -NoProfile — the command line of the PowerShell remoting host,
identical for legitimate administration and for lateral movement. The rule now requires either
the -EncodedCommand flag or a hidden window combined with inline Base64 decoding or in-memory
decompression. That dropped both remoting-host hits and kept both Meterpreter payloads, which
never use -enc at all.
Severity reflects response cost, not scariness. The schtasks rule is medium, not high:
software updaters and RMM agents create interpreter-backed scheduled tasks constantly. A rule
that pages an analyst dozens of times a day gets ignored, and an ignored rule detects nothing.
Documented deliberately — a rule whose limits are unknown is a rule you cannot trust.
- Schtasks rule misses RPC-created tasks. It is scoped to
process_creation, so it only sees theschtasks.exebinary running. Creating a task through the COM API, the PowerShellScheduledTasksmodule, or RPC over\PIPE\atsvc(asimpacket-atexecdoes) never spawns that process. The sampletemp_scheduled_task_4698_4699.evtxcontains exactly this: a task registered as SYSTEM that this rule does not catch. Covering the technique properly needs a second rule on Security event 4698, parsing the task XML. schtasks /XMLhides the payload. With that flag the task action lives in an external file, so the command line carries no interpreter or LOLBin to match on. Current coverage depends on the XML path sitting in a user-writable directory.- False positives are not yet baselined. The corpus contains attacks, not normal office traffic, so the rules have never been measured against a clean environment.
Requires Chainsaw and the sample corpus, neither of which is committed here.
git clone --depth 1 https://github.com/sbousseaden/EVTX-ATTACK-SAMPLES.git ../data-evtx-attack-samples
python -m venv .venv
./.venv/Scripts/python.exe -m pip install sigma-cli pysigma-backend-splunk pyyamlValidate the rules:
./.venv/Scripts/sigma.exe check rules/Hunt across the corpus:
./bin/chainsaw/chainsaw_x86_64-pc-windows-msvc.exe hunt "../data-evtx-attack-samples" -s rules/ --mapping bin/chainsaw/mappings/sigma-event-logs-all.yml --skip-errors --json -o out/detections.jsonRegenerate the coverage report:
./.venv/Scripts/python.exe scripts/report.pyrules/windows/ Sigma rules
converted/ the same rules as Splunk SPL and Defender XDR KQL, with conversion gaps explained
scripts/ report.py - correlates hits back to ATT&CK, flags silent rules
docs/ generated coverage report
- Security 4698 rule with task XML parsing, to close the gap above
- Registry Run key persistence (T1547.001)
- Service creation / PsExec pattern (T1543.003)
- Event log clearing (T1070.001)
- CI workflow validating every rule on push