| name | analyzing-malware |
| description | 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. |
| verified | 2026-07-27T00:00:00.000Z |
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-binaries
- 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
sha256sum sample && file sample && du -h sample
ssdeep sample; tlsh sample
python3 -c "import pefile;print(pefile.PE('sample').get_imphash())"
pecheck sample
capa -v sample
floss sample
binwalk -E sample
binwalk -Me sample
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:
oleid doc.xls && olevba --deobf doc.xls
oledump.py doc.doc
msodde doc.docx
rtfobj doc.rtf
pdfid file.pdf && pdf-parser -a file.pdf
box-js payload.js
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:
vol -f mem.raw windows.malfind
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.
python3 -m maco.extract sample
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:
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:
yara -w rule.yar ./samples/family/
yara -w rule.yar ./corpus/goodware/
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
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 Obtain Capabilities
Initial Access (TA0001)
- T1566.001 Spearphishing Attachment — see also
performing-social-engineering, analyzing-phishing-emails
Execution (TA0002)
- T1059.001 PowerShell — see also
escalating-windows-privileges
- T1203 Exploitation for Client Execution — see also
performing-social-engineering, analyzing-binaries
Privilege Escalation (TA0004)
- T1055 Process Injection (also Defense Evasion) — see also
escalating-windows-privileges
Defense Evasion (TA0005)
- T1027 Obfuscated Files or Information — see also
analyzing-binaries
- T1027.002 Software Packing — see also
analyzing-binaries
- T1140 Deobfuscate/Decode Files or Information — see also
analyzing-binaries
- T1218.011 Rundll32 — see also
hunting-threats
- T1497 Virtualization/Sandbox Evasion — see also
analyzing-binaries
- T1553 Subvert Trust Controls — see also
auditing-supply-chain
- T1620 Reflective Code Loading — see also
analyzing-binaries
- T1622 Debugger Evasion — see also
analyzing-binaries
Collection (TA0009)
- T1056.001 Keylogging (also Credential Access)
Command and Control (TA0011)
- T1071 Application Layer Protocol — see also
engineering-detections, analyzing-network-traffic
- T1132 Data Encoding — see also
transferring-files, analyzing-network-traffic
- T1568 Dynamic Resolution — see also
hunting-threats, analyzing-network-traffic
- T1573 Encrypted Channel — see also
engineering-detections, analyzing-network-traffic
Impact (TA0040)
- 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.
Reading External Sources
Fetch public advisories, specifications, and vendor reports as Markdown:
curl -sL "https://defuddle.md/<url>"
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