BOOT CHAIN LAB
Lab 6 · detection engineering · capstone

Where it has to be real.

Disk can be empty or lying. The network only carries ciphertext. But to run, code must exist — decrypted, unpacked, resolved — in RAM. That is the one place an implant cannot hide and still execute. Lab 5's sled landed somewhere; this is where you go find it. Memory forensics is reading that snapshot and asking: what's executing here that nothing on disk accounts for?

01 — why memory

The place that can't lie

Every trick from the earlier labs converges here. A fileless implant never touches disk — but it's a running thread, so it's in RAM. A packed payload is gibberish on disk and plaintext in memory once it unpacks to run. The call-table hooks from Lab 2 are pointers in live kernel structures. The hidden process from Lab 3 still has an EPROCESS object the allocator knows about. The NOP sled from Lab 5 is a committed, executable region somewhere in a victim's address space.

injected codeMemory a process is executing that is private (not shared) and not backed by a file on disk. Legitimate executable code is nearly always a mapped image. Private + executable + no backing file is the classic shape of injection.
hidden processesUnlinking an EPROCESS from the list hides it from pslist — but the object still carries its pool tag, so scanning the pool finds it anyway. Lab 3's cross-view, done against the image.
hooks & callbacksSSDT / IDT / IRP tables and notify-routine arrays live in kernel memory. Resolve each pointer against the module that owns that address — a pointer into unbacked or unexpected memory is the hook from Lab 2.
02 — run malfind

Hunt injected code by its shape

The canonical technique (Volatility's malfind): walk every process's committed memory regions (its VAD tree) and flag the ones that are executable, private, and have no backing file — then look at the first bytes. An MZ header or a run of 0x90 in a region like that has no innocent explanation. Run the scan on this sample image:

Run malfind to classify each region.

rule: executable & private & unbacked → injection candidate; inspect first bytes. Mapped-image code is cleared. A known JIT engine is flagged for tuning, not convicted — see §04.

03 — the process that isn't there

pslist vs psscan, in the image

The same move as Lab 3, one layer down. pslist walks the doubly-linked list the OS maintains — the convenient view, and the one a rootkit unlinks itself from. psscan ignores the list and scans the memory pool for anything carrying the Proc pool tag. A process present in the scan but absent from the list unlinked itself.

pslist · linked list

psscan · pool-tag scan

Here psscan turns up a svch0st.exe (pid 6620) the list never mentions — hollowed and unlinked. On its own that's a question, not a conviction: the pool can also hold a process that exited mid-capture. The answer is corroboration — does it also own injected memory (§02) or an outbound socket? Convictions are built from agreeing evidence, never one view.

04 — the hard part

A snapshot of a moving target

Memory forensics is powerful and full of ways to fool yourself. The discipline is knowing them:

On this Mac. Full memory imaging is harder on modern macOS (SIP, Apple-silicon protections) than the Windows tooling assumes. The lab's practical analog is live endpoint telemetry — osquery process/open-handle tables and eslogger events — which captures the same facts (unbacked executable mappings, process lineage) continuously, without a raw dump. The principle is OS-agnostic; the acquisition path differs.

05 — provenance & citations

Where this comes from

technique & tooling Volatility 3 — Volatility Foundation. The reference open-source memory-forensics framework; windows.malfind, windows.pslist, windows.psscan, windows.ssdt.
github.com/volatilityfoundation/volatility3
A. Schuster (2006), “Searching for Processes and Threads in Microsoft Windows Memory Dumps,” DFRWS — pool-tag scanning, the basis of psscan.
reference & mapping Ligh, Case, Levy & Walters (2014), The Art of Memory Forensics, Wiley — the standard text.
MITRE ATT&CK — Process Injection T1055; Reflective / fileless execution.
this lab Closes the arc: the sled from Lab 5, the cross-view from Lab 3, the hooks from Lab 2 — all found again in RAM. macOS analog: osquery + eslogger in BlueTeamLab.

That's the chain, end to end: from the first instruction at 0x7c00 to the injected page in RAM — seven ways to measure the ground an attacker stands on, without ever standing on it yourself.