malware-dynamic-analysis
Skill46 starsChanged 2 months agoMITView on GitHub
Behavioral analysis of a sample executed in an isolated VM. Use after triage when runtime behavior, C2 traffic, dropped files, persistence, or injection must be observed. Claude produces a tailored VM runbook from triage predictions, then parses the exported text evidence (Procmon CSV, Sysmon JSON/CSV, tshark output, autoruns, strings) on the host to reconstruct behavior and extract IOCs. The analyst runs the VM; Claude never executes the sample.
- Installs packages
1 other project uses a version of this.
Adopted by
Most recently taken up by
- TaiMaBenJi/taima-skillsword for word, first seen Oct 11, 2026
Other versions1 project uses a version of this.
Word for word · 1
- TaiMaBenJi/taima-skills★ 1100% same
Edited · 0
None found.
Wrote their own version · 0
None found.
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository6 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- detection-engineerSkill
- malware-report-writerSkill
- malware-triageSkill
- malware-analysisSkill
- specialized-file-analyzerSkill
The file
We split this skill into the rules it gives an agent
6 rules. About 0 are common, 2 are distinctive, and 4 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈2
Distinctive · estimate
This author's own choices. Worth a look.
4
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 56
Do not filter to the sample alone if injection is predicted — include the predicted target (explorer.exe, svchost.exe, RegAsm.exe, …).
- Very specific: line 82
If nothing happens: see references/anti_analysis_bypass.md (VM checks, sleep patching, required arguments, missing parent process, …
- Very specific: line 86
Run these before reverting.
- Distinctive: line 133
If the user brings PML / PCAP(NG) / EVTX instead, reply with the conversion command and wait:
- Very specific: line 259
Every PE in dropped/ is a new sample: add it to analysis_state.md and route back through malware-triage.
- Distinctive: line 275
Remove your own lab artifacts (VM hostname, INetSim IPs, analyst username) and Windows-internal noise from the IOC list before recording it.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Malware Dynamic Analysis
Two halves. Part A is a runbook the analyst follows inside the isolated VM (REMnux / FlareVM); you tailor it from triage predictions and it ends with text-format evidence exports. Part B is your work: parse that evidence on the host, reconstruct what the sample did, extract behavioral IOCs, and write findings to analysis_state.md.
Execution Model
- You never execute the sample. The VM is network-isolated and has no Claude in it. Everything you run is on the host against exported evidence files.
- Locate skill files. Scripts and reference files ship in this skill's directory. Set
R="${CLAUDE_PLUGIN_ROOT:-<dir containing this SKILL.md>}"once (when installed as a plugin$CLAUDE_PLUGIN_ROOTis set; otherwise it is this skill folder). Your working directory is the user's analysis workspace, so prefix every script path below with$R, e.g.python3 "$R"/scripts/ioc_extract.py. - Before the VM run: read the triage findings in
analysis_state.mdand emit a runbook tailored to the predictions (which process names to filter, which Sysmon event IDs matter, expected protocol, expected persistence, expected evasion). Skip the tailoring only if triage is missing — then use the default runbook as-is. - After the VM run: the user hands you an evidence directory. Inventory it, reject binary formats with the conversion command (see Converting Binary Evidence), and then work through Part B with Bash and the bundled scripts. Do not ask the user to summarize the evidence for you.
- Scripts (relative to this skill dir):
scripts/procmon_summary.py,scripts/sysmon_summary.py; plus../scripts/ioc_extract.pyat repo root. All stdlib Python 3. - Sandbox reports count as evidence. ANY.RUN / Joe Sandbox / Hybrid Analysis / Threat.Zone (MCP) JSON or text reports go through Part B Step 6.
- Large files:
wc -lfirst. Use the summary scripts andgrep, nevercata 200k-line Procmon CSV.
Part A — VM Runbook (analyst executes this)
Emit this to the user, filled in with the sample name and triage predictions. Keep the safety checklist verbatim.
A1. Safety checklist — all boxes or do not execute
- Clean VM snapshot taken
- Network: host-only / internal, with INetSim or FakeNet-NG answering (never NAT to the real internet unless the engagement explicitly allows it)
- No shared folders, no clipboard sharing, no drag-and-drop
- Guest time sync disabled
- Monitoring tools started before execution (order below)
- Analysis persona active — no real credentials, names, or corporate artifacts on the VM
- Evidence transfer path decided (USB / one-way share) and a
C:\evidence\directory created
Full VM hardening and anti-VM-detection countermeasures: references/sandbox_setup.md, references/anti_analysis_bypass.md.
A2. Start monitoring (in this order)
- INetSim / FakeNet-NG (network simulation)
- Sysmon — already installed with
olafhartong/sysmon-modularor SwiftOnSecurity config - Procmon — clear capture (Ctrl+X), apply filters (below)
- Wireshark — capture on the VM adapter
- System Informer
- Regshot 1st shot (optional) /
autorunscbaseline (below)
Tool configuration details: references/tool_setup.md.
Procmon filters (tailor from triage — add predicted child processes and LOLBins):
Process Name is <sample.exe> Include
Process Name is <predicted child, e.g. powershell.exe, rundll32.exe> Include
Operation contains Process Include (keeps Process Create for the tree)
Process Name is procmon.exe / SystemInformer.exe / wireshark.exe ExcludeDo not filter to the sample alone if injection is predicted — include the predicted target (explorer.exe, svchost.exe, RegAsm.exe, …).
Baseline persistence snapshot (Sysinternals Autoruns, run as admin):
autorunsc64.exe -accepteula -a * -c -h -s -nobanner | Out-File -Encoding utf8 C:\evidence\autoruns_before.csvA3. Execute
# EXE
.\sample.exe # add args if triage found a required switch, e.g. /install /silent
# DLL — triage lists the exports; try DllMain first, then each named export
rundll32.exe sample.dll,DllMain
rundll32.exe sample.dll,<Export>
# Scripts
powershell.exe -ExecutionPolicy Bypass -File sample.ps1
cscript.exe //NoLogo sample.vbs
wscript.exe sample.js
mshta.exe sample.htaObserve 15 minutes minimum; 60+ if triage found sleep/time checks. Interact where the sample expects it (click the decoy, dismiss dialogs). Note the wall-clock time of execution — it anchors every timeline.
Watch for: new processes, network attempts (INetSim log), files in %TEMP%, %APPDATA%, C:\ProgramData, C:\Users\Public, registry Run keys, new services/tasks, UI changes (ransom note, fake error), CPU spikes.
If nothing happens: see references/anti_analysis_bypass.md (VM checks, sleep patching, required arguments, missing parent process, locale/keyboard checks).
A4. Export evidence — text formats only
Run these before reverting. Every file lands in C:\evidence\ (or /evidence on REMnux) and must be text.
| Source | Command / action | File |
| Procmon | File → Save → All events → CSV (or procmon.exe /OpenLog cap.pml /SaveAs procmon.csv) | procmon.csv |
| Sysmon | Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-Sysmon/Operational'} | Select-Object Id,TimeCreated,Message | ConvertTo-Json -Depth 3 | Out-File -Encoding utf8 C:\evidence\sysmon.json | sysmon.json |
| Wireshark → tshark | see block below | dns.txt, http.txt, conns.txt, tls.txt, syn.txt |
| Wireshark objects | File → Export Objects → HTTP → save all | http_objects/ |
| INetSim | copy /var/log/inetsim/service.log and report/ | inetsim_service.log |
| System Informer | File → Save → processes.txt; for suspicious process: right-click → Create dump file | processes.txt, <proc>.dmp |
| Memory dump strings | strings -a -n 8 -e l proc.dmp > proc_strings_wide.txt; strings -a -n 8 proc.dmp > proc_strings.txt (REMnux strings, or FLOSS) | *_strings*.txt |
| Persistence | autorunsc64.exe -accepteula -a * -c -h -s -nobanner | Out-File -Encoding utf8 C:\evidence\autoruns_after.csv | autoruns_after.csv |
| Scheduled tasks / services / WMI | PowerShell block below | persistence.txt |
| Regshot | Compare → output TXT | regshot.txt |
| Dropped files | PowerShell block below; copy the files themselves into dropped/ (they are new samples) | dropped_hashes.csv, dropped/ |
| Screenshots | ransom notes, dialogs, anything visual | screenshots/*.png |
tshark exports (run on REMnux against the saved capture.pcapng, or in the FlareVM Wireshark install dir):
P=capture.pcapng
tshark -r $P -Y "dns.flags.response==0" -T fields -e frame.time -e ip.src -e dns.qry.name > dns.txt
tshark -r $P -Y "http.request" -T fields -e frame.time -e ip.dst -e http.host -e http.request.method -e http.request.uri -e http.user_agent > http.txt
tshark -r $P -Y "tls.handshake.type==1" -T fields -e frame.time -e ip.dst -e tcp.dstport -e tls.handshake.extensions_server_name -e tls.handshake.ja3 > tls.txt
tshark -r $P -q -z conv,tcp -z conv,udp > conns.txt
tshark -r $P -Y "tcp.flags.syn==1 && tcp.flags.ack==0" -T fields -e frame.time_epoch -e ip.dst -e tcp.dstport > syn.txt
tshark -r $P -Y "http.request.method==POST" -T fields -e ip.dst -e http.request.uri -e http.content_length -e http.file_data > http_post.txtPersistence and dropped files (PowerShell, after execution):
$E = "C:\evidence"
Get-ScheduledTask | ? {$_.TaskPath -notlike "\Microsoft*"} | Select TaskName,TaskPath,State,@{n='Action';e={$_.Actions.Execute + ' ' + $_.Actions.Arguments}} | Format-List | Out-File -Encoding utf8 "$E\persistence.txt"
Get-CimInstance Win32_Service | ? {$_.PathName -notlike "C:\Windows\*"} | Select Name,PathName,StartMode,State | Format-List | Out-File -Encoding utf8 "$E\persistence.txt" -Append
Get-CimInstance -Namespace root\Subscription -Class __FilterToConsumerBinding | Format-List | Out-File -Encoding utf8 "$E\persistence.txt" -Append
foreach ($k in 'HKCU','HKLM') { Get-ItemProperty "${k}:\Software\Microsoft\Windows\CurrentVersion\Run*" | Out-File -Encoding utf8 "$E\persistence.txt" -Append }
$t = (Get-Date).AddMinutes(-90) # adjust to execution time
mkdir "$E\dropped" -Force | Out-Null
Get-ChildItem -Path $env:TEMP,$env:APPDATA,$env:LOCALAPPDATA,C:\ProgramData,C:\Users\Public,C:\Windows\Temp -Recurse -File -Force -ErrorAction SilentlyContinue |
? {$_.CreationTime -gt $t} | % { Copy-Item $_.FullName "$E\dropped\" -Force -ErrorAction SilentlyContinue; $_ } |
Get-FileHash -Algorithm SHA256 | Export-Csv "$E\dropped_hashes.csv" -NoTypeInformationThen: transfer C:\evidence\ to the host, revert the snapshot, verify the revert.
Converting Binary Evidence
If the user brings PML / PCAP(NG) / EVTX instead, reply with the conversion command and wait:
| Got | Convert with |
.pml | Windows VM: procmon.exe /OpenLog x.pml /SaveAs x.csv |
.pcap / .pcapng | The tshark block in A4 (tshark exists on REMnux and on any host with Wireshark) — you can run this yourself on the host if tshark is installed: command -v tshark |
.evtx | Windows: Get-WinEvent -Path sysmon.evtx | Select Id,TimeCreated,Message | ConvertTo-Json -Depth 3 | Out-File -Encoding utf8 sysmon.json. Host/REMnux: evtx_dump --format jsonl sysmon.evtx > sysmon.jsonl (pip install evtx) — sysmon_summary.py reads both |
.dmp | strings -a -n 8 x.dmp > x_strings.txt; strings -a -n 8 -e l x.dmp > x_strings_wide.txt — run on the host, it is not executable |
PCAP and memory dumps are safe to handle on the host; the PE files in dropped/ are new samples and go back through triage.
Part B — Evidence Analysis (you do this)
B0. Inventory
E=/path/to/evidence
ls -la "$E"; file "$E"/* | grep -v ':.*text' ; wc -l "$E"/*.csv "$E"/*.txt "$E"/*.json 2>/dev/null
head -2 "$E/procmon.csv" # confirm columns: Time of Day, Process Name, PID, Operation, Path, Result, DetailAnything that is not text → Converting Binary Evidence. Note the sample's process name(s) from triage/state; you will scope everything on them.
B1. Process behavior — Procmon
python3 malware-dynamic-analysis/scripts/procmon_summary.py "$E/procmon.csv" --process sample.exe > "$E/procmon_summary.txt"
wc -l "$E/procmon_summary.txt"; sed -n 1,80p "$E/procmon_summary.txt"The summary gives: process tree with command lines, files created/written/renamed/deleted, registry writes with persistence keys flagged, network endpoints, DLLs loaded from outside C:\Windows, event counts. Read it fully (page with sed -n). Then drill into specifics straight from the CSV:
# everything one child did
grep -F '"powershell.exe"' "$E/procmon.csv" | cut -d, -f2,4,5 | sort | uniq -c | sort -rn | head -40
# a specific path or key
grep -iF 'CurrentVersion\Run' "$E/procmon.csv" | head
# timeline of process starts (first-seen order)
grep -F '"Process Start"' "$E/procmon.csv" | cut -d, -f1,2,3,7 | head -40Interpret against the triage predictions: confirmed, refuted, or unexpected. Injection shows up as the sample writing to another process's address space only indirectly in Procmon — cross-check with Sysmon EID 8/10 in B2. Self-deletion (SetDispositionInformationFile on its own path, or cmd /c del), decoy launches, and LOLBin chains (rundll32, regsvr32, mshta, wscript, msiexec, certutil, bitsadmin) are the usual tells.
B2. Process behavior — Sysmon
python3 malware-dynamic-analysis/scripts/sysmon_summary.py "$E/sysmon.json" --process sample.exe > "$E/sysmon_summary.txt"
sed -n 1,120p "$E/sysmon_summary.txt"Sections and what they prove:
| Section (EID) | Read it for |
| Process tree (1) | Authoritative parent/child + full command lines + hashes of every executed image |
| Network (3) | Per-process destinations; BEACON-LIKE tag = regular intervals (coefficient of variation < 0.3 over ≥5 connections) |
| DNS (22) | Queried names and resolved IPs, even when the connection failed |
| Files (11) | Dropped files by process — the source of truth for dropped/ |
| Registry (12/13/14) | PERSISTENCE flags: Run/RunOnce, Services, Winlogon, IFEO, TaskCache, AppInit |
| Remote threads (8) | CreateRemoteThread injection: source → target, start address |
| Process access (10) | OpenProcess with high rights (0x1F0FFF, 0x1FFFFF, 0x143A) → injection prep, LSASS access → credential theft |
| Image loads (7) | Unsigned DLLs from user-writable paths, sideloading |
| Pipes (17/18) | Named pipes = Cobalt Strike / Meterpreter / custom IPC IOCs |
| WMI (19/20/21) | WMI event subscription persistence |
| Tampering (25) | Process hollowing / herpaderping |
Correlate B1 and B2: Procmon has more file/registry granularity, Sysmon has hashes, injection, DNS, and command lines. Where they disagree, trust Sysmon for process identity and Procmon for file operations.
B3. Network
cat "$E/dns.txt" | awk '{print $NF}' | sort | uniq -c | sort -rn | head -30
cat "$E/http.txt" | head -40
cat "$E/tls.txt" | awk -F'\t' '{print $2":"$3, $4, $5}' | sort -u
sed -n 1,60p "$E/conns.txt"
grep -v '^$' "$E/http_post.txt" | head -20
grep -iE 'connect|request|GET|POST' "$E/inetsim_service.log" | head -40Beacon detection from syn.txt (interval regularity per destination):
python3 - "$E/syn.txt" <<'EOF'
import sys, statistics, collections
by = collections.defaultdict(list)
for line in open(sys.argv[1]):
p = line.split()
if len(p) == 3: by[(p[1], p[2])].append(float(p[0]))
for (ip, port), ts in by.items():
ts.sort(); gaps = [b-a for a, b in zip(ts, ts[1:])]
if len(gaps) >= 4:
m = statistics.mean(gaps); cv = statistics.pstdev(gaps)/m if m else 9
print(f"{ip}:{port} n={len(ts)} mean={m:.1f}s cv={cv:.2f} {'BEACON' if cv < 0.3 else ''}")
EOFWhat to establish: C2 hosts (DNS name → IP → port → protocol), beacon interval and jitter, User-Agent and URI pattern (Suricata material), TLS SNI/JA3, download URLs and what came back (http_objects/ — file them; PE payloads go back to triage), exfiltration (POST sizes, encoding), DGA signs (many NXDOMAIN, random-looking labels), and whether traffic went to INetSim or the sample gave up (matters for what you can claim).
B4. Persistence and system changes
cat "$E/persistence.txt"
# autoruns diff: entries present after but not before
python3 - "$E/autoruns_before.csv" "$E/autoruns_after.csv" <<'EOF'
import csv, sys
key = lambda r: (r.get('Entry Location',''), r.get('Entry',''), r.get('Image Path',''))
before = {key(r) for r in csv.DictReader(open(sys.argv[1], encoding='utf-8-sig', errors='replace'))}
for r in csv.DictReader(open(sys.argv[2], encoding='utf-8-sig', errors='replace')):
if key(r) not in before: print(r.get('Entry Location'), '|', r.get('Entry'), '|', r.get('Image Path'), '|', r.get('Signer',''))
EOF
grep -iE 'Run|Services|TaskCache|Winlogon' "$E/regshot.txt" | head -40Map each mechanism to ATT&CK (T1547.001 Run keys, T1053.005 scheduled task, T1543.003 service, T1546.003 WMI, T1574.002 sideloading, …) — the detection phase needs the technique IDs.
B5. Dropped files and memory strings
cat "$E/dropped_hashes.csv"
file "$E"/dropped/*
python3 scripts/ioc_extract.py "$E"/*_strings*.txt # C2, keys, paths decrypted only at runtime
grep -iE 'user-agent|/gate|/panel|\.php|password|token|Bearer' "$E"/*_strings*.txt | sort -u | head -40Every PE in dropped/ is a new sample: add it to analysis_state.md and route back through malware-triage. Runtime strings that were absent from the static strings dump are the decrypted config — call that out explicitly, it is the strongest YARA/Suricata material.
B6. Sandbox reports (if provided)
ANY.RUN / Joe / Hybrid Analysis / Threat.Zone JSON: jq the process tree, network, dropped files, and MITRE sections; treat them as a fourth evidence source and reconcile with B1-B5. Sandbox results are weaker than your own VM run when the sample is VM-aware — say so if behaviors differ.
jq -r '.. | .processes? // empty' report.json | head; jq -r '.. | .network? // empty' report.json | headB7. Consolidate
cat "$E/procmon_summary.txt" "$E/sysmon_summary.txt" "$E"/dns.txt "$E"/http.txt "$E"/tls.txt "$E"/persistence.txt 2>/dev/null | python3 scripts/ioc_extract.py > "$E/iocs_defanged.txt"Remove your own lab artifacts (VM hostname, INetSim IPs, analyst username) and Windows-internal noise from the IOC list before recording it.
Output
Append to analysis_state.md under the sample's Analysis Findings and IOCs Identified, then print the findings summary:
## Dynamic Analysis — [sample] (executed [UTC time], observed [n] min, VM: [FlareVM/REMnux], network: [INetSim/FakeNet/none])
### Execution chain
[process tree with command lines; injection targets; LOLBins; self-deletion]
### Predictions vs observed
| Triage prediction | Observed | Evidence |
### File system
Created / modified / deleted, with hashes for dropped PE files
### Registry & persistence
Mechanism → key/task/service → payload path → ATT&CK ID
### Network
C2: host → IP:port, protocol, beacon interval/jitter, UA, URI pattern, TLS SNI/JA3 · Downloads · Exfil · DGA
### Evasion observed
Sleep, VM checks, debugger checks, tampering (EID 25), what was bypassed and how
### Behavioral IOCs (defanged)
Process (names, cmdlines, mutexes, pipes) · File (paths, hashes) · Registry · Network
### MITRE ATT&CK
Technique IDs with the observation that supports each
### Not observed / limitations
[network to real C2 blocked; sample exited after VM check; only 15 min observed …]Recommend detection-engineer next (behaviors + network IOCs are ready) unless dropped payloads need triage first.
Quality Gate
Evidence inventoried and all text · process tree with command lines · every prediction marked confirmed/refuted/unexpected · dropped files hashed and routed · persistence mapped to ATT&CK · C2 characterized (or explicitly "no network observed") · IOCs defanged and lab noise removed · limitations stated · state file updated.
References
references/tool_setup.md— Procmon filters/columns, Wireshark filters, System Informer, Sysmon install, Regshot, TCPView, Noriben, INetSim, FakeNet-NGreferences/sandbox_setup.md— REMnux/FlareVM build, isolation, snapshots, CAPE/Cuckooreferences/anti_analysis_bypass.md— VM/debugger/sleep evasion and how to defeat itscripts/procmon_summary.py,scripts/sysmon_summary.py— evidence condensers (--self-testto verify)../scripts/ioc_extract.py— IOC extraction and defanging
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

