Sigma and YARA rules explained.
Sigma rules detect threats in logs; YARA hunts malware in files. A practical, example-driven guide to detection-as-code and how to convert and test rules.
Two rules can describe the same attack from opposite ends. One says: "when a Windows host logs a PowerShell process that reaches out to the internet and pulls down code, raise an alert." The other says: "when a file on disk contains this exact byte pattern, flag it as malware." The first is a Sigma rule: it reasons about events in your logs. The second is a YARA rule: it reasons about bytes in your files. Learn both and you can express detections that travel between tools instead of rotting inside one vendor's console.
This is the core idea behind detection-as-code, and it is the thread that ties this whole article together. Let's start there, then work through each language with real, runnable rules you can read line by line.
What is detection-as-code, and why bother?
For years, detection logic lived where nobody could see it: hand-typed into a SIEM search bar, saved as a correlation rule in a GUI, or worse, in an analyst's head. That approach has three chronic problems. It is not portable: a Splunk search does not run on Elastic. It is not reviewable: there is no diff, no pull request, no history of who changed what and why. And it is not testable: you find out a rule was broken when it fails to fire during an incident.
Detection-as-code treats detections the way engineers treat software. Rules are plain-text files, stored in Git, reviewed by a second pair of eyes, versioned, tagged with the technique they cover, and validated in CI before they ever reach production. You get a changelog for your defenses. When a detection misfires, you can bisect it. When you switch platforms, you migrate the rules instead of rewriting your program from scratch. Sigma and YARA are the two most widely adopted formats for doing exactly this – one for logs, one for files.
Sigma: a generic detection rule for logs and SIEMs
Sigma is an open, vendor-neutral format for describing detections over log data. Created by Florian Roth and Thomas Patzke and maintained by the SigmaHQ project, it is often described as "the YAML that means the same thing everywhere." You write the logic once, and a converter turns it into the query language of whichever SIEM you actually run – Splunk SPL, Elastic's KQL and EQL, Microsoft Sentinel's KQL, QRadar AQL, and many more. Think of Sigma as the interlingua of the SOC toolstack: analysts read one grammar, and every platform speaks its own dialect underneath.
How a Sigma rule is structured
Every Sigma rule is a YAML document with a handful of load-bearing keys:
- title / id / description: human metadata. The
idis a stable UUID so tooling can track a rule across renames. - logsource: where to look. A
category(likeprocess_creation), aproduct(likewindows), or aservice(likesshd). This is what lets one rule map onto many different log schemas. - detection: what to look for. One or more named "selection" blocks of field/value matches, using modifiers like
|contains,|endswith, or|contains|all. - condition: how the selections combine: boolean logic like
selection and not filter. - falsepositives / level / tags: triage hints and, importantly, MITRE ATT&CK technique tags so the rule slots into a coverage map.
A complete Sigma rule, commented
Here is a full, valid rule that detects a classic PowerShell download cradle: the kind of one-liner malware droppers love:
title: PowerShell Web Download via Net.WebClient # shown in the alert
id: e6c54d94-498c-4b93-a2d1-1a3e7f9c02aa # stable UUID for tracking
status: test # experimental | test | stable
description: Detects PowerShell using Net.WebClient to pull a remote payload
references:
- https://attack.mitre.org/techniques/T1059/001/
author: Breachfolio
date: 2026/07/15
logsource: # WHERE to look, independent of SIEM
category: process_creation # e.g. Sysmon Event ID 1
product: windows
detection: # WHAT to look for
selection_img: # the PowerShell binary itself
- Image|endswith: '\powershell.exe'
- OriginalFileName: 'PowerShell.EXE'
selection_cli: # AND both strings in the command line
CommandLine|contains|all:
- 'Net.WebClient'
- 'DownloadString'
condition: selection_img and selection_cli # how the blocks combine
falsepositives:
- Legitimate admin or software-deployment scripts
level: high # informational | low | medium | high | critical
tags:
- attack.execution
- attack.t1059.001
Read it top to bottom and it is almost prose: on Windows, in process-creation events, find PowerShell where the command line contains both Net.WebClient and DownloadString. Notice what the rule does not say: it never mentions Splunk, Elastic, or a specific field-mapping. That abstraction is the whole point.
Converting Sigma to your SIEM with sigma-cli and pySigma
The engine that turns that YAML into a real query is pySigma, usually driven through the sigma-cli command-line tool. Install it and list what backends are available:
$ pipx install sigma-cli
$ sigma list targets # splunk, elasticsearch, kusto (Sentinel/KQL), qradar, ...
$ sigma list pipelines # sysmon, windows-audit, crowdstrike, ...
A "pipeline" tells the converter how the abstract fields (like Image) map onto the concrete schema of your logs (like a Sysmon EventCode=1 event). To emit Splunk SPL for the rule above using the Sysmon pipeline:
$ sigma convert -t splunk -p sysmon powershell_webclient.yml
The output is a native Splunk search: the exact text depends on the pipeline, but it looks like this:
EventCode=1 (Image="*\\powershell.exe" OR OriginalFileName="PowerShell.EXE")
CommandLine="*Net.WebClient*" CommandLine="*DownloadString*"
Swap -t splunk for -t elasticsearch and you get an Elastic query instead; swap in -t kusto and you get KQL for Microsoft Sentinel or Defender. One source rule, many targets. That is how a community of thousands can share detections despite running completely different platforms.
YARA: pattern matching on files, memory, and malware
YARA answers a different question. It does not look at events; it looks at content: the raw bytes of files, process memory, or network buffers. Created by Victor Alvarez and maintained by VirusTotal, YARA is the de facto standard for describing malware families and is often called "the pattern-matching Swiss army knife for malware researchers." Where Sigma expresses a behavior in your logs, a YARA rule expresses a signature: the fingerprints that make a piece of code recognizably itself. Those fingerprints are a species of indicator of compromise, encoded so a scanner can act on them.
How a YARA rule is structured
A YARA rule has three sections inside a rule block:
- meta: free-form metadata: author, description, date, reference links, sample hashes. It has no effect on matching; it is there for humans and triage tooling.
- strings: the patterns to search for. These can be text (
"System.Net.WebClient"), hexadecimal byte sequences ({ 4D 5A }), or regular expressions (/[a-f0-9]{32}/), each with modifiers likenocase,ascii, andwide. - condition: the boolean logic that decides a match: how many strings, in what combination, at what offset, under what file size. This is where YARA's real expressiveness lives.
A complete YARA rule
Here is a rule that flags a small Windows executable carrying an embedded PowerShell downloader stub:
rule Win_Downloader_PowerShell_Stub
{
meta:
description = "Windows PE bundling a PowerShell download cradle"
author = "Breachfolio"
date = "2026-07-15"
reference = "https://attack.mitre.org/techniques/T1059/001/"
hash = "d41d8cd98f00b204e9800998ecf8427e"
strings:
$mz = { 4D 5A } // PE magic bytes "MZ"
$ps_enc = "powershell -nop -w hidden -enc" ascii wide nocase
$webclient = "System.Net.WebClient" ascii wide
$download = "DownloadString" ascii wide
condition:
// must start with MZ, be small, and hold the downloader strings
$mz at 0 and filesize < 500KB and $ps_enc and $webclient and $download
}
The ascii wide modifier tells YARA to match both plain and UTF-16 encodings of a string – essential on Windows, where the same text appears both ways. The condition $mz at 0 anchors the "MZ" magic to the very first byte so the rule only fires on real PE files, and filesize < 500KB keeps it from wasting cycles on large, irrelevant files. Small touches like these are the difference between a precise rule and a false-positive machine.
Testing a YARA rule from the command line
The yara CLI is delightfully direct. Point it at a rule and a target:
$ yara -r -s downloader.yar /samples/ # -r recursive, -s show matched strings
Win_Downloader_PowerShell_Stub /samples/dropper.exe
0x0:$mz: 4D 5A
0x3f10:$ps_enc: powershell -nop -w hidden -enc
0x41a8:$webclient: System.Net.WebClient
The same binary works against a memory dump or, with a scanner integration, live process memory – which is why YARA shows up constantly in digital forensics and DFIR, where investigators sweep RAM and disk images for known-bad code that never touched a log.
When to use which
The dividing line is simple: Sigma is for what happened; YARA is for what a thing is. If your evidence is an event – a process spawned, a user authenticated, a DNS query resolved – reach for Sigma. If your evidence is an artifact – a file, a memory region, a document – reach for YARA. Most mature detection programs run both, because attacks leave both kinds of trace.
| Dimension | Sigma | YARA |
|---|---|---|
| What it inspects | Log events (SIEM data) | Files, memory, raw bytes |
| Question it answers | "Did this behavior occur?" | "Is this thing malicious?" |
| Format | YAML, converted to SIEM queries | Native .yar rule syntax |
| Where it runs | Splunk, Elastic, Sentinel, QRadar… | yara CLI, EDR, sandboxes, VirusTotal |
| Core sections | logsource, detection, condition | meta, strings, condition |
| Example use | Alert on a PowerShell download cradle in logs | Flag a dropper family on disk or in RAM |
| Maintainer | SigmaHQ (Roth, Patzke) | VirusTotal (Victor Alvarez) |
The cousins: KQL, SPL, EQL, and Suricata rules
Sigma and YARA do not live alone. Once a Sigma rule is converted, it becomes native query language – SPL in Splunk, KQL in Microsoft Sentinel and Elastic, or EQL (Event Query Language) in Elastic for sequence-based detections that chain events in order. These are the "run-time" languages Sigma compiles down to; you will still read and tune them by hand, but Sigma keeps the portable source of truth.
On the network side, the equivalent of YARA is Suricata (and Snort) rules, which pattern-match on packets and flows rather than files. A Suricata signature reads a little like a YARA rule crossed with a firewall ACL:
alert http any any -> any any (msg:"Suspicious PowerShell UA";
http.user_agent; content:"WindowsPowerShell"; sid:1000001; rev:1;)
If you want to see how the network-detection engines compare head to head, our Snort vs Suricata breakdown covers that ground. The mental model to keep: Sigma watches logs, YARA watches files, Suricata watches the wire, and mature programs wire all three into the same alerting pipeline.
Where to find detection rules
You rarely start from a blank file. Enormous, curated, open repositories already cover the common ground, and reading them is the fastest way to learn the idioms:
- SigmaHQ/sigma – the canonical Sigma rule repository, thousands of community-maintained rules mapped to MITRE ATT&CK.
- Neo23x0/signature-base – Florian Roth's widely used base of YARA (and Sigma) signatures, the ruleset behind the THOR/LOKI scanners.
- Yara-Rules/rules – a large community collection of YARA rules organized by malware family and category.
- elastic/detection-rules – Elastic Security's open detection ruleset, including EQL and KQL logic you can study alongside Sigma.
- YARAify (abuse.ch) – a free service to scan files against a large public pool of YARA rules and to hunt with your own.
For the official references, keep the YARA documentation and the Sigma specification within reach – both are the ground truth when a modifier or condition does not behave the way you expect.
Writing and testing rules without drowning in false positives
A rule that never fires is useless; a rule that fires on everything is worse, because it trains your analysts to ignore it. The discipline that separates good detection engineers from bad ones is testing against reality. A few habits carry most of the weight:
- Test on both benign and malicious samples. Run YARA against a folder of clean, legitimate binaries (
yara -r rule.yar /clean_corpus/) and confirm zero hits before you trust a match on a real sample. For Sigma, validate the converted query against historical logs and count how noisy it is over a normal week. - Anchor and constrain. In YARA, use
filesizelimits, offset anchors like$mz at 0, and require several strings together rather than a single common one. In Sigma, addfilterselections andand notconditions to carve out known-good software. - Fill in
falsepositiveshonestly. That field is not decoration: it is the note your future self reads at 3 a.m. deciding whether an alert matters. - Lint and validate in CI.
sigma checkvalidates rule syntax, andyara -w(disable warnings) plus a compile step catches broken rules before they ship. Wire both into a pull-request check so a bad rule never merges. - Tag to a framework. Mapping every rule to a MITRE ATT&CK technique turns a pile of detections into a coverage map, so you can see what you are blind to.
Do these things and detection stops being folklore. Your rules become artifacts you can review, migrate, and trust, which is the entire promise of detection-as-code. Sigma gives you portable eyes on your logs; YARA gives you precise fingerprints for your files. Learn to write and test both, and you can describe almost any threat in a form that outlives whatever tool you happen to run today.
Frequently asked questions
What is the difference between Sigma and YARA?
What is a Sigma rule?
How do I convert a Sigma rule to Splunk or Elastic?
What is a YARA rule used for?
Where can I find ready-made detection rules?
Can YARA scan memory, or is it only for files on disk?
Daniel A. and Óscar S. run Breachfolio, a small independent site about security and AI. This article was drafted with AI assistance and reviewed by a person before it went live. We write from documentation, vendor sources and published research rather than from original lab benchmarks, and we link a source in the sentence that relies on it. How we work · About us
