# Writing Yara Rules

> Author durable YARA detection rules — meta/strings/condition anatomy, string types and modifiers, structural conditions with file magic and offsets, the PE/ELF/math/hash modules, specificity-vs-durability tuning, atom-aware performance, memory and process scanning, and YARA-X. Use when writing a YARA rule, creating a signature for a malware family or a file/memory artifact, turning IOCs or a capt…

- **Type:** Skill
- **Install:** `agentstack add skill-evilfreelancer-secs-writing-yara-rules`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [EvilFreelancer](https://agentstack.voostack.com/s/evilfreelancer)
- **Installs:** 0
- **Category:** [AI & ML](https://agentstack.voostack.com/c/ai-and-ml)
- **Latest version:** 0.1.0
- **License:** Apache-2.0
- **Upstream author:** [EvilFreelancer](https://github.com/EvilFreelancer)
- **Source:** https://github.com/EvilFreelancer/secs/tree/main/.agents/skills/writing-yara-rules

## Install

```sh
agentstack add skill-evilfreelancer-secs-writing-yara-rules
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Writing YARA Rules

A good YARA rule matches the malware's *nature* — its code, its structure, its
unavoidable constants — not its *costume*, which is a filename or a mutable
string that changes on the next build. Match the nature and the rule survives
recompilation and catches the whole family; match the costume and you catch one
sample once. The entire craft is choosing strings and a condition that are both
specific enough to avoid false positives and durable enough to generalize.

## When to Use

- Writing a YARA rule to detect a malware family, tool, or capability
- Creating a signature for a file or in-memory artifact from a known sample
- Turning IOCs or a captured specimen into a portable, testable detection
- Hunting for a family across a corpus (VirusTotal Retrohunt, LOKI/THOR, on-host scan)
- Clustering related samples by shared code, constants, or structure
- Reviewing or tuning an existing rule for false positives and scan performance

## When NOT to Use

- **The detection belongs in log or SIEM telemetry, not on files or memory** —
  use `writing-sigma-rules`
- **Choosing what to detect and where it should live, the strategy above rule
  syntax** — use `engineering-detections`
- **You do not yet understand the sample well enough to pick durable anchors** —
  use `analyzing-malware` first
- **Running the hunt rather than authoring the signature** — use `hunting-threats`
- **Packaging IOCs, attribution, and a finished report** — use
  `producing-threat-intelligence`

## Rule Anatomy

Three sections: `meta` (documentation, never matched on), `strings` (the
patterns), `condition` (the boolean that decides a hit).

```yara
import "pe"

rule Family_Loader_v1
{
    meta:
        author      = "analyst"
        date        = "2026-07-26"
        description = "ExampleLoader stage-1, config-decode stub + family constants"
        hash        = "a1b2c3..."
        reference   = "https://internal/case/1234"
        version     = "1"
        tlp         = "amber"
    strings:
        $decode = { 8A 04 0? 32 0? 88 0? 4? 3B ?? 72 }
        $marker = "cfg::begin" ascii
        $mutex  = "Global\\ExL-%08x" ascii
    condition:
        uint16(0) == 0x5A4D and filesize = 3 and                     // the $beacon string appears 3+ times

    // Bound the search — a 40-byte dropper is not a 50 MB installer
    filesize " and       // API import fingerprint
        pe.number_of_sections == 5 and
        pe.imports("wininet.dll", "InternetOpenA") and
        pe.exports("PluginInit") and
        for any s in pe.sections : ( s.name == ".xdata" and s.raw_data_size == 0 ) and
        pe.rich_signature.length > 0 and                 // Rich header (compiler fingerprint)
        pe.timestamp > 1577836800
}
```

`imphash` clusters samples built from the same import table; the Rich header
fingerprints the build toolchain and is hard to forge; `pe.imports`/`pe.exports`
anchor on capability rather than incidental bytes.

**ELF** mirrors PE for Linux (`elf.number_of_sections`, `elf.type`,
`elf.symtab`). **math** scores regions — flag packed or encrypted blobs:

```yara
import "math"
rule Packed_HighEntropy {
    condition:
        uint16(0) == 0x5A4D and
        math.entropy(0x1000, filesize - 0x1000) >= 7.2 and   // near-random tail
        math.mean(0, filesize) > 100
}
```

**hash** computes digests inside the condition — useful to pin a specific
embedded resource, not the whole file (a whole-file hash needs no YARA):

```yara
import "hash"
rule EmbeddedResource {
    condition:
        hash.sha256(0x400, 0x200) == "e3b0c4..."
}
```

## Targeting Position-Independent Things

Anchor on what moves with the code, not with the campaign. In rough order of
durability: crypto constants (S-boxes, MD5/SHA init values, custom key
schedules) → the family's own mutex/pipe/registry name templates → config
markers and delimiters → C2 URI templates (`/gate/`, `/panel/upload.php`) →
unique error and debug strings the developer left in → stack strings once you
have deobfuscated them with `floss`. A filename, a compile timestamp, a
campaign C2 IP, and a single common Win32 API name are *not* durable — they are
the costume.

## Killing False Positives

A rule is not done when it hits the sample; it is done when it does not hit
goodware. Three levers, applied together:

- **Quorum** — require `N of M` strings, never a lone common one. Any single
  string can appear in benign software; three family constants together will not.
- **File-type anchor** — lead the condition with `uint16(0) == 0x5A4D` or the
  ELF magic so the rule never even scans an unrelated file type.
- **Size bound** — `filesize "      # scheme in the path is optional
```

This strips page boilerplate — roughly 78% fewer tokens on a prose page — and
returns the full text rather than a summary, so you can grep it and trust a
negative result.

Three things it is not for. Fetch JSON and API responses raw, because
readability extraction mangles structured data. Fetch authenticated or
JavaScript-rendered pages directly, because it retrieves them anonymously. And
never route **adversary infrastructure** (phishing links, C2, malware hosting),
**client-owned hosts**, or **engagement URLs** through it — the request leaves
your machine to a third party, and for live adversary infrastructure it also
tips off the operator.

Some sites block the extractor and return an error blob rather than the page —
`{"error":"Failed to fetch: 418 I'm a teapot"}` from freedesktop.org, for
instance. That is the fetch being refused, **not** the source saying the thing
does not exist. Re-fetch the URL directly before drawing any conclusion from
it.

## References

- `writing-sigma-rules` — the same craft for log and SIEM telemetry
- `engineering-detections` — choosing what to detect and where it belongs
- `analyzing-malware` — understanding the sample that a durable rule is built from
- `hunting-threats` — running the hunt these signatures drive
- `producing-threat-intelligence` — packaging IOCs, attribution, and reporting
- `reporting-security-findings` — writing up what the detection found
- YARA (VirusTotal) and YARA-X — the engines and their documentation
- yarGen — auto-generate candidate rules and strings from samples (a starting
  point, never a finished rule)
- yara-validator / `yr fmt` — lint and normalize rules in CI
- LOKI and THOR (Nextron) — IOC and YARA scanners for on-host hunting
- VirusTotal Retrohunt — run a rule across VT's corpus to find related samples

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [EvilFreelancer](https://github.com/EvilFreelancer)
- **Source:** [EvilFreelancer/secs](https://github.com/EvilFreelancer/secs)
- **License:** Apache-2.0

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** yes
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-evilfreelancer-secs-writing-yara-rules
- Seller: https://agentstack.voostack.com/s/evilfreelancer
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
