Lab 04 — Static Analysis — Capabilities¶
Hands-on lab · ← Back to the module concept
Setup¶
git clone https://github.com/plaintext-security/plaintext-labs
cd plaintext-labs/malware/04-static-capabilities
make up
make fetch-sample # pulls a real Agent Tesla sample from MalwareBazaar into the isolated container
make demo
⚠ This lab analyzes a live malware sample. Handle it accordingly. - Static only. This module never executes the sample —
capareads capabilities from the binary statically, andyaramatches on strings/imports. Do not run it. - Isolation. All work stays inside the isolated container; never copy the sample to your host. - Hygiene. The sample is fetched at lab time (password-protected zip, passwordinfected) and is never committed —.gitignorecoverssamples/.make fetch-sampleneeds a free abuse.ch Auth-Key (setMB_AUTH_KEY). - Offline fallback. No key / MalwareBazaar unreachable? Skipmake fetch-sample;make demofalls back to the bundled syntheticloader.exe, andutil.dllstays the benign control.
Scenario¶
This is the same Agent Tesla sample you dissected in Module 03 — now you raise the level of abstraction. Module 03 gave you the raw IAT and strings; here you ask what does this binary actually do? capa (Mandiant's capability-detection tool) reads the PE statically and labels behaviours — keylogging, credential access, persistence, anti-analysis — and maps them to MITRE ATT&CK and MBC. Agent Tesla (MITRE S0331) is a .NET keylogger/infostealer that hooks the keyboard, harvests stored browser and mail credentials, and exfiltrates over SMTP/FTP/HTTP — the behaviour FortiGuard dissects in the module's Learn path. Your job: produce a capa capability report for the case ticket, then author a YARA rule keyed on what this real sample actually exposes — its imports, mutex, and distinctive strings — and prove it fires on the sample but stays quiet on a benign control.
Throughout, the sample = the real Agent Tesla PE that
make fetch-sampledrops insamples/(path printed by the target). In offline mode it is the bundled syntheticloader.exe;util.dll(or/bin/ls) remains the benign no-match control.
Do¶
-
[ ] Run
capaagainst the sample. Runcapa /lab/samples/<hash>(ormake demofor the synthetic fallback). Read every capability it reports. For each ATT&CK technique ID in the output, look it up on attack.mitre.org and read the description. Which of Agent Tesla's documented behaviours — keylogging, credential access, persistence, anti-analysis — does capa surface? -
[ ] Cross-check capa against your Module 03 IAT. Are there capabilities you expected from the Module 03 import analysis that capa did not flag? Are there capabilities capa flagged that the raw IAT did not obviously reveal? Explain why an import might not generate a capa match, and why capa can label a behaviour the import list alone wouldn't (Hint: capa rules combine multiple features; .NET/managed code and indirect resolution complicate static coverage).
-
[ ] Run the provided YARA rule and read it. Run
yara /lab/data/rules/suspicious-capabilities.yar /lab/data/samples/loader.exeagainst the synthetic fallback. Understand each condition and why it was written, then note: these rules key on the synthetic sample's strings — they will not match the real Agent Tesla PE. That gap is the point of the next step. -
[ ] Author your own YARA rule from the real sample (the build half). Reading capabilities is only half the job — now turn the highest-signal findings into a detection keyed on what this Agent Tesla sample actually exposes. From Module 03 / your capa run, pick: (a) a suspicious-API combination (the import names as strings — e.g. the keylogging pair
SetWindowsHookEx/GetAsyncKeyState, or credential/registry APIs), plus (b) one distinctive string the sample carries (a mutex, a credential-store path, an SMTP host/port, or a config URL), gated onpe.is_pe. Write it toagent-tesla-caps.yar. Then prove the two-sided result: it must match the real sample and must not match the benign control (util.dll, or a known-good binary like/bin/ls). A rule that fires on the benign control is keyed on the wrong thing — narrow it until only the real sample matches. (In offline mode, key your rule on the syntheticloader.exestrings instead and prove the same two-sided result againstutil.dll.) (Hint:yara /path/to/rule /path/to/file; use thepemodule for the PE check and require all chosen strings in the condition so a single shared import can't trigger it.) -
[ ] Interpret the ATT&CK mapping. In
capabilities-report.md, list each capa-detected capability with: ATT&CK ID, technique name, and a one-sentence explanation of what part of the binary implements it. Tie the keylogging / credential-access / exfiltration matches back to Agent Tesla's documented behaviour (S0331, FortiGuard). If capa detected little or nothing (e.g. a packed or heavily obfuscated .NET sample), explain that and state what you would do next.
Success criteria — you're done when¶
- [ ] capa output is captured and all ATT&CK IDs are looked up and annotated.
- [ ]
agent-tesla-caps.yarmatches the real sample (or syntheticloader.exeoffline) and does not matchutil.dll(or/bin/ls) — the build half, proven two-sided. - [ ]
capabilities-report.mdexists with a complete ATT&CK mapping table tied to Agent Tesla's documented behaviour. - [ ] Capability gap analysis is written (minimum two sentences).
Deliverables¶
agent-tesla-caps.yar (with the match/no-match proof recorded in the report), capabilities-report.md, and cap_report.py (see Automate & own it). Commit all three. The sample itself, and any raw capa JSON dumps, stay out of commits.
Automate & own it¶
Required. cap_report.py is provided as a starting point in data/: it runs capa --json <file> (via subprocess), parses the JSON, and outputs a Markdown table of ATT&CK ID, technique name, confidence, and capa rule namespace. Extend it to also fold in MBC behaviours and to add a one-line "summary" per row that you write yourself by hand from the ATT&CK lookup — AI can draft the JSON parsing; you own the technique names so you read each one. The script must exit 0 and produce valid Markdown.
AI acceleration¶
Paste your capa JSON output into an AI and ask it to explain each capability in one sentence for a non-technical executive audience. Then review each sentence for technical accuracy — AI frequently understates or misstates what process injection or credential access actually means. Correct the errors; this forces you to own the interpretation.
Connects forward¶
The YARA rule you write here is the detection deliverable for Module 04. In a real SOC it would be deployed to EDR, SIEM, or a file-scanning pipeline. The ATT&CK technique IDs map directly to the detections in Track 02 (Defensive Operations). In Module 07 you will correlate these capabilities with the actual disassembly to see where each behaviour is implemented.
Marketable proof¶
"I run capa against unknown binaries, interpret the MITRE ATT&CK capability output, and write YARA rules that translate forensic findings into deployed detections."
Stretch¶
- Add a second YARA rule using byte patterns (
{ 4D 5A ?? ?? }for the MZ header plus a specific string sequence) and record what it matches across the samples from Module 02. - Run
capaagainstutil.dlland compare the capability output to the real sample. Why does the DLL produce so little even though both are PE files?
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).