# 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.

- Skill: `trilwu/analyzing-malware` (Agent Skill)
- Install (CLI): `npx skillmds add trilwu/analyzing-malware`
- Raw SKILL.md: https://api.skillmd.com/api/skills/trilwu/analyzing-malware/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: trilwu (https://skillmd.com/u/trilwu)
- Updated: 2026-09-10
- Page: https://skillmd.com/skills/trilwu/analyzing-malware

---


# 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

