AI agent skill · by @trilwu
Analyzing Malware
Analyze suspected malware safely — containment, static triage, sandboxed detonation, unpacking, capability and C2 extraction, IOC production, and YARA rule authoring. Use when handed a suspicious file, hash, or sample, when triaging an alert artifact, or when producing detection content from a specimen.
Archived 2026-10-23 · Source updated 2026-09-04 · License: MIT. Check the original repository for the latest version.
SKILL.md instructions
# Analyzing Malware
The analysis is the easy part. The part that goes wrong is containment: a
sample detonated on a machine that can reach production, or an IOC published
that burns an active investigation. Get the environment right first.
## When to Use
- Triaging a suspicious file, attachment, script, or dropped binary
- Determining a sample's capability, persistence, and command-and-control
- Extracting indicators for hunting and blocking
- Writing YARA or behavioural detection from a specimen
- Supporting an incident with sample-derived intelligence
## When NOT to Use
- **Writing malware, droppers, loaders, or evasion code** — out of scope for
this skill regardless of framing
- **Pure RE of a benign binary** — use `analyzing-binaries`
- **A raw shellcode blob with no PE/ELF header** — use `analyzing-shellcode`
- **The sample's network capture** — use `analyzing-network-traffic`
- **Sweeping a whole web source tree for planted webshells** (not one recovered
sample) — use `hunting-web-backdoors`
- **Writing a YARA signature for the family** — use `writing-yara-rules`
- **The wider incident** — use `responding-to-incidents`
- **Turning findings into deployed rules** — use `engineering-detections`
- **Pivoting sample IOCs into related infrastructure, actor tracking, or a
finished intel product** — use `producing-threat-intelligence`
## Containment: Do This Before Anything Else
| Control | Requirement |
| --- | --- |
| Host | Disposable VM or dedicated bare-metal, snapshot taken before execution |
| Network | Isolated segment; simulated services (INetSim/FakeNet-NG) by default |
| Shares | No host folder sharing, no clipboard sharing, no mounted host drives |
| Credentials | No real accounts, no domain join, no password manager |
| Handling | Sample stored in a password-protected archive, extension neutered (`.bin`, `.mal`) |
| Egress | Real internet only with an explicit decision and a plan for attribution leakage |
Live C2 contact tells the operator you are looking. On an active incident, do
not resolve the C2 domain, submit the hash publicly, or upload the sample to a
multi-scanner service until the incident lead approves it — public submission
is a disclosure.
## Static Triage — No Execution
```bash
# Identity, always first
sha256sum sample && file sample && du -h sample
# Fuzzy and import hashes for clustering against known families
ssdeep sample; tlsh sample # Debian tlsh-tools ships /usr/bin/tlsh;
# built from upstream it is tlsh_unittest
python3 -c "import pefile;print(pefile.PE('sample').get_imphash())"
# Structure
pecheck sample # or: rabin2 -I / readelf -h
capa -v sample # capability detection mapped to ATT&CK — start here
floss sample # deobfuscated + stack strings, better than `strings`
# Packing and embedded content
binwalk -E sample # entropy
binwalk -Me sample # extract embedded objects
```
`capa` is the highest-value single command in this workflow: it turns a binary
into a list of behaviours mapped to MITRE ATT&CK and MBC, which tells you
whether deeper analysis is warranted at all.
**Document-borne and script-borne samples:**
```bash
oleid doc.xls && olevba --deobf doc.xls # OLE macros
oledump.py doc.doc # stream-level inspection
msodde doc.docx # DDE payloads
rtfobj doc.rtf # embedded objects in RTF
pdfid file.pdf && pdf-parser -a file.pdf # /JS /OpenAction /Launch
# Obfuscated scripts: normalize before reading
box-js payload.js
# PowerShell: decode -EncodedCommand, then unwrap the layers
echo '<base64>' | base64 -d | iconv -f UTF-16LE -t UTF-8
```
Most script malware is three layers of encoding around ten lines of logic.
Deobfuscate mechanically rather than reading the obfuscated form.
## Dynamic Analysis
Snapshot, detonate, observe, revert. Never analyze twice from a dirty state.
```
Baseline snapshot
→ start Procmon / Sysmon / inotify + tcpdump + INetSim
→ detonate with the right launcher (rundll32, wscript, mshta, Office)
→ observe 3-5 minutes, then interact (click, wait past sleep timers)
→ collect artifacts and memory
→ revert
```
What to collect and what each answers:
| Artifact | Tool | Answers |
| --- | --- | --- |
| Process tree | Sysmon E1, Procmon, `execsnoop` | Injection, LOLBin abuse, child spawns |
| File and registry writes | Procmon, `inotifywait` | Drops, persistence, config |
| Network | `tcpdump`, Wireshark, INetSim logs, mitmproxy | C2 endpoints, beacon interval, protocol |
| Memory | DumpIt / `procdump`, then Volatility | Unpacked payload, injected code, keys |
| Persistence | Autoruns, `systemctl list-units`, cron, LaunchAgents | Survival mechanism |
**Recover the unpacked payload from memory** rather than fighting the packer:
```bash
# After the sample unpacks itself, dump and carve
vol -f mem.raw windows.malfind # injected/RWX regions
vol -f mem.raw windows.dumpfiles --pid <pid>
```
Watch for **sleep and evasion gates**: many samples idle for minutes, check for
a domain-joined host, count CPU cores, or look for analysis processes. If
nothing happens, patch the check or hook `Sleep`/`NtDelayExecution` with Frida
before concluding the sample is inert.
## Capability Model
Structure findings against ATT&CK rather than as a narrative:
- **Initial execution** — how it was launched, what it needed
- **Defense evasion** — packing, injection, AMSI/ETW patching, signed-binary proxying
- **Persistence** — run keys, services, scheduled tasks, WMI subscriptions, cron, LaunchAgents
- **Credential access** — LSASS access, browser stores, keylogging
- **Discovery** — host, domain, and security-product enumeration
- **Collection and exfiltration** — what is staged, where, and how it leaves
- **Command and control** — protocol, encoding, jitter, fallback channels, kill date
- **Impact** — encryption, wiping, resource hijacking
For each, record the concrete evidence (address, API call, artifact) that
supports the claim. A capability asserted without evidence is a guess, and
guesses in a malware report drive bad response decisions.
## Configuration and C2 Extraction
The config is the most valuable output — it feeds blocking, hunting, and
attribution.
```bash
# Known families: use the community extractors first
python3 -m maco.extract sample # MACO / CAPE / RATDecoders ecosystems
# Unknown: find the decode routine, then emulate it over the encrypted blob
```
Typical config contents: C2 URLs and fallbacks, campaign or botnet ID, RC4/AES
key, mutex, sleep interval and jitter, install path, kill date. Extract all of
them — campaign IDs and mutexes are often better hunting pivots than the C2,
which rotates.
## IOC and Detection Output
Rank indicators by how long they survive and how specific they are:
```
Hash → precise, dies immediately (recompile)
C2 IP/domain → useful now, rotates in days
Mutex / config → survives rotation, family-specific
Behaviour/TTP → survives redevelopment; write these
```
Write YARA against structure and code, not incidental strings:
```yara
rule Family_Loader_ConfigDecode
{
meta:
author = "analyst"
date = "2026-07-26"
description = "Loader config RC4 decode stub"
hash = "<sha256>"
reference = "<internal case id>"
strings:
// The decode loop's constants, not a filename it happens to drop
$decode = { 8A 04 0? 32 0? 88 0? 4? 3B ?? 72 }
$mutex = "Global\\<family-specific>" ascii
condition:
uint16(0) == 0x5A4D and filesize < 2MB and all of them
}
```
Validate every rule before it ships:
```bash
yara -w rule.yar ./samples/family/ # must hit all known-true samples
yara -w rule.yar ./corpus/goodware/ # must produce zero hits — this step is not optional
```
Hand behavioural detections to `engineering-detections` for Sigma/EDR
conversion and tuning.
## Rationalizations to Reject
- *"It's just a script, I'll run it on my laptop."* Script malware is malware.
- *"The sandbox said it's clean."* Sandboxes are evaded by design. A clean
verdict with a suspicious file is a reason to analyze harder, not to close.
- *"I'll upload it to VirusTotal to check quickly."* Public submission is
disclosure to the adversary and possibly to your customer's competitors.
Decide deliberately.
- *"The hash is the IOC."* The hash blocks exactly this build.
- *"AV named it Family X, so it is Family X."* Vendor names are inconsistent.
Confirm with code or config similarity before you inherit that family's
attribution and playbook.
- *"No network traffic, so no C2."* Check for sleep gates, DGA seeds waiting
on a date, and dead-drop resolvers before concluding.
## Deliverable
- **Identity** — filename(s), SHA-256, imphash, ssdeep, size, type, signer
- **Verdict and confidence** — malicious/suspicious/benign, with reasoning
- **Family and campaign** — with the evidence that supports the attribution
- **Capability** — ATT&CK-mapped, each item evidenced
- **IOCs** — tiered as above, with a stated confidence per indicator
- **Detection** — YARA, Sigma, and network signatures, with FP-test results
- **Recommended actions** — containment, blocking, hunting queries
<!-- attack:start -->
## ATT&CK Coverage
_Generated from `secskills-core/ttp-index.json` — edit that file, then run
`python3 scripts/sync_attack.py --write`. Re-verify IDs against the
current ATT&CK release before citing them in a report._
**Resource Development** (TA0042)
- [T1588](https://attack.mitre.org/techniques/T1588/) Obtain Capabilities
**Initial Access** (TA0001)
- [T1566.001](https://attack.mitre.org/techniques/T1566/001/) Spearphishing Attachment — see also `performing-social-engineering`, `analyzing-phishing-emails`
**Execution** (TA0002)
- [T1059.001](https://attack.mitre.org/techniques/T1059/001/) PowerShell — see also `escalating-windows-privileges`
- [T1203](https://attack.mitre.org/techniques/T1203/) Exploitation for Client Execution — see also `performing-social-engineering`, `exploiting-memory-corruption`
**Privilege Escalation** (TA0004)
- [T1055](https://attack.mitre.org/techniques/T1055/) Process Injection _(also Defense Evasion)_ — see also `escalating-windows-privileges`
**Defense Evasion** (TA0005)
- [T1027](https://attack.mitre.org/techniques/T1027/) Obfuscated Files or Information — see also `analyzing-binaries`, `analyzing-shellcode`
- [T1027.002](https://attack.mitre.org/techniques/T1027/002/) Software Packing — see also `analyzing-binaries`
- [T1140](https://attack.mitre.org/techniques/T1140/) Deobfuscate/Decode Files or Information — see also `analyzing-binaries`, `analyzing-shellcode`
- [T1218.011](https://attack.mitre.org/techniques/T1218/011/) Rundll32 — see also `hunting-threats`
- [T1497](https://attack.mitre.org/techniques/T1497/) Virtualization/Sandbox Evasion — see also `analyzing-binaries`
- [T1553](https://attack.mitre.org/techniques/T1553/) Subvert Trust Controls — see also `auditing-supply-chain`
- [T1620](https://attack.mitre.org/techniques/T1620/) Reflective Code Loading — see also `analyzing-shellcode`
- [T1622](https://attack.mitre.org/techniques/T1622/) Debugger Evasion — see also `analyzing-binaries`
**Collection** (TA0009)
- [T1056.001](https://attack.mitre.org/techniques/T1056/001/) Keylogging _(also Credential Access)_
**Command and Control** (TA0011)
- [T1071](https://attack.mitre.org/techniques/T1071/) Application Layer Protocol — see also `engineering-detections`, `analyzing-network-traffic`
- [T1132](https://attack.mitre.org/techniques/T1132/) Data Encoding — see also `transferring-files`, `analyzing-network-traffic`
- [T1568](https://attack.mitre.org/techniques/T1568/) Dynamic Resolution — see also `hunting-threats`, `analyzing-network-traffic`
- [T1573](https://attack.mitre.org/techniques/T1573/) Encrypted Channel — see also `engineering-detections`, `analyzing-network-traffic`
**Impact** (TA0040)
- [T1486](https://attack.mitre.org/techniques/T1486/) Data Encrypted for Impact — see also `responding-to-incidents`
Detection content for any of these: `engineering-detections`. Proactive search: `hunting-threats`. Post-compromise: `responding-to-incidents`.
<!-- attack:end -->
## Reading External Sources
Fetch public advisories, specifications, and vendor reports as Markdown:
```bash
curl -sL "https://defuddle.md/<url>" # 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
- `analyzing-binaries` — disassembly, unpacking, and anti-analysis detail
- `responding-to-incidents` — scoping and eradication around the sample
- `engineering-detections` — turning capability into deployed rules
- MITRE ATT&CK and MBC (Malware Behavior Catalog) for classification
- `capa`, `floss`, `oletools`, `Volatility 3`, `YARA` as the core toolchain