agentleFS
gl0bal01gl0bal01/malware-analysis-claude-skills/malware-dynamic-analysis/SKILL.md

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

  • Other versions1 project uses a version of this.

    Word for word · 1

    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.

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
  1. Very specific:

    Do not filter to the sample alone if injection is predicted — include the predicted target (explorer.exe, svchost.exe, RegAsm.exe, …).

    line 56
  2. Very specific:

    If nothing happens: see references/anti_analysis_bypass.md (VM checks, sleep patching, required arguments, missing parent process, …

    line 82
  3. Very specific:

    Run these before reverting.

    line 86
  4. Distinctive:

    If the user brings PML / PCAP(NG) / EVTX instead, reply with the conversion command and wait:

    line 133
  5. Very specific:

    Every PE in dropped/ is a new sample: add it to analysis_state.md and route back through malware-triage.

    line 259
  6. Distinctive:

    Remove your own lab artifacts (VM hostname, INetSim IPs, analyst username) and Windows-internal noise from the IOC list before recording it.

    line 275

≈ “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.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

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_ROOT is 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.md and 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.py at 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 -l first. Use the summary scripts and grep, never cat a 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)

  1. INetSim / FakeNet-NG (network simulation)
  2. Sysmon — already installed with olafhartong/sysmon-modular or SwiftOnSecurity config
  3. Procmon — clear capture (Ctrl+X), apply filters (below)
  4. Wireshark — capture on the VM adapter
  5. System Informer
  6. Regshot 1st shot (optional) / autorunsc baseline (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   Exclude

Do 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.csv

A3. 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.hta

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

SourceCommand / actionFile
ProcmonFile → Save → All events → CSV (or procmon.exe /OpenLog cap.pml /SaveAs procmon.csv)procmon.csv
SysmonGet-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-Sysmon/Operational'} | Select-Object Id,TimeCreated,Message | ConvertTo-Json -Depth 3 | Out-File -Encoding utf8 C:\evidence\sysmon.jsonsysmon.json
Wireshark → tsharksee block belowdns.txt, http.txt, conns.txt, tls.txt, syn.txt
Wireshark objectsFile → Export Objects → HTTP → save allhttp_objects/
INetSimcopy /var/log/inetsim/service.log and report/inetsim_service.log
System InformerFile → Save → processes.txt; for suspicious process: right-click → Create dump fileprocesses.txt, <proc>.dmp
Memory dump stringsstrings -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
Persistenceautorunsc64.exe -accepteula -a * -c -h -s -nobanner | Out-File -Encoding utf8 C:\evidence\autoruns_after.csvautoruns_after.csv
Scheduled tasks / services / WMIPowerShell block belowpersistence.txt
RegshotCompare → output TXTregshot.txt
Dropped filesPowerShell block below; copy the files themselves into dropped/ (they are new samples)dropped_hashes.csv, dropped/
Screenshotsransom notes, dialogs, anything visualscreenshots/*.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.txt

Persistence 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" -NoTypeInformation

Then: 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:

GotConvert with
.pmlWindows VM: procmon.exe /OpenLog x.pml /SaveAs x.csv
.pcap / .pcapngThe 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
.evtxWindows: 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
.dmpstrings -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, Detail

Anything 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 -40

Interpret 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 -40

Beacon 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 ''}")
EOF

What 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 -40

Map 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 -40

Every 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 | head

B7. 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-NG
  • references/sandbox_setup.md — REMnux/FlareVM build, isolation, snapshots, CAPE/Cuckoo
  • references/anti_analysis_bypass.md — VM/debugger/sleep evasion and how to defeat it
  • scripts/procmon_summary.py, scripts/sysmon_summary.py — evidence condensers (--self-test to verify)
  • ../scripts/ioc_extract.py — IOC extraction and defanging

Download now (ZIP)

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
What did you use it for? e.g. Reviewing pull requests in a Rails app

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.