Prerequisites
- Target system, dependencies and environment configured.
Usage
Purpose
YARA is the standard language for pattern-matching malware — rules that describe the byte sequences, strings, and structure that identify a malware family, then match them across files, memory, and repositories. A good YARA rule catches the whole family (including new variants), not just the one sample you analysed; a bad one either misses variants or false-positives on legitimate files. This skill covers writing rules that generalise well and stay precise.
When to use it
After analysing a sample, to turn that analysis into a durable, family-level detection (feeds detection-engineering, threat-hunting, and IR scanning). It's how malware analysis produces detection that catches the next sample from the same actor, not just the one you have.
Procedure
- Analyse first, then generalise. A rule is only as good as your understanding of the family. From analysis (static/dynamic/code), identify what's characteristic and stable across the family versus what's specific to this one sample. You want to match the former.
- Choose distinctive, stable features — the art of good YARA:
- Unique strings — distinctive strings the malware author wrote (a custom mutex name, an unusual error message, a C2 URL pattern, a PDB path) that are unlikely in benign files.
- Code/byte patterns — a distinctive sequence of bytes from a characteristic routine (a decryption stub), using wildcards for the parts that vary (addresses, registers).
- Structure — PE characteristics, section names, imports combinations.
Avoid features that are common to many programs (they cause false positives) or that trivially change between variants (they miss them).
- Write the rule with a good condition. Combine features so the rule is specific but not brittle — e.g. "N of these M distinctive strings" tolerates variant differences while staying precise:
rule Family_X {
strings:
$a = "distinctive_mutex_name"
$b = { 8B 45 ?? 33 D2 F7 75 ?? } // code pattern, wildcards for variable bytes
$c = "unusual C2 path pattern"
condition:
uint16(0) == 0x5A4D and 2 of them // PE + at least 2 of the 3 features
}
- Test against both malware and benign corpora — mandatory. Run the rule against a set of the family's samples (does it catch them, including variants?) and a large set of known-good files (does it false-positive?). A rule untested against goodware is a false-positive incident waiting to happen.
- Balance breadth and precision. Too specific (matches only your one sample) misses variants; too broad (matches common patterns) false-positives. Tune toward "catches the family, matches nothing benign".
- Add metadata and share. Author, date, family, reference, and confidence in the rule's
meta block, so others can use and trust it. Contribute to shared rule sets where appropriate.
Cheatsheet
analyse -> identify what's STABLE across the family vs specific to this sample
(match the stable, characteristic features)
good features (distinctive + hard to change)
unique author strings: custom mutex, odd error msg, C2 pattern, PDB path
code/byte patterns from a characteristic routine (wildcard the variable bytes)
structural: section names, import combos, PE traits
avoid: common strings/patterns (false positives) | trivially-varying bytes (misses variants)
condition tips
uint16(0) == 0x5A4D // is a PE (MZ)
N of ($a,$b,$c) // tolerate variant differences, stay precise
$x at 0 / in (0..1024) // position constraints
TEST both ways (mandatory)
vs family samples + VARIANTS -> does it catch them?
vs large GOODWARE corpus -> does it false-positive?
balance: too specific = misses variants ; too broad = false positives
meta: author, date, family, reference, confidence -> shareable + trusted
Reading a rule's quality
- Catches the family including variants you didn't train on = a good, generalising rule; the whole point of family-level (not sample-level) detection.
- Matches only the exact sample you analysed = too specific; it's really just a hash with extra steps and misses the next variant. Generalise to stable features.
- False-positives on the goodware corpus = too broad or built on common features; unusable in production and erodes trust. This is why testing against benign files is mandatory, not optional.
- Built on author-written distinctive strings + a wildcarded code pattern = the durable core; these are hard for the author to change without effort (Pyramid-of-Pain thinking applied to signatures).
- An
N of them condition = tolerant of variant differences while staying precise; usually better than requiring all features.
- A tested, metadata-rich rule that catches the family and nothing benign = the deliverable — durable detection from your analysis.
Pitfalls
- Writing a rule that matches only your one sample. Overfitting to sample-specific bytes gives you a glorified hash; match the family's stable, characteristic features so it catches variants.
- Not testing against goodware. The single biggest YARA mistake — an untested rule false-positives on legitimate files in production. Always test against a large benign corpus.
- Using common strings/patterns. Features shared with benign software guarantee false positives; choose distinctive, author-specific ones.
- Rigid byte patterns. Matching exact bytes that vary between variants (addresses, registers) misses them; wildcard the variable parts.
- No metadata. A rule without author/family/reference is hard for others to trust or maintain; fill the
meta block.
References
- YARA documentation (virustotal.github.io/yara)
- yarGen / rule-generation tools (as a starting point, then hand-tune)
- The extracting-iocs, static-triage, and detection-engineering skills
- MITRE ATT&CK and the threat-intel pyramid-of-pain skill (durability thinking)
Inputs
- Relevant source code, logs, network traces, or system specifications.
Outputs
- Analysis findings, security audit report, or generated code artifacts.
1---2name: yara-rule-writing3description: Use when writing YARA rules to detect malware families — signatures that catch a whole family or campaign, not just one sample, without false-positiving on benign files.4---5678## Prerequisites9- Target system, dependencies and environment configured.1011## Usage12### Purpose1314YARA is the standard language for pattern-matching malware — rules that describe the byte sequences, strings, and structure that identify a malware family, then match them across files, memory, and repositories. A good YARA rule catches the whole family (including new variants), not just the one sample you analysed; a bad one either misses variants or false-positives on legitimate files. This skill covers writing rules that generalise well and stay precise.1516### When to use it1718After analysing a sample, to turn that analysis into a durable, family-level detection (feeds detection-engineering, threat-hunting, and IR scanning). It's how malware analysis produces detection that catches the *next* sample from the same actor, not just the one you have.1920### Procedure21221. **Analyse first, then generalise.** A rule is only as good as your understanding of the family. From analysis (static/dynamic/code), identify what's *characteristic and stable* across the family versus what's specific to this one sample. You want to match the former.232. **Choose distinctive, stable features** — the art of good YARA:24 - **Unique strings** — distinctive strings the malware author wrote (a custom mutex name, an unusual error message, a C2 URL pattern, a PDB path) that are unlikely in benign files.25 - **Code/byte patterns** — a distinctive sequence of bytes from a characteristic routine (a decryption stub), using wildcards for the parts that vary (addresses, registers).26 - **Structure** — PE characteristics, section names, imports combinations.27 Avoid features that are common to many programs (they cause false positives) or that trivially change between variants (they miss them).283. **Write the rule with a good condition.** Combine features so the rule is specific but not brittle — e.g. "N of these M distinctive strings" tolerates variant differences while staying precise:29 ```30 rule Family_X {31 strings:32 $a = "distinctive_mutex_name"33 $b = { 8B 45 ?? 33 D2 F7 75 ?? } // code pattern, wildcards for variable bytes34 $c = "unusual C2 path pattern"35 condition:36 uint16(0) == 0x5A4D and 2 of them // PE + at least 2 of the 3 features37 }38 ```394. **Test against both malware and benign corpora — mandatory.** Run the rule against a set of the family's samples (does it catch them, including variants?) *and* a large set of known-good files (does it false-positive?). A rule untested against goodware is a false-positive incident waiting to happen.405. **Balance breadth and precision.** Too specific (matches only your one sample) misses variants; too broad (matches common patterns) false-positives. Tune toward "catches the family, matches nothing benign".416. **Add metadata and share.** Author, date, family, reference, and confidence in the rule's `meta` block, so others can use and trust it. Contribute to shared rule sets where appropriate.4243### Cheatsheet4445```46analyse -> identify what's STABLE across the family vs specific to this sample47 (match the stable, characteristic features)4849good features (distinctive + hard to change)50 unique author strings: custom mutex, odd error msg, C2 pattern, PDB path51 code/byte patterns from a characteristic routine (wildcard the variable bytes)52 structural: section names, import combos, PE traits53avoid: common strings/patterns (false positives) | trivially-varying bytes (misses variants)5455condition tips56 uint16(0) == 0x5A4D // is a PE (MZ)57 N of ($a,$b,$c) // tolerate variant differences, stay precise58 $x at 0 / in (0..1024) // position constraints5960TEST both ways (mandatory)61 vs family samples + VARIANTS -> does it catch them?62 vs large GOODWARE corpus -> does it false-positive?6364balance: too specific = misses variants ; too broad = false positives65meta: author, date, family, reference, confidence -> shareable + trusted66```6768### Reading a rule's quality6970- **Catches the family including variants you didn't train on** = a good, generalising rule; the whole point of family-level (not sample-level) detection.71- **Matches only the exact sample you analysed** = too specific; it's really just a hash with extra steps and misses the next variant. Generalise to stable features.72- **False-positives on the goodware corpus** = too broad or built on common features; unusable in production and erodes trust. This is why testing against benign files is mandatory, not optional.73- **Built on author-written distinctive strings + a wildcarded code pattern** = the durable core; these are hard for the author to change without effort (Pyramid-of-Pain thinking applied to signatures).74- **An `N of them` condition** = tolerant of variant differences while staying precise; usually better than requiring all features.75- **A tested, metadata-rich rule that catches the family and nothing benign** = the deliverable — durable detection from your analysis.7677### Pitfalls7879- **Writing a rule that matches only your one sample.** Overfitting to sample-specific bytes gives you a glorified hash; match the family's stable, characteristic features so it catches variants.80- **Not testing against goodware.** The single biggest YARA mistake — an untested rule false-positives on legitimate files in production. Always test against a large benign corpus.81- **Using common strings/patterns.** Features shared with benign software guarantee false positives; choose distinctive, author-specific ones.82- **Rigid byte patterns.** Matching exact bytes that vary between variants (addresses, registers) misses them; wildcard the variable parts.83- **No metadata.** A rule without author/family/reference is hard for others to trust or maintain; fill the `meta` block.8485### References8687- YARA documentation (virustotal.github.io/yara)88- yarGen / rule-generation tools (as a starting point, then hand-tune)89- The extracting-iocs, static-triage, and detection-engineering skills90- MITRE ATT&CK and the threat-intel pyramid-of-pain skill (durability thinking)9192## Inputs93- Relevant source code, logs, network traces, or system specifications.9495## Outputs96- Analysis findings, security audit report, or generated code artifacts.