Skip to content

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 — capa reads capabilities from the binary statically, and yara matches 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, password infected) and is never committed.gitignore covers samples/. make fetch-sample needs a free abuse.ch Auth-Key (set MB_AUTH_KEY). - Offline fallback. No key / MalwareBazaar unreachable? Skip make fetch-sample; make demo falls back to the bundled synthetic loader.exe, and util.dll stays 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-sample drops in samples/ (path printed by the target). In offline mode it is the bundled synthetic loader.exe; util.dll (or /bin/ls) remains the benign no-match control.

Do

  1. [ ] Run capa against the sample. Run capa /lab/samples/<hash> (or make demo for 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?

  2. [ ] 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).

  3. [ ] Run the provided YARA rule and read it. Run yara /lab/data/rules/suspicious-capabilities.yar /lab/data/samples/loader.exe against 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.

  4. [ ] 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 on pe.is_pe. Write it to agent-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 synthetic loader.exe strings instead and prove the same two-sided result against util.dll.) (Hint: yara /path/to/rule /path/to/file; use the pe module for the PE check and require all chosen strings in the condition so a single shared import can't trigger it.)

  5. [ ] 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.yar matches the real sample (or synthetic loader.exe offline) and does not match util.dll (or /bin/ls) — the build half, proven two-sided.
  • [ ] capabilities-report.md exists 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 capa against util.dll and 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).