Writing Your First SIGMA Detection Rule
A step-by-step guide to creating SIGMA rules for detecting suspicious process execution on Windows endpoints.
SIGMA is the lingua franca of detection engineering. It is a generic, open-source signature format for log-based threat detection that can be compiled into queries for almost any SIEM platform — Splunk, Elastic, Microsoft Sentinel, QRadar, and more. Learning to write SIGMA rules is one of the highest-leverage skills a detection engineer can develop.
What is SIGMA?
SIGMA is to detection rules what Snort is to network IDS signatures. A single SIGMA rule can be converted to KQL, SPL, EQL, Lucene, or any other query language using sigma-cli. This portability makes it possible to write a rule once and deploy it everywhere.
The format is human-readable YAML. It describes:
- What log source to search (Windows event logs, syslog, web logs, etc.)
- What to look for (field/value conditions)
- How to correlate conditions (AND, OR, NOT, aggregation)
- Metadata (title, author, MITRE mapping, severity)
Anatomy of a SIGMA Rule
Here is the structure of a complete SIGMA rule:
title: Suspicious Encoded PowerShell Execution
id: a8b4f3c2-1234-5678-abcd-ef0123456789
status: test
description: Detects execution of PowerShell with Base64-encoded command via -EncodedCommand flag
references:
- https://attack.mitre.org/techniques/T1059/001/
author: Threat Detection Labs
date: 2026-05-16
tags:
- attack.execution
- attack.t1059.001
logsource:
category: process_creation
product: windows
detection:
selection:
Image|endswith:
- '\powershell.exe'
- '\pwsh.exe'
CommandLine|contains:
- ' -EncodedCommand '
- ' -enc '
- ' -ec '
condition: selection
falsepositives:
- Legitimate administrative scripts using encoded commands
- Software deployment tools (SCCM, Intune)
level: medium
Let’s break down each section:
logsource
Defines where to look. category: process_creation maps to Windows Security Event ID 4688 or Sysmon Event ID 1. The product: windows field tells the compiler to target Windows-specific data sources.
detection
This is the heart of the rule. It contains named field sets (called “selections”) and a condition expression that combines them.
| Modifier | Meaning |
|---|---|
contains | Field value contains the string (substring match) |
endswith | Field value ends with the string |
startswith | Field value starts with the string |
re | Regular expression match |
all | All values in the list must match |
condition
Uses boolean logic: selection1 and selection2, selection1 or selection2, not selection1, or aggregation functions like count() > 5.
A Complete Rule: Detecting Encoded PowerShell
Attackers frequently use Base64-encoded PowerShell to obfuscate their commands. A payload like:
powershell.exe -EncodedCommand JABjAGwAaQBlAG4AdAAgAD0A...
…is far harder to read at a glance than a plaintext command. Our rule above detects any process creation where PowerShell is invoked with encoding flags. Here is a more complete version with additional context:
title: Encoded PowerShell Execution via Command Line
id: b64-ps-execution-v2
status: production
description: >
Detects PowerShell invoked with -EncodedCommand, -enc, or -ec flags.
Encoded commands are frequently used by attackers to bypass simple string
matching and hide malicious payloads.
references:
- https://attack.mitre.org/techniques/T1059/001/
- https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_powershell_exe
author: Threat Detection Labs
date: 2026-05-16
modified: 2026-05-16
tags:
- attack.execution
- attack.defense_evasion
- attack.t1059.001
- attack.t1027
logsource:
category: process_creation
product: windows
detection:
selection_image:
Image|endswith:
- '\powershell.exe'
- '\pwsh.exe'
selection_cli:
CommandLine|contains:
- ' -EncodedCommand '
- ' -enc '
- ' -ec '
- ' /EncodedCommand '
- ' /enc '
filter_known_good:
ParentImage|endswith:
- '\msiexec.exe'
condition: selection_image and selection_cli and not filter_known_good
falsepositives:
- Some legitimate software installers
- SCCM/Intune deployment scripts
level: medium
Testing Your Rule
Before deploying, test locally with sigma-cli:
# Install sigma-cli
pip install sigma-cli
# Convert to KQL for Microsoft Sentinel
sigma convert -t kusto rule.yml
# Convert to Splunk SPL
sigma convert -t splunk rule.yml
# Convert to Elastic EQL
sigma convert -t eql rule.yml
The KQL output will look something like:
DeviceProcessEvents
| where FileName in~ ("powershell.exe", "pwsh.exe")
and ProcessCommandLine has_any ("-EncodedCommand", "-enc", "-ec", "/EncodedCommand")
and not (InitiatingProcessFileName =~ "msiexec.exe")
Common Pitfalls
1. Over-broad conditions — Using contains: 'power' will match everything with “power” in the path. Be specific.
2. Missing case sensitivity — Windows file paths are case-insensitive. Use the |windash modifier to handle \ vs / variants, and note that most backends handle case-insensitivity automatically.
3. Skipping false positive analysis — Before going to production, run the converted query against 30 days of logs in count-only mode. Anything over ~50 hits/day needs filtering.
4. Missing parent process context — Adding ParentImage conditions dramatically reduces false positives on rules targeting common binaries like cmd.exe or wscript.exe.
Next Steps
Once you have your first rule working:
- Add it to a SIGMA rule repository (e.g.,
SigmaHQ/sigma) - Set up automated conversion in your CI/CD pipeline
- Map it to your detection coverage heatmap in ATT&CK Navigator
SIGMA rules compound in value — the more you write, the clearer the gaps in your coverage become.