Cheat sheet — Dynamic Analysis: Behavioural¶
Companion to Module 05 — Dynamic Analysis — Behavioural · CC BY 4.0 — print it, pin it, share it.
Last reviewed: 2026-07
Only detonate live malware in an isolated, disposable analysis VM with no bridged network. Reset to a known-clean state after every run — never analyse two samples in the same environment.
strace — the syscall microscope¶
strace ./sample # every syscall, in order, with args + return values
strace -f ./sample # -f: follow forks/threads (malware spawns children)
strace -o trace.log -f ./sample # write the trace to a file for later grepping
strace -e trace=network ./sample # filter: only network syscalls
strace -e trace=openat,connect,execve,clone,mprotect ./sample # the high-signal set
strace -tt -T ./sample # -tt: wall-clock timestamps -T: time spent in each call
strace -s 200 ./sample # show up to 200 bytes of string args (default 32)
ltrace — the library-call complement¶
ltrace ./sample # libc calls: fopen, malloc, execve wrappers, strcmp…
ltrace -f ./sample # follow children
ltrace -S ./sample # interleave syscalls (strace) with library calls
ltrace -e 'malloc+free-@libc.so*' ./sample # filter which calls to show
- Use ltrace when the interesting logic is a libc wrapper (string compares in a check,
system()args) that strace only shows as the raw syscall.
Reading the trace — signal from noise¶
A medium program traces thousands of lines. Grep the raw log for the handful that matter:
| Trace line | Suggests | ATT&CK |
|---|---|---|
openat("/etc/passwd", …) |
credential file access | T1003.008 |
connect(…) to a non-loopback addr |
network C2 | T1071 |
execve(…) / clone(…) |
process spawn / new interpreter | T1059 |
mprotect(…, PROT_EXEC) on prior-RW mem |
shellcode written then made runnable | T1055 |
Author the host detection — Sigma / auditd¶
# Sigma: process_creation source
title: Suspicious /etc/passwd read after network connect
logsource: { product: linux, category: process_creation }
detection:
sel:
Image|endswith: '/sample'
condition: sel
level: high
tags: [attack.t1003.008]
# auditd — watch a sensitive read; then aureport/ausearch the log
auditctl -w /etc/passwd -p r -k cred_read
ausearch -k cred_read
- Prove it: the rule must fire on the malicious trace and stay quiet on a benign one. Match without a true-negative is half a rule.
Windows equivalent — Procmon CSV (read-only here)¶
Filter discipline is the skill: exclude OS noise, include by process/path/result.
Events to isolate: RegSetValue on …\CurrentVersion\Run → T1547.001 (persistence)
WriteFile into another process image → T1055 (injection)
Gotchas worth remembering¶
- You are running live code. Network isolation must hold and the environment must reset to clean after each run (
make resetrebuilds from the image — your snapshot equivalent). - A quiet trace is not proof of innocence. The trace only captures the path the sample took this run — environment-conditional or time-delayed code (Module 10) may simply not fire.
- The skill is reading, not running. Anyone can launch
strace; finding the lone RWXmprotector the odd-portconnectin thousands of lines is the job. - strace/ltrace can be detected. A
ptrace-based check sees the tracer and may go quiet (Module 10) — "did nothing" can mean "detected me." - AI gives a decent first-pass trace summary but glosses the rare, high-value events — grep the raw trace for
connect/execve/mprotect/cloneyourself.
Comments
Sign in with GitHub to comment. Choose the type: Feedback (errors or suggestions on this page) · Hints (help for fellow learners — no spoilers) · General (anything else).