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:
rule→meta/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).