Malware Triage skill for Codex
A safe verdict without ever running it. Codex triages a suspicious file without executing it: hash and reputation lookup first, true file-type identification, structure inspection for PE, Office, PDF and scripts with oletools, pefile, capa and floss, then IOC extraction and a confidence-rated verdict. It insists on an isolated environment, keeps samples zipped, and escalates to incident response or dynamic analysis when static analysis is not enough.
curl -fsSL codexskills.dev/install.sh \ | sh -s -- malware-triage Installs to ~/.agents/skills/malware-triage/ for every project on this machine.
curl -fsSL codexskills.dev/cli.mjs -o codex-skills.mjsnode codex-skills.mjs install malware-triage The CLI also searches, updates and removes skills. Run it with no arguments to pick from a list. Needs Node 20.12+.
curl -fsSL codexskills.dev/install.sh \ | sh -s -- --project malware-triage Installs to .agents/skills/malware-triage/ in the current repository. Commit it and everyone who runs Codex there gets it.
curl -fsSLO codexskills.dev/downloads/malware-triage.zipunzip -o malware-triage.zip -d ~/.agents/skills/ The archive holds the skill folder with its generated agents/openai.yaml. Unzip into .agents/skills/ to scope it to a repo.
& ([scriptblock]::Create((irm codexskills.dev/install.ps1))) malware-triage PowerShell 5.1 or 7. Installs to %USERPROFILE%\.agents\skills\. Add -Project for the current repo.
104-line POSIX script. No sudo, no telemetry. Read install.sh
Use it in Codex
Start a prompt with $malware-triage, or pick it from /skills.
You can also just describe the task: Codex reads the description below and loads the playbook when your request matches.
What Codex reads before loading it
Performs defensive static triage of a suspicious file in an isolated environment - hashing and reputation lookup, file-type and structure inspection (PE/ELF/Mach-O, Office, PDF, scripts, archives), string and indicator extraction, macro and embedded-object analysis, and a verdict with IOCs for blocking. Static and isolated only; it never runs the sample. Use when a user, SOC or incident needs a quick read on whether a downloaded or emailed file is malicious and what to block, without a full reverse-engineering effort.
Use it when
- A downloaded or emailed file needs a quick malicious-or-not read
- A SOC alert references a file you need to characterise
- You need IOCs to block from a sample without full reverse engineering
Use something else when
- You are running a live incident and need containment steps: use incident-response
- The evidence is log data rather than a file: use log-forensics
How to check the result
Every conclusion traces to an observed artifact (hash, string, structure), the sample was never executed, and the IOC list is defanged and ready for blocklists.
The mistake it prevents
Executing the sample to see what it does, or uploading a potentially sensitive file to a public multi-scanner before a hash-only lookup.
The goal is a fast, safe verdict: is this file likely malicious, what does it try to do, and what indicators should be blocked or hunted. Done well means you never executed the sample, you worked in an isolated environment, and every conclusion is backed by an observed artifact (a hash, a string, a structure), not a hunch.
Hard rules (read before anything)
- Never execute the sample. No double-click, no
./file, no “just see what it does” outside a purpose-built detonation sandbox owned by your team. This skill is static only. - Isolate. Work on a disposable VM or container with no access to production, no credentials mounted, and ideally no network. Treat the file as hostile input: copy it into its own empty directory and pass its path as an argument; never run an interpreter or build tool from inside that directory.
- Handle safely. Keep the sample zipped with a password (
infected) at rest so on-access AV does not quarantine it mid-analysis and so it is not double-clickable. - Confidentiality and legality. The sample may contain the victim’s data. Do not upload a potentially sensitive file to a public multi-scanner without authorization — public uploads are shared with vendors and sometimes downloadable. Prefer hash lookups first.
Triage flow
- [ ] 1. Hash it; look up the hash (not the file) in reputation sources
- [ ] 2. Identify the true file type (not the extension)
- [ ] 3. Inspect structure for the type; extract strings and indicators
- [ ] 4. Pull IOCs: hashes, domains, URLs, IPs, mutexes, filenames
- [ ] 5. Write a verdict with confidence and the artifacts that support it
1. Hash and reputation
sha256sum sample.bin; sha1sum sample.bin; md5sum sample.bin
Look up the SHA-256 in sources that take hashes (VirusTotal, MalwareBazaar, your EDR’s intel) without uploading the file. A known-bad hash ends the triage early; a never-seen hash means rely on your own static analysis.
2. Identify the type
file sample.bin # magic-based type, ignores the extension
trid sample.bin # finer type guess (if installed)
exiftool sample.bin # metadata: author, tool, timestamps (note, forgeable)
A .pdf that file calls a PE, or a .docx that is really an HTML smuggling page, is itself
a finding.
3. Inspect by type (static tools only)
| Type | Tools | Look for |
|---|---|---|
| PE (Windows exe/dll) | pefile, capa, floss, pecheck | imports (CreateRemoteThread, WinHTTP), sections, high-entropy = packed, signature, resources |
| ELF / Mach-O | readelf, nm, objdump -d (static only) | linked libraries, suspicious syscalls, embedded blobs |
| Office doc | oletools (olevba, oleid, rtfobj), oledump | auto-exec macros (AutoOpen), obfuscated VBA, external template/DDE links |
pdfid, pdf-parser (peepdf alt) | /OpenAction, /JavaScript, /Launch, /EmbeddedFile | |
| Script (ps1/js/vbs/bat/sh) | read it; floss/base64 decoders | encoded commands, download-and-run, obfuscation layers |
| Archive / installer | 7z l, binwalk | nested payloads, LNK files, double extensions, path traversal entries |
strings -a -n 8 sample.bin | sort -u | less # ASCII; add -el for UTF-16LE (Windows)
floss sample.bin # deobfuscated/stacked strings
capa sample.bin # maps to ATT&CK capabilities, no execution
olevba --decode suspicious.docm # dump and deobfuscate macros, does not run them
pdfid.py suspicious.pdf # counts risky PDF keywords
Most of these need installs (often the oletools, pefile, flare-capa/flare-floss
Python packages) and are offline once installed; in the Codex sandbox, call out when a step
needs network for the install.
4. Extract IOCs
Pull and record: file hashes, embedded URLs/domains/IPs, registry keys, mutex names,
scheduled-task or service names, dropped filenames, and any C2-looking host. Defang them in
notes (hxxp://evil[.]com) so nobody clicks. These feed blocklists and threat hunts.
Interpreting signals
| Observation | Leans | Note |
|---|---|---|
| High section entropy, tiny import table, packer strings (UPX, Themida) | Suspicious | Packing is common in malware but also in legit protected software |
Macro with AutoOpen + base64 + powershell -enc | Malicious | Classic maldoc chain |
PDF with /OpenAction launching JS or /Launch | Suspicious | Benign PDFs rarely auto-run anything |
| Valid, current code-signing cert from a known vendor | Leans benign | But stolen certs exist; weigh with other signals |
| Only business strings, normal imports, signed, known hash | Likely benign | Say so; false alarms waste time too |
A single signal is rarely conclusive. State confidence (likely malicious / suspicious, needs sandboxing / likely benign) and what would raise it.
When to stop and escalate
- Confirmed malicious or part of an active incident: hand the IOCs to incident response and stop poking; do not tip off the actor by resolving their C2 from a corporate IP.
- Needs dynamic analysis to be sure: route to a dedicated detonation sandbox and a reverse engineer. This skill does not build or run detonation environments.
- Targeted/novel sample: preserve the original, document chain of custody, escalate.
Output template
## Triage: invoice_scan.pdf.exe
**SHA-256:** 3f2a... | **Type:** PE32 executable (file says exe; name claims PDF)
**Reputation:** 41/72 vendors flag (MalwareBazaar family: AgentTesla), by hash lookup
**Static findings:** UPX-packed; WinHTTP + persistence imports; UTF-16 string hxxps://c2[.]bad[.]tld/g
**Verdict:** Malicious (high). Infostealer behaviour by capability map; do not execute.
**IOCs to block:** SHA-256 above; domain c2[.]bad[.]tld; mutex "Global\\xZ1"
**Next:** IR notified; sample retained zipped (pw: infected); dynamic analysis optional What the zip contains
SKILL.md plus the interface file below. Nothing runs on install.
agents/openai.yaml
Gives the Codex app a display name, a one-line description and a starter prompt for this skill.
interface:
display_name: "Malware Triage"
short_description: "A safe verdict without ever running it"
default_prompt: "$malware-triage Someone downloaded this attachment - is it safe? Do not run it" About this skill
Written and maintained by the Codex Skills editors to the same editorial standard as every skill here: a selective description, a real workflow, known pitfalls and a way to verify the work. First published , last updated . MIT licensed. Something wrong or out of date? Tell us.