# Malware Triage

> Malware triage workflow — sandbox output analysis (CAPE/Hybrid-Analysis/ANY.RUN/Joe Sandbox), YARA rule scaffolding at pattern level, IOC extraction, and TTP mapping to MITRE ATT&CK. Sandbox-only discipline; do not detonate in production or without an isolated runtime.

- Skill: `roodlicht/malware-triage` (Agent Skill)
- Install (CLI): `npx skillmds@latest add roodlicht/malware-triage`
- Raw SKILL.md: https://api.skillmd.com/api/skills/roodlicht/malware-triage/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Productivity
- Author: roodlicht (https://skillmd.com/u/roodlicht)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/roodlicht/malware-triage

---


# Malware Triage

> **Sandbox-only discipline**: analysing a sample means running it in an isolated environment. Detonating in production or on a workstation with network egress creates an incident instead of solving one. Treat all samples as worm-class — that discipline costs less than a production outbreak. Detailed reverse engineering (debugger-attached, IDA Pro / Ghidra interactive) is out of scope here — that is a further specialization. The skill covers sandbox-driven triage and YARA scaffolding at signal-pattern level.

## When to use

A suspicious file or process lands on your SOC desk. Before you can say "clean" or "incident", you need a structured triage. This skill provides the structure.

Triggers on:

- A question like "what does this sample do", "write a YARA rule for this family", "ATT&CK mapping from this sandbox output", "is this the same malware family as last month".
- A handoff from `ioc-hunter` (sample known, IOCs needed), `log-triage` (suspect-execution event in EDR), `forensics-assist` (memory-extracted binary), `ir-runbook` (sample is part of an incident).
- Bug-bounty or bug disclosure where a sample is provided.
- A periodic review of EDR quarantine.

### When NOT (handoff)

- Deep reverse engineering with disassembler/debugger → out of scope. Requires specialized reverse work.
- Detection-rule building on IOCs or TTPs → `detection-engineer` (Sigma/SPL/KQL).
- IOC feed curation and sharing → `ioc-hunter`.
- Forensic evidence-grade analysis for court → `forensics-assist` plus a specialized forensics team.
- Active response after a confirmed incident → `ir-runbook`.
- Production detonation → don't. Lab/sandbox only.
- Attacker-tooling replication or tuning → out of scope.

## Approach

Six phases. Phase 1 (intake discipline) and phase 4 (YARA scaffolding) are where triage work becomes durable.

### 1. Intake and sandbox choice

- **Sample acquisition**: file comes from EDR quarantine, an email attachment, a USB find, or a public repo. Ensure secure transfer to the lab (encrypted, password-protected ZIP outside production paths).
- **Hash-first check**: compute SHA-256, look up against VirusTotal / Hybrid-Analysis / abuse.ch MalwareBazaar / internal history. Known? Then triage can be sped up by reading existing analysis.
- **Sandbox choice**:
  - **CAPE Sandbox** (open-source, on-prem) — Cuckoo fork with config extraction. Default for on-prem-only policy.
  - **ANY.RUN** (commercial, cloud) — interactive sandbox with manual progression. Good for user-interaction-required malware.
  - **Joe Sandbox** (commercial) — deep, multi-OS.
  - **Hybrid-Analysis** (Falcon Sandbox, free for research) — solid free tier.
  - **VirusTotal** — not just hash lookup; runs a sandbox if a sample is uploaded. Beware: upload is public; do not use for confidential samples.
- **Live versus static first pass**: before you run dynamic, gather static info — file type, headers, embedded strings, packer fingerprints (`pestudio`, `die`, `floss` for obfuscated strings, `binwalk` for archives).

Discipline: confidential samples (potential PII, potential IP leak) go to an on-prem sandbox or a paid private tier, not public VirusTotal.

### 2. Static-analysis pass

Before dynamic execution:

- **File type and metadata**: PE/ELF/Mach-O/script (PowerShell/JS/macro), compiler info, signing status.
- **String extraction** (`strings`, `floss` for stack-encoded). Hosts, URLs, file paths, mutex names, registry keys.
- **Sections / imports / exports**: unusual imports (CryptAcquireContext + InternetOpen + WriteFile is a frequent ransomware pattern), `.text` section size vs entropy (high entropy = packed).
- **YARA first pass**: known rules from community repositories (`Yara-Rules`, `Neo23x0/signature-base`, `Elastic/protections-artifacts`) against the sample. A known-family match speeds up the rest.
- **Code-signing check**: signed but unknown publisher is a red flag (stolen or dropped cert). Verify the cert chain.

### 3. Dynamic analysis via sandbox

Sandbox runs in an isolated VM with instrumented process events.

- **Process-tree observation**: parent → child → grandchild. Classic suspect: `winword.exe → cmd.exe → powershell.exe → certutil.exe`.
- **Network egress**: DNS queries (resolved and unresolved), HTTP requests, TLS fingerprints (JA3/JA4), C2 hosts. Match against `ioc-hunter` feeds.
- **Filesystem changes**: writes to Startup folders, schedule folders, AppData paths.
- **Registry changes**: Run keys, services, COM hijacks, BITS jobs.
- **API calls**: WriteProcessMemory + CreateRemoteThread (process injection T1055), CryptEncrypt burst (ransomware), VirtualProtect (shellcode runtime).
- **Persistence-mechanism detection**: scheduled-task creation, service installation, registry Run keys.
- **Anti-VM / anti-sandbox**: CPUID checks, mouse-movement checks, sleep-skip detection. The sandbox output usually shows whether detection happened.

For user-interaction malware (banking trojans, info-stealers with UI trigger): manual interaction in an interactive sandbox.

### 4. YARA-rule scaffolding at pattern level

YARA is the standard for malware classification. We write rules at pattern level, not for one specific binary.

```yara
rule SUSPECT_MyFamily_Loader {
  meta:
    author = "<analyst>"
    date = "YYYY-MM-DD"
    description = "Detects MyFamily loader pattern with embedded config string"
    reference = "<sandbox-report-link>"
    hash_seen = "<sha256>"
    tlp = "AMBER"

  strings:
    $config_marker  = "MYCFG_v2:" ascii wide
    $api_resolve_a  = "GetProcAddress" ascii
    $api_resolve_b  = "LoadLibraryA" ascii
    $unique_string  = "MyFamilyLoader/" ascii nocase
    $opcode_pattern = { 8B ?? ?? ?? 89 ?? E8 ?? ?? ?? ?? }

  condition:
    uint16(0) == 0x5A4D and             // PE header
    filesize < 5MB and
    (
      $config_marker or
      ($unique_string and 2 of ($api_resolve_*) and $opcode_pattern)
    )
}
```

**Discipline**:

- `meta.author`, `meta.date`, `meta.tlp`: tracking and sharing policy.
- `meta.hash_seen`: what the rule was conceived against; helps later reviewers.
- **Specific enough to distinguish at family level, not so specific that a second sample from the same family is missed.**
- **Performance-aware**: wildcards in opcodes and heavy regex against all files slow scanners down. Anchor with PE magic, file-size limits, context.
- **Test for false positives**: scan the rule against 1000+ benign binaries before production deployment. `yara` CLI or `Threatray`/`Cylance` test corpora.
- **Sharing**: TLP classification explicit. Open-share community rules to the Yara-Rules repo, sector-share via FI-ISAC NL or MISP events.

### 5. TTP extraction and ATT&CK mapping

Sandboxes give raw events; mapping them to ATT&CK techniques makes them reusable.

Per observation: technique T-ID. Common mappings:

- Embedded macro that downloads PowerShell → T1566.001 (Spearphishing Attachment) + T1059.001 (PowerShell).
- Process hollowing → T1055.012.
- LSASS access → T1003.001.
- Scheduled-task creation → T1053.005.
- Registry Run key → T1547.001.
- Network C2 over HTTPS → T1071.001 + T1573.002.
- DNS-tunneling C2 → T1071.004.
- Tor dropper / I2P → T1090.003 (multi-hop proxy).

**ATT&CK coverage output**: a table with technique T-ID, observation, evidence link (sandbox-report section). Provides input for `detection-engineer` (which detection rules are touched by this family) and `purple-ops` (gap analysis: which we miss).

### 6. Output, sharing, and verification-loop

- **Family classification** (if recognized): name + version (where known), source attribution (which vendor classifies it as such).
- **IOCs extracted**: hashes, IPs/domains/URLs, mutex names, file paths, registry keys. Forward to `ioc-hunter` with a confidence score.
- **YARA rule(s)**: as new or as refinement of existing.
- **TTP mapping**: ATT&CK table.
- **Recommendations** for the blue-team stack: which rules cover this, which are missing.

**Sharing**: keep confidential context internal; for community samples share to MISP / abuse.ch MalwareBazaar / VirusTotal / FI-ISAC.

**Verification-loop**: Layer 1 scope (all observations from the sandbox report carried over, sandbox ran fully?, no anti-sandbox detection bypass skipped?). Layer 2: ATT&CK T-IDs correct, family attribution only when there is a vendor source (no invented attribution), YARA syntax against the current YARA version (4.x), sandbox-feature claims (CAPE config extraction, ANY.RUN interactive) current.

## Output

```
Malware triage report — <sample-id / hash>
SHA-256:        <hash>
File type:      <PE/ELF/Mach-O/script>
Sandbox:        <CAPE/ANY.RUN/Joe/etc> | Run-id: <ref>
First seen:     <date/source>
TLP:            <classification>

Static analysis:
  Compiler:           <ref>
  Packed/obfuscated:  <yes/no, method>
  Strings of interest: <briefly noted, redacted>
  Code-signing:       <signed-by-X / unsigned / suspicious>
  YARA pre-match:     <existing family rules that match>

Dynamic observations:
  Process tree:       <parent → child → ...>
  Filesystem writes:  <persistence paths>
  Registry changes:   <run keys / services>
  Network egress:     <C2 hosts, DNS queries, JA3/JA4>
  API pattern:        <process injection / encryption burst / etc>
  Persistence:        <mechanism>
  Anti-sandbox:       <detected / not>

Family classification:
  Name:               <known family or "unknown variant">
  Variant:            <if derived>
  Attribution:        <vendor source if available>

IOCs (handoff to ioc-hunter):
  Hashes:    <list>
  IPs:       <list>
  Domains:   <list>
  URLs:      <list>
  Mutex:     <list>
  TLP:       <classification>

YARA rule(s):
  <full rule block>

TTP mapping (ATT&CK):
  Tactic | Technique-ID | Observation | Sandbox-evidence-ref

Recommendations:
  Detection (handoff to detection-engineer):  <which rules to write>
  Hunt (handoff to ioc-hunter / threat-hunt): <retro window>
  Cleanup (handoff to ir-runbook):            <if live infection>

Verification-loop: ...
```

## References

- **MITRE ATT&CK** — [https://attack.mitre.org/](https://attack.mitre.org/). Technique mapping.
- **CAPE Sandbox** — [https://github.com/kevoreilly/CAPEv2](https://github.com/kevoreilly/CAPEv2). Open-source dynamic analysis.
- **abuse.ch MalwareBazaar** — [https://bazaar.abuse.ch/](https://bazaar.abuse.ch/). Sample repository, signature database.
- **YARA** — [https://virustotal.github.io/yara/](https://virustotal.github.io/yara/). Pattern-matching framework.
- **Yara-Rules / signature-base (Neo23x0)** — [https://github.com/Neo23x0/signature-base](https://github.com/Neo23x0/signature-base). Community rules.
- **MalAPI.io** — [https://malapi.io/](https://malapi.io/). API-to-technique mapping for static analysis.
- **VirusTotal** — [https://www.virustotal.com/](https://www.virustotal.com/). Public hash lookup and sandbox; mind upload policy for confidential samples.
- **Hybrid-Analysis** — [https://www.hybrid-analysis.com/](https://www.hybrid-analysis.com/). Falcon Sandbox, free tier for research.
- **MITRE TRAM** — [https://github.com/center-for-threat-informed-defense/tram](https://github.com/center-for-threat-informed-defense/tram). NLP tool for TTP extraction from reports.
- **Florian Roth — Yara Style Guide** — [https://github.com/Neo23x0/YARA-Style-Guide](https://github.com/Neo23x0/YARA-Style-Guide). Practical YARA best practices.

## Categories

- blue

