From a log to a detection that works in any SIEM
During an investigation you spot the pattern: a 4625 followed by a 4624 from the same IP, or a PowerShell with -enc. Good. Now turn it into a permanent detection. And here comes the usual problem: you write it in KQL and it only works for Sentinel; your colleague needs it in SPL for Splunk; the next person, in Elastic. The same work three times, three places to drift out of sync.
Sigma: the "YAML of detections"
Sigma is an open, vendor-neutral format for detection rules. You write the logic once, in readable YAML, and a converter translates it into your SIEM's language: KQL, SPL, Elastic's Lucene/EQL, Wazuh… It is to detections what YARA rules are to files: portable and shareable. That is why vendors, CERTs and projects like the official Sigma rules repo publish them.
Anatomy of a rule
Many failed logons followed by a success
- Problem
- Password guessing leaves a burst of
4625and, if the attacker gets it right, a4624for the same account. - Goal
- Alert when an account piles up failures from an IP and then logs on from it.
- Telemetry
- Windows Security, events
4625(failure) and4624(success). - Requirements
- «Audit Logon» with Success and Failure, and a converter or SIEM that supports Sigma correlation rules.
- Level
- Medium
title: Failed logon
name: failed_logon
status: experimental
logsource:
product: windows
service: security
detection:
selection:
EventID: 4625
condition: selection
---
title: Successful logon
name: successful_logon
status: experimental
logsource:
product: windows
service: security
detection:
selection:
EventID: 4624
condition: selection
---
title: Burst of failed logons
name: many_failed_logons
status: experimental
correlation:
type: event_count
rules:
- failed_logon
group-by:
- TargetUserName
- IpAddress
timespan: 10m
condition:
gte: 5
---
title: Failures followed by success (possible brute force)
status: experimental
correlation:
type: temporal_ordered
rules:
- many_failed_logons
- successful_logon
group-by:
- TargetUserName
- IpAddress
timespan: 1h
falsepositives:
- Corporate VPN with legitimate retries
level: medium
tags:
- attack.credential-access
- attack.t1110.001
How it works. Two base rules (failure and success) and two correlations: event_count requires 5 or more failures for the same account and IP within 10 minutes, and temporal_ordered requires a success to follow within 1 hour. A single condition cannot say «first this, then that»: it is evaluated on each event separately.
Known false positives
- VPNs or apps with an expired password that retry on their own.
- Someone who forgets their password and eventually gets it right.
Limits
- It misses password spraying (a few attempts on many accounts): for that, group by IP only.
- The thresholds (5 failures, 10 minutes, 1 hour) are a starting point: tune them to your environment.
- Not every Sigma converter supports correlations.
Sources: SigmaHQ — Sigma Correlation Rules Specification
The pieces that matter: logsource (where events come from), detection with one or more selections and a condition that combines them, the level (severity) and —crucially— falsepositives and the MITRE ATT&CK tags, which pin the rule to a concrete technique. When several events have to be linked, correlation comes in.
A correction. The first version of this article used a single rule with condition: fail and success. That rule never fires: the condition is evaluated on each event separately, and no event is both a 4625 and a 4624. «First this, then that» is a correlation: event_count counts the failures and temporal_ordered requires the success to come afterwards.
From log to rule, step by step
- Isolate the event in the real log: which fields identify it (EventID, process image, command line, port…).
- Write the selection with those fields. Be specific:
Image|endswith: '\powershell.exe'andCommandLine|contains: '-enc'beats searching for just "powershell". - Define the condition (one selection, several with
and/or, or exclusions withnot filter). - Map to ATT&CK and document the false positives you already know.
- Convert and test in your SIEM before trusting it.
sigma-cli toolchain, Sigma Forge takes you from a real log to the Sigma rule and then to KQL, SPL, Lucene, EQL and Wazuh — paste the event, tune the selection and copy the query for your platform. All in your browser.The real enemy: false positives
A rule that fires a hundred times a day is not a detection, it is noise the analyst learns to ignore —and that is exactly where the real attack slips through—. Precise selections, exclusions of known-legit activity, and an honest level separate a useful rule from one that ends up muted.
Checklist
- ✅ Is the detection tied to ONE SIEM? Write it in Sigma and convert it.
- ✅ Specific selection (image + arguments + fields), not loose keywords.
- ✅ Clear
condition; usenotto exclude known-legit activity. - ✅ Map to MITRE ATT&CK and fill in
falsepositives. - ✅ Test it with a real event before deploying.
Writing in Sigma is not one more layer of work: it is writing once instead of three times, and leaving the detection where anyone —including you six months from now— can read it and carry it to their platform.