Skip to content

Back to the catalog

dfir.chwriteup

[s|l]trace - Linux Malware Analysis

A hands-on DFIR walkthrough analyzing the BPFDoor Linux backdoor purely through strace syscall tracing, without static/dynamic disassembly. The author compiles BPFDoor from a leaked Pastebin source, traces execution with strace -ff, and correlates observed syscalls (self-copy to /dev/shm/kdmtmpflush, timestomping, --init respawn, PID file check at /var/run/haldrund.pid) with prior analysis from Sandfly Security's Craig Rowland, producing usable IOCs for detection/hunting.

TL;DR Traces BPFDoor's full execution chain with strace to extract IOCs and confirm known behaviors like ramdisk self-copy and timestomping.
Document

What it is

A DFIR walkthrough that reverses BPFDoor's startup behavior using only strace, not a disassembler. It reproduces the technique on a self-compiled sample and maps each observed syscall to Craig Rowland's (Sandfly Security) prior static analysis, so the value here is the method and the exact process chain, not the malware identification the summary already gives.

How it works

The author compiles the leaked source and traces it, following child forks so each process gets its own log:

wget https://pastebin.com/raw/kmmJuuQP
mv kmmJuuQP kmmJuuQP.c
gcc -o BPFDoor kmmJuuQP.c
chmod +x BPFDoor
strace -o log -ff ./BPFDoor

-ff is the load-bearing flag: BPFDoor forks repeatedly, and without per-process logs the chain is unreadable. The trace shows a distinct sequence of execve calls across PIDs:

flowchart TD
    A["PID 6014: execve BPFDoor<br/>access /var/run/haldrund.pid"] -->|ENOENT: not infected| B["clone → PID 6015"]
    A -->|R_OK=0: already infected| Z["terminate"]
    B --> C["sh -c: rm -f /dev/shm/kdmtmpflush"]
    C --> D["/bin/rm removes kdmtmpflush"]
    D --> E["/bin/cp BPFDoor → /dev/shm/kdmtmpflush"]
    E --> F["/bin/chmod 755 kdmtmpflush"]
    F --> G["execve kdmtmpflush --init<br/>(timestomp + go resident)"]

The infection check (access("/var/run/haldrund.pid", R_OK)) runs first; a return of 0 means the host is already compromised and the sample exits. Two details the author flags as not in Craig's write-up: the copy is done via /bin/cp (whose internals — openat O_WRONLY|O_CREAT|O_EXCL, mmap, read/write of the 32608-byte ELF — are visible), and a separate /bin/chmod 755 /dev/shm/kdmtmpflush (fchmodat 0755) makes the dropped copy executable.

What to do

Use these as detection/hunt signals, all observable as spawned processes or file events:

  • Execution or existence of /dev/shm/kdmtmpflush (Linux ramdisk — a copy of the original binary).
  • cp/chmod 755 targeting anything under /dev/shm.
  • rm -f /dev/shm/kdmtmpflush followed immediately by a self-copy to the same path.
  • Reads/writes of /var/run/haldrund.pid (the infection-marker PID file).
  • Any process invoking itself with a --init argument, which triggers timestomping and residency.

For your own triage, the reusable takeaway is strace -o log -ff against an untrusted binary in a disposable VM to surface exec chains and dropped-file paths without reversing.

Caveats

The sample is compiled from leaked Pastebin source, not a captured in-the-wild binary, so offsets and the 32608-byte size are specific to this build. The trace excerpt is condensed; the full logs and binary are in a password-protected archive (infected). Analysis covers startup and self-installation only — the packet-capture/BPF backdoor logic that follows --init is not traced in the provided text.

Organisations named here

  • Craig Rowland
  • Sandfly Security

Technologies named here

  • strace
  • Linux
  • ltrace
  • Ubuntu
  • gcc
  • ps

Techniques named here

  • Masquerading
  • Timestomping
  • Ingress Tool Transfer / Self-copy to ramdisk
  • Indicator Removal
  • BPF-based traffic filtering / sniffing for C2
  • Marker file to prevent re-infection

Threat actors named here

  • BPFDoor