malware::analysis

dfir static · dynamic triage · sandbox
Triage Static Dynamic Config / C2 Shellcode .NET Packers / anti Detection
SAFETY → Detonate only in an instrumented, snapshot-able VM with a controlled network. Prefer static where you can: anti-tamper/anti-debug samples may silently corrupt data under a debugger, not just exit.
01Triage
Identify + hash
sha256sum sample ; ssdeep -b sample   # exact + fuzzy hash
file sample ; exiftool sample
diec sample.exe            # Detect It Easy: packer/compiler
diec -e sample.exe         # -e section entropy (>7 = packed)
# imphash for family clustering
python3 -c "import pefile;print(pefile.PE('x.exe').get_imphash())"
ssdeep -m known.txt suspect.exe  # match vs known set
Strings + capabilities
# FLOSS = strings + decoded/stack/tight (deobfuscated)
floss sample.exe
floss --only stack tight -- sample.exe  # '--' before path
floss -j sample.exe > strings.json

# capa (v9.x) → MITRE ATT&CK / MBC capabilities
capa sample.exe
capa -vv sample.exe         # show which features matched
capa -j sample.exe > caps.json
pecheck.py -y all sample.exe  # PE summary + YARA
02Static Analysis
PE structure & disasm
rabin2 -I sample.exe        # info: arch, bits, signed
rabin2 -i / -E / -S sample.exe # imports / exports / sections
objdump -x sample.exe | less
# deep dive: Ghidra / IDA / Binary Ninja

# red flags
- RWX section · very high entropy · tiny import table
- VirtualAlloc/WriteProcessMemory/CreateRemoteThread (injection)
- WinHttp/InternetOpenUrl/WSASocket (C2)
Unpacking
upx -l packed.exe          # is it UPX?
upx -d packed.exe -o unpacked.exe

# custom packer → dump OEP in a debugger:
- bp on VirtualAlloc / tail-jump to a fresh RWX region
- run to OEP, dump the image, rebuild the IAT (Scylla)
- unpac.me for automated cloud unpacking (see §08)

# then diff: strings/imports/entropy before vs after,
# carve embedded config or a 2nd stage from resources/overlay
03Dynamic Analysis
Sandbox + baseline
# CAPEv2 — auto config/payload extraction (Cuckoo successor)
python3 utils/submit.py sample.exe
python3 utils/submit.py --package dll --options function=Foo sample.dll
python3 utils/process.py -r <task_id>   # re-run config extraction
# any.run = interactive cloud sandbox (web)

# Local baseline BEFORE detonating:
Regshot: shot1 → detonate → shot2 → Compare   # reg+file diff
Observe (4 channels)
proc Process Explorer / System Informer · ProcDOT graph
fs+reg Procmon /Quiet /BackingFile cap.pml → CSV
api  API Monitor (Crypto/Registry/Internet groups)
net  dumpcap -i eth0 -w cap.pcapng ; TCPView
     tshark -r cap.pcapng --export-objects http,./out

linux strace / ltrace / tcpdump / inotifywait
Fake the network
# cut real internet so C2 reveals itself locally
sudo inetsim            # fake HTTP/S,DNS,SMTP,FTP...
fakenet                 # FakeNet-NG (Admin/root)
fakenet -c custom.ini -l fakenet.log
# point the VM gateway/DNS at the fake service
Memory pivots
vol -f mem.raw windows.malfind   # injected RWX code
vol -f mem.raw windows.netscan   # C2 sockets
vol -f mem.raw windows.cmdline
# full memory workflow → volatility3 cheat sheet
04Config / C2 Extraction
Automated
# 1) identify the family (capa rules) →
# 2) let the sandbox/extractor pull the config:
python3 utils/process.py -r <task_id>   # CAPE 'cape_config' key
# frameworks CAPE uses: RATDecoders, DC3-MWCP, malduck, MaCo

# standalone family parsers (malwareconfig.com):
pip install git+https://github.com/kevthehermit/RATDecoders
python DarkComet.py sample.bin config.json
Manual blob decode
# config often = a high-entropy resource/overlay, XOR/RC4'd
- find the key: nearby string, imphash-known routine, or brute 1-byte
- XOR: xorsearch / translate.py ; RC4: look for 0x100 sbox loop
- then record the recovered indicators:

beacon URI · User-Agent · sleep/jitter · C2 host(s)
campaign/watermark · mutex · pubkey
05Shellcode
Emulate
scdbg /f sc.bin              # libemu: logs Win32 API calls
scdbg /f sc.bin /findsc       # find likely entry points
scdbg /f sc.bin /s -1         # unlimited steps (packed/looping)

speakeasy -t sc.bin -r -a x64 -o report.json
# -r/--raw shellcode, -a arch; --raw-offset skips a decoder stub
Run under a debugger
# BlobRunner: maps blob, prints base, pauses → attach x64dbg
BlobRunner.exe sc.bin       # BlobRunner64.exe for x64

# Cutter/Rizin ESIL (single-step without native run):
aei ; aeim ; aeip            # init VM, stack/mem, set IP
aes / aeso                   # step / step-over ; aer = regs
06.NET
Decompile
# diec/file says .NET / managed →
ilspycmd sample.dll            # CLI decompile to stdout
ilspycmd -p -o ./out sample.dll # -p export compilable project
# GUI: dnSpyEx (maintained fork) — read + debug + IL patch
#      JetBrains dotPeek — strong on generics/obfuscation
Deobfuscate
# use the de4dotEx / de4dot-cex forks (orig is 2015-stale)
de4dot sample.exe             # → sample-cleaned.exe
de4dot -r C:/in -ro C:/out    # recurse dir → output dir
de4dot --strtyp delegate --strtok 0x06000123 sample.exe
# strings still encrypted? dnSpyEx: bp the decrypt method, dump
07Packers & Anti-Analysis
Spot it statically (prefer static)
# Packing signal:
- section entropy >7.0 (diec -e / pefile get_entropy)
- tiny import table / near-empty imphash
- weird section names: UPX0, .themida, .aspack, .netreactor

# Anti-debug imports to flag:
IsDebuggerPresent · CheckRemoteDebuggerPresent · NtQueryInformationProcess
# PEB.BeingDebugged = fs:[0x30]+2 (x86) / gs:[0x60]+2 (x64)
Anti-VM & early exec
# Anti-VM (static grep of strings/disasm):
cpuid · rdtsc · "VMware" "VBOX" "VBoxGuest" "qemu" · hypervisor bit
# capa has rules that surface anti-debug/anti-VM automatically

# TLS callbacks run BEFORE the entry point — common unpack/anti stub
pe.DIRECTORY_ENTRY_TLS.struct.AddressOfCallBacks
08Detection & Clustering
Author signatures
# capa → ATT&CK/MBC (already ran in triage)
# YARA: strings + condition. Modifiers:
yara -r -s rules.yar /samples   # -s show match offsets, -m meta
#   xor / xor(0x01-0xff), base64 / base64wide, wide, nocase, fullword
#   (nocase can't combine with base64 or xor)

# rank noisy strings by ML relevance:
flarestrings mal.exe | rank_strings -l 100 -s
Cluster & services
imphash  # exact import-layout family match
ssdeep -d ./samples/*  # byte-similarity across variants

# services:
unpac.me      # automated unpacker (API: 'Authorization: Key ..')
VirusTotal    # vt file <hash> ; vt file behaviours <hash>
FLARE-VM      # Mandiant analysis distro (FLOSS/capa/stringsifter)
09Pitfalls
Instrumented VM only
Snapshot before detonation; be ready to revert.
Strings mislead
Decoys, dead strings, and encrypted blobs are the norm — corroborate.
Prefer static on anti-tamper
A debugger can corrupt data silently. Static + dynamic + memory must reinforce each other.