Skip to content

Cheat sheet — Static Analysis: Capabilities

Companion to Module 04 — Static Analysis — Capabilities · CC BY 4.0 — print it, pin it, share it.

Last reviewed: 2026-07

Only handle live malware in an isolated, disposable analysis VM with no bridged network.

capa — labelled behaviours, not raw APIs

capa sample.exe                        # capabilities mapped to ATT&CK + MBC
capa -v sample.exe                     # verbose: which rules matched
capa -vv sample.exe                    # very verbose: the exact features that fired (audit the logic)
capa -j sample.exe > capa.json         # JSON — feed a report or a diff
capa -t "process injection" sample.exe # filter to rules tagged with a string/technique
  • Output fields to read: ATT&CK technique, MBC objective/behavior, namespace, rule name. capa turns "calls VirtualAllocEx + WriteProcessMemory" into "performs process injection (T1055)" — the language the rest of the team already speaks.
  • Workflow order: capa first (what can it do?), YARA second (does it match a known family?), then strings/imports fill the gaps. None replaces the others.

Reading the "silence" — capa on a packed sample

capa sample.exe                        # near-empty output on a packed binary
# cross-check the Module 02 entropy read:
diec -e sample.exe                     # high .text entropy?
  • Empty capa + high entropy = "packed, unpack/detonate first," not "no capabilities." The silence is a result, not a clean bill of health.

YARA — apply your rules

rule trickbot_injector {
    meta:
        author = "you"
        family = "TrickBot"
        attck  = "T1055"
    strings:
        $s1 = "svchost.exe" wide ascii
        $s2 = "wermgr.exe"  wide ascii
        $x  = { 8B 45 ?? 33 D2 }        // byte pattern, ?? = wildcard nibble
    condition:
        uint16(0) == 0x5A4D and 2 of ($s1, $s2, $x)
}
yara -s rule.yar sample.exe            # -s: show matched strings + offsets
yara -r rule.yar ./corpus/             # -r: recurse a directory
yara rule.yar ./benign/                # true-negative gate — must stay quiet
  • Anatomy: rulemeta / strings / condition. String modifiers: nocase, wide, ascii, fullword.
  • capa applies curated behavioural rules; YARA applies yours — bytes/strings/regex you write from a specific mutex, XOR key, or section name that identifies a family and scales across millions of files.

capa vs YARA — when to reach for each

Need Tool
"What behaviours does this binary implement?" capa
ATT&CK / MBC labels for the report capa
"Does this match a family I've already seen?" YARA
A scalable signature on your own IOC YARA

Gotchas worth remembering

  • capa reasons from static structure only. Dynamic imports via GetProcAddress, runtime-decrypted strings, and packer stubs are invisible to it — a packed binary yields almost no output.
  • Empty capa is a finding, not a pass. Read it together with entropy; silence + high entropy routes the sample to unpacking or dynamic analysis, not to "benign."
  • A YARA rule that compiles and matches nothing is the most common failure. The compiler being happy is not validation — run it against a true positive and a true negative yourself.
  • capa's capabilities are claims from pattern rules; when a verdict hinges on one, confirm it in the disassembler (Module 07) — that's where a capability gets verified or corrected.
  • AI writes a YARA skeleton fast but over-broadens or over-narrows conditions; you own the true-positive / true-negative check, not the model.

Comments

Sign in with GitHub to comment. Choose the type: Feedback (errors or suggestions on this page) · Hints (help for fellow learners — no spoilers) · General (anything else).