YARA Rule Authoring
Write YARA-X rules that catch the intended family without drowning analysts in false positives.
Target runtime: YARA-X (Rust successor to legacy YARA). Install: brew install yara-x or cargo install yara-x. Essential CLI: yr check, yr scan, yr fmt, yr dump.
When to Use
- Write, review, or optimize YARA-X rules for malware, hacktools, webshells, or supply-chain artifacts
- Convert IOCs or threat intel into maintainable signatures
- Debug false positives or tune
any of / all of logic
- Migrate legacy YARA rules to YARA-X stricter validation
- Author Chrome extension (
crx) or Android DEX (dex) module rules
- Prepare rulesets for production, YARA-CI, or VirusTotal retrohunt
When NOT to Use
- Full malware reverse engineering, disassembly, or unpacker development →
reverse-engineer
- Network intrusion detection (Suricata, Snort, Zeek) → network security / SOC tooling skills
- Memory forensics with Volatility or live RAM analysis →
digital-forensics-analyst
- Hash-only blocklists with no pattern logic → use IOC lists or EDR hash feeds
- Enterprise security strategy, GRC, or audit evidence →
cybersecurity, compliance-engineer
- Embedding YARA in CI/CD pipelines as the primary task →
devsecops
- Adversarial LLM or application red team →
ai-redteam
Related skills
| Need |
Skill |
| Security program, IR strategy, detection philosophy |
cybersecurity |
| SIEM/EDR rules, logging, control implementation |
information-security-engineer |
| Audit evidence, control mapping, CCM |
compliance-engineer |
| Pipeline gates, artifact scanning, SBOM |
devsecops |
| Binary RE, unpacking, patch diff |
reverse-engineer |
| SOC alert triage and detection tuning (non-YARA) |
defensive-security-analyst, soc-analyst |
| Proactive threat hunts and ATT&CK campaigns |
threat-hunter |
| CTI briefs, IOC/TTP production |
cti-analyst |
| Adversarial AI / prompt injection testing |
ai-redteam |
| Disk imaging and forensic reports |
digital-forensics-analyst |
Core principles
- Atoms matter — YARA extracts 4-byte subsequences for Aho-Corasick prefilter. Strings with repeated bytes, common sequences, or under 4 bytes force expensive bytecode verification on too many files.
- Family-specific, not category-generic — "Detects ransomware" matches everything and nothing. Target identifiable mutexes, PDB paths, C2 paths, or structural markers for one family or campaign.
- Goodware before production — Validate against ecosystem-appropriate clean corpus (VT goodware for PE; top npm packages for JS; marketplace extensions for CRX).
- Short-circuit cheap checks first —
filesize → magic bytes → strings → modules.
- Metadata is documentation — Name, description, author, reference, and date survive personnel changes.
Essential toolkit
| Tool |
Purpose |
| yarGen |
Candidate strings from samples (--excludegood); always yr check output |
| FLOSS |
Obfuscated/stack strings when yarGen fails |
| yr |
yr check, yr scan -s, yr fmt, yr dump -m pe|crx|dex |
| YARA-CI / VT retrohunt |
Goodware corpus testing before deploy |
Core workflows
1. Scope samples and file type
- Collect 3+ variants when possible (single-sample rules are brittle)
- Check packing: entropy > 7.0 or few strings → unpack or target packer/structure, not encrypted layer
- Choose platform path: PE magic / JS / Office ZIP /
import "crx" / import "dex"
See references/yara_x_scope_and_tooling.md for install, CLI workflow, and migration.
2. Extract and filter strings
- Run yarGen or FLOSS on unpacked samples
- Reject ~80% of yarGen output: API names,
C:\Windows\, format strings, require/fetch alone
- Prefer gold tier: mutex names, PDB paths, stack strings; silver: C2 paths, config markers
See references/string_selection_and_atoms.md for decision trees and modifiers.
3. Write rule with ordered conditions
rule MAL_Win_Example_Loader_Jan26
{
meta:
description = "Detects Example loader via unique mutex and config path"
author = "Team <team@example.com>"
reference = "https://example.com/analysis"
date = "2026-01-15"
strings:
$mutex = "Global\\ExampleMutex" ascii wide
$cfg = "/api/beacon/check" ascii
condition:
filesize < 10MB and
uint16(0) == 0x5A4D and
all of ($mutex, $cfg)
}
Condition order: filesize → magic bytes → string matches → module calls (pe, crx, dex).
See references/conditions_and_performance.md for atom theory, regex bounds, and loops.
4. Validate and test
yr check rule.yar && yr fmt -w rule.yar
yr scan -s rule.yar malware_samples/ # must match all targets
yr scan -c rule.yar goodware_corpus/ # must be zero
FP flow: yr scan -s on false positive → identify matching string → tighten, exclude vendor, or pivot to structure.
See references/testing_goodware_and_fp_debugging.md for corpus selection and investigation.
5. Platform modules (when applicable)
- Chrome extensions:
import "crx" — permissions, permhash() (v1.11.0+). Always crx.is_crx first.
- Android:
import "dex" — dex.contains_class(), contains_method(), contains_string(). API differs from legacy YARA dex module.
See references/platform_modules_pe_crx_dex.md.
6. Deploy
- Naming:
{CATEGORY}_{PLATFORM}_{FAMILY}_{VARIANT}_{DATE} (e.g. MAL_Win_Emotet_Loader_Jan26)
- Peer review + quality checklist
- Monitor production FPs; version rules in Git with full metadata
See references/style_metadata_and_deployment.md.
Decision trees (quick reference)
Is this string good enough?
< 4 bytes? → reject
Repeated bytes (0000, 9090)? → reject
API name or common path? → reject
Unique to family? → use
Common across malware? → combine with family-specific marker
any of vs all of
- Individually unique strings →
any of ($a*)
- Common strings that are suspicious only together →
all of ($a*)
- Mixed confidence →
all of ($core_*) and any of ($variant_*)
Production lesson: any of ($network_*) with fetch, axios, http matches most web apps — require credential path and exfil destination and network call.
When strings fail → pivot
Use yr dump -m pe for sections, imports, imphash, resources; math.entropy() on sections; packer signatures. If nothing unique remains, YARA alone may not be the right control.
Legacy YARA migration
yr check --relaxed-re-syntax rules/ # diagnostic only
yr check rules/ # fix until clean
Common fixes: escape \{ in regex; base64 strings need 3+ chars; @a[-1] → @a[#a - 1]; remove duplicate modifiers.
Rationalizations to reject
| Thought |
Reality |
| "yarGen gave me these strings" |
yarGen suggests; you validate each string |
| "It works on 10 samples" |
Test goodware corpus before deploy |
| "I'll tighten after FPs" |
FPs burn trust — write tight rules upfront |
| "This API name is malicious" |
Legitimate software uses the same APIs |
| "any of them is fine" |
Common strings + any = FP flood |
Quality checklist
When to load references
| Topic |
Reference |
| YARA-X install, CLI, migration, toolkit |
references/yara_x_scope_and_tooling.md |
| String quality, types, modifiers |
references/string_selection_and_atoms.md |
| Atoms, condition order, regex, loops |
references/conditions_and_performance.md |
| PE, macOS, JS, crx, dex patterns |
references/platform_modules_pe_crx_dex.md |
| Goodware testing, FP debugging |
references/testing_goodware_and_fp_debugging.md |
| Naming, metadata, deployment |
references/style_metadata_and_deployment.md |
1---2name: yara-rule-authoring3description: Guides authoring, review, optimization, and false-positive debugging of YARA-X detection rules for malware identification across PE, script, npm, Office, Chrome extensions (crx module), and Android DEX (dex module). Covers string and atom quality, condition short-circuiting, legacy YARA migration, yarGen/FLOSS workflows, goodware validation, and production deployment—not full malware reverse engineering, network IDS (Suricata/Snort), or memory forensics (Volatility). Use when the user asks to write YARA rule, YARA-X, yr check, yr scan, false positive YARA, yarGen, malware detection rule, crx module, dex module, optimize YARA performance, or migrate legacy YARA.4---56# YARA Rule Authoring78Write YARA-X rules that catch the intended family without drowning analysts in false positives.910> **Target runtime:** YARA-X (Rust successor to legacy YARA). Install: `brew install yara-x` or `cargo install yara-x`. Essential CLI: `yr check`, `yr scan`, `yr fmt`, `yr dump`.1112## When to Use1314- Write, review, or optimize YARA-X rules for malware, hacktools, webshells, or supply-chain artifacts15- Convert IOCs or threat intel into maintainable signatures16- Debug false positives or tune `any of` / `all of` logic17- Migrate legacy YARA rules to YARA-X stricter validation18- Author Chrome extension (`crx`) or Android DEX (`dex`) module rules19- Prepare rulesets for production, YARA-CI, or VirusTotal retrohunt2021## When NOT to Use2223- Full malware reverse engineering, disassembly, or unpacker development → `reverse-engineer`24- Network intrusion detection (Suricata, Snort, Zeek) → network security / SOC tooling skills25- Memory forensics with Volatility or live RAM analysis → `digital-forensics-analyst`26- Hash-only blocklists with no pattern logic → use IOC lists or EDR hash feeds27- Enterprise security strategy, GRC, or audit evidence → `cybersecurity`, `compliance-engineer`28- Embedding YARA in CI/CD pipelines as the primary task → `devsecops`29- Adversarial LLM or application red team → `ai-redteam`3031## Related skills3233| Need | Skill |34|---|---|35| Security program, IR strategy, detection philosophy | `cybersecurity` |36| SIEM/EDR rules, logging, control implementation | `information-security-engineer` |37| Audit evidence, control mapping, CCM | `compliance-engineer` |38| Pipeline gates, artifact scanning, SBOM | `devsecops` |39| Binary RE, unpacking, patch diff | `reverse-engineer` |40| SOC alert triage and detection tuning (non-YARA) | `defensive-security-analyst`, `soc-analyst` |41| Proactive threat hunts and ATT&CK campaigns | `threat-hunter` |42| CTI briefs, IOC/TTP production | `cti-analyst` |43| Adversarial AI / prompt injection testing | `ai-redteam` |44| Disk imaging and forensic reports | `digital-forensics-analyst` |4546## Core principles47481. **Atoms matter** — YARA extracts 4-byte subsequences for Aho-Corasick prefilter. Strings with repeated bytes, common sequences, or under 4 bytes force expensive bytecode verification on too many files.492. **Family-specific, not category-generic** — "Detects ransomware" matches everything and nothing. Target identifiable mutexes, PDB paths, C2 paths, or structural markers for one family or campaign.503. **Goodware before production** — Validate against ecosystem-appropriate clean corpus (VT goodware for PE; top npm packages for JS; marketplace extensions for CRX).514. **Short-circuit cheap checks first** — `filesize` → magic bytes → strings → modules.525. **Metadata is documentation** — Name, description, author, reference, and date survive personnel changes.5354## Essential toolkit5556| Tool | Purpose |57|---|---|58| **yarGen** | Candidate strings from samples (`--excludegood`); always `yr check` output |59| **FLOSS** | Obfuscated/stack strings when yarGen fails |60| **yr** | `yr check`, `yr scan -s`, `yr fmt`, `yr dump -m pe\|crx\|dex` |61| **YARA-CI / VT retrohunt** | Goodware corpus testing before deploy |6263## Core workflows6465### 1. Scope samples and file type66671. Collect **3+ variants** when possible (single-sample rules are brittle)682. Check packing: entropy > 7.0 or few strings → unpack or target packer/structure, not encrypted layer693. Choose platform path: PE magic / JS / Office ZIP / `import "crx"` / `import "dex"`7071**See `references/yara_x_scope_and_tooling.md` for install, CLI workflow, and migration.**7273### 2. Extract and filter strings74751. Run yarGen or FLOSS on unpacked samples762. Reject ~80% of yarGen output: API names, `C:\Windows\`, format strings, `require`/`fetch` alone773. Prefer gold tier: mutex names, PDB paths, stack strings; silver: C2 paths, config markers7879**See `references/string_selection_and_atoms.md` for decision trees and modifiers.**8081### 3. Write rule with ordered conditions8283```yara84rule MAL_Win_Example_Loader_Jan2685{86 meta:87 description = "Detects Example loader via unique mutex and config path"88 author = "Team <team@example.com>"89 reference = "https://example.com/analysis"90 date = "2026-01-15"9192 strings:93 $mutex = "Global\\ExampleMutex" ascii wide94 $cfg = "/api/beacon/check" ascii9596 condition:97 filesize < 10MB and98 uint16(0) == 0x5A4D and99 all of ($mutex, $cfg)100}101```102103**Condition order:** `filesize` → magic bytes → string matches → module calls (`pe`, `crx`, `dex`).104105**See `references/conditions_and_performance.md` for atom theory, regex bounds, and loops.**106107### 4. Validate and test108109```bash110yr check rule.yar && yr fmt -w rule.yar111yr scan -s rule.yar malware_samples/ # must match all targets112yr scan -c rule.yar goodware_corpus/ # must be zero113```114115**FP flow:** `yr scan -s` on false positive → identify matching string → tighten, exclude vendor, or pivot to structure.116117**See `references/testing_goodware_and_fp_debugging.md` for corpus selection and investigation.**118119### 5. Platform modules (when applicable)120121- **Chrome extensions:** `import "crx"` — permissions, `permhash()` (v1.11.0+). Always `crx.is_crx` first.122- **Android:** `import "dex"` — `dex.contains_class()`, `contains_method()`, `contains_string()`. API differs from legacy YARA dex module.123124**See `references/platform_modules_pe_crx_dex.md`.**125126### 6. Deploy1271281. Naming: `{CATEGORY}_{PLATFORM}_{FAMILY}_{VARIANT}_{DATE}` (e.g. `MAL_Win_Emotet_Loader_Jan26`)1292. Peer review + quality checklist1303. Monitor production FPs; version rules in Git with full metadata131132**See `references/style_metadata_and_deployment.md`.**133134## Decision trees (quick reference)135136### Is this string good enough?137138```139< 4 bytes? → reject140Repeated bytes (0000, 9090)? → reject141API name or common path? → reject142Unique to family? → use143Common across malware? → combine with family-specific marker144```145146### `any of` vs `all of`147148- Individually unique strings → `any of ($a*)`149- Common strings that are suspicious only together → `all of ($a*)`150- Mixed confidence → `all of ($core_*) and any of ($variant_*)`151152Production lesson: `any of ($network_*)` with `fetch`, `axios`, `http` matches most web apps — require credential path **and** exfil destination **and** network call.153154### When strings fail → pivot155156Use `yr dump -m pe` for sections, imports, imphash, resources; `math.entropy()` on sections; packer signatures. If nothing unique remains, YARA alone may not be the right control.157158## Legacy YARA migration159160```bash161yr check --relaxed-re-syntax rules/ # diagnostic only162yr check rules/ # fix until clean163```164165Common fixes: escape `\{` in regex; base64 strings need 3+ chars; `@a[-1]` → `@a[#a - 1]`; remove duplicate modifiers.166167## Rationalizations to reject168169| Thought | Reality |170|---|---|171| "yarGen gave me these strings" | yarGen suggests; you validate each string |172| "It works on 10 samples" | Test goodware corpus before deploy |173| "I'll tighten after FPs" | FPs burn trust — write tight rules upfront |174| "This API name is malicious" | Legitimate software uses the same APIs |175| "any of them is fine" | Common strings + `any` = FP flood |176177## Quality checklist178179- [ ] Name follows `{CATEGORY}_{PLATFORM}_{FAMILY}_{VARIANT}_{DATE}`180- [ ] Description starts with "Detects" and states distinguishing feature181- [ ] Required meta: author, reference, date182- [ ] Strings ≥4 bytes with good atoms; no unbounded regex (`.*`)183- [ ] Condition: `filesize` and magic bytes before modules184- [ ] Matches all target samples; **zero** goodware matches185- [ ] `yr check` and `yr fmt --check` pass186- [ ] Peer review completed187188## When to load references189190| Topic | Reference |191|---|---|192| YARA-X install, CLI, migration, toolkit | `references/yara_x_scope_and_tooling.md` |193| String quality, types, modifiers | `references/string_selection_and_atoms.md` |194| Atoms, condition order, regex, loops | `references/conditions_and_performance.md` |195| PE, macOS, JS, crx, dex patterns | `references/platform_modules_pe_crx_dex.md` |196| Goodware testing, FP debugging | `references/testing_goodware_and_fp_debugging.md` |197| Naming, metadata, deployment | `references/style_metadata_and_deployment.md` |