Cheat sheet
Sigma and YARA
The two detection rule formats you should be able to read and write: Sigma for logs, YARA for files and memory. For the resulting queries, see SIEM queries.
Structure of a Sigma rule
| Field | Role |
|---|---|
| title | Short name of the rule |
| id | Unique identifier (UUID) |
| status | Maturity: experimental, test or stable |
| logsource | Targeted data source: product, category, service |
| detection | Field selections and the condition combining them |
| condition | Logical combination of the selections (and, or, not, 1 of selection*) |
| falsepositives | Known legitimate cases that trigger the rule |
| level | Severity: informational, low, medium, high, critical |
| tags | Related ATT&CK techniques (e.g. attack.t1059.001) |
title: PowerShell started by Word
id: 6e3f4c1a-0000-4000-8000-000000000001
status: experimental
logsource:
product: windows
category: process_creation
detection:
selection:
ParentImage|endswith: '\WINWORD.EXE'
Image|endswith: '\powershell.exe'
condition: selection
falsepositives:
- Documented internal macros
level: high
tags:
- attack.execution
- attack.t1204.002
Sigma field modifiers
| Modifier | Effect |
|---|---|
| |contains | The value appears anywhere in the field |
| |startswith | The field starts with the value |
| |endswith | The field ends with the value |
| |all | Every value of the list must be present |
| |re | Regular expression |
| |base64offset | Looks for the base64-encoded value, whatever its position |
| |cidr | The IP address belongs to a range |
| |windash | Accepts - and / before command-line options |
# Convert a rule to a SIEM query (pySigma, sigma-cli) sigma convert -t splunk -p sysmon rule.yml sigma convert -t lucene rule.yml
Sigma or a direct query?A Sigma rule can be shared and converted to any SIEM: it is the format of public repositories (SigmaHQ). A KQL or SPL query only works in its own tool.
Elements of a YARA rule
| Element | Meaning |
|---|---|
| meta: | Free metadata: author, description, date |
| strings: | Declaration of the patterns ($a, $b…) |
| condition: | Boolean expression deciding the match |
| nocase | Case-insensitive string |
| wide | UTF-16 string (two bytes per character) |
| ascii | ASCII string (default; combine with wide) |
| { 4D 5A ?? 00 } | Hexadecimal pattern; ?? stands for any byte |
| #a > 3 | Pattern $a appears more than three times |
| $a at 0 | Pattern $a is at the very start of the file |
| filesize < 1MB | The file is smaller than 1 MB |
| 2 of ($s*) | At least two of the patterns whose name starts with $s |
| uint16(0) == 0x5A4D | The first two bytes are MZ: Windows executable (PE) |
rule Suspicious_loader
{
meta:
description = "Example: executable that downloads and runs a script"
strings:
$s1 = "DownloadString" ascii wide nocase
$s2 = "powershell" ascii wide nocase
$s3 = "-enc" ascii wide
condition:
uint16(0) == 0x5A4D and filesize < 2MB and 2 of ($s*)
}
# Run: yara -r rule.yar folder/ (-s prints the matched strings)
Classic trapStrings in Windows executables are often UTF-16: without the wide keyword, the rule will not find them.