Skip to content

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:

grep -E 'openat|connect|execve|clone|mprotect' trace.log
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 reset rebuilds 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 RWX mprotect or the odd-port connect in 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/clone yourself.

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