Memory Forensics with Volatility 3

Memory Forensics with Volatility 3 - article cover image Tools & Defense
Time it takes to read this article 6 minutes.

Disclaimer: This article is provided strictly for educational purposes and authorized security testing. Only run these techniques against systems you own or have explicit written permission to assess. Unauthorized access to computer systems is illegal in virtually every jurisdiction and can carry severe penalties.

Introduction

Disk forensics answers what was left behind; memory forensics answers what was *running*. A RAM capture holds decrypted malware payloads that only ever existed in-memory, injected shellcode with no corresponding file on disk, active network connections, decrypted credentials cached by the LSA, and the true state of the process tree — none of which is reliably visible from a static disk image. For fileless malware, process-injection tradecraft, and living-off-the-land activity, memory is frequently the only place the evidence exists at all.

Volatility 3 is the current generation of the dominant open-source memory forensics framework, a full rewrite of Volatility 2 that replaced the old hand-maintained ‘profile’ system with symbol tables generated directly from OS debug symbols (PDBs on Windows), making it far more resilient to new Windows builds. It works purely as a set of Python plugins that walk kernel data structures inside a raw memory image, reconstructing the process list, network state, loaded modules, and more without needing the analyzed machine to cooperate in any way.

Attack Prerequisites

Memory forensics requires a captured image and the tooling to interpret it; the prerequisites are acquisition-side, not exploitation-side:

  • A memory acquisition tool run at (or as close as possible to) the time of the incident — WinPmem, Magnet RAM Capture, FTK Imager, or a hypervisor snapshot/.vmem file for virtualized hosts.
  • An intact, uncorrupted raw image (.raw, .mem, .vmem, or a hibernation/crash-dump file Volatility can also parse) — partial captures from a crashing or rebooting host can break structure walking.
  • Volatility 3 installed (pip install volatility3) with network access (or a pre-cached local symbol store) to fetch or generate the matching ISF symbol table for the target Windows build, or a Linux/Mac banner-matched symbol package for those platforms.
  • Sufficient disk and RAM on the analysis workstation — a 32GB capture is routine, and several plugins (malfind, dumpfiles) materialize large amounts of extracted data.

How It Works

A raw memory image is just a flat byte stream, but Volatility 3 knows the layout of the OS kernel’s core data structures (the EPROCESS list for Windows processes, the ETHREAD list for threads, VAD trees for virtual address descriptors, etc.) from the ISF symbol table it loads for that specific build. Plugins walk these structures the same way the kernel itself would: windows.pslist walks the doubly linked EPROCESS list, while windows.psscan instead scans the whole image for byte patterns matching an EPROCESS pool tag, which finds processes that have been unlinked from the list (a classic DKOM anti-forensics technique) but are still resident in memory. Comparing pslist and psscan output is one of the single most useful cross-checks in memory forensics.

Process injection detection relies on the VAD (Virtual Address Descriptor) tree, which tracks every memory region a process has mapped and its protection flags. Legitimate executable code almost always maps back to a file on disk (a DLL or the EXE image); a region marked PAGE_EXECUTE_READWRITE with no backing file, or a private, anonymously allocated region containing a PE header or shellcode-like bytes, is the signature of process injection, reflective DLL loading, or process hollowing. windows.malfind automates exactly this heuristic and is usually the first plugin run against an image suspected of hosting injected code.

Network artifacts (windows.netscan), open handles (windows.handles), loaded modules (windows.dlllist), and registry hives resident in memory (windows.registry.hivelist / windows.registry.printkey) round out the picture, letting an analyst correlate a suspicious process with the connections it held open and the DLLs it had loaded, all from a single static capture.

Practical Example / Configuration

A standard Volatility 3 triage sequence against a captured image, run in order from broad situational awareness down to targeted extraction:

# 1. Identify the OS build so the right symbol table is used
python3 vol.py -f memdump.raw windows.info

# 2. Baseline process view (walks the EPROCESS linked list)
python3 vol.py -f memdump.raw windows.pslist
python3 vol.py -f memdump.raw windows.pstree

# 3. Pool-scan for unlinked/hidden processes -- compare against pslist
python3 vol.py -f memdump.raw windows.psscan

# 4. Hunt for injected code / RWX private memory (VAD heuristic)
python3 vol.py -f memdump.raw windows.malfind --pid 4412

# 5. Command lines and environment for the suspicious PID
python3 vol.py -f memdump.raw windows.cmdline --pid 4412
python3 vol.py -f memdump.raw windows.envars --pid 4412

# 6. Network state at time of capture
python3 vol.py -f memdump.raw windows.netscan

# 7. Loaded modules / DLLs for the suspicious process
python3 vol.py -f memdump.raw windows.dlllist --pid 4412
Bash

Walkthrough / Exploitation

Once malfind flags a suspicious VAD region inside a legitimate-looking process (a common pattern for beacon-style implants injected into svchost.exe or a browser process), extract the region and the process image itself for static analysis and hashing:

# Dump the flagged VAD region(s) to disk for a disassembler/YARA pass
python3 vol.py -f memdump.raw -o ./out windows.malfind --pid 4412 --dump

# Dump the full process executable as reconstructed from memory
python3 vol.py -f memdump.raw -o ./out windows.pslist --pid 4412 --dump

# Sweep the whole image with a YARA rule (e.g. a known C2 config pattern)
python3 vol.py -f memdump.raw windows.vadyarascan --yara-file cobalt.yar
Bash

Recover files an attacker may have staged or executed purely in memory using filescan to locate FILE_OBJECT structures and dumpfiles to extract the cached content:

python3 vol.py -f memdump.raw windows.filescan | grep -i 'temp\\'
python3 vol.py -f memdump.raw -o ./out windows.dumpfiles --virtaddr 0x8a4f2010
Bash

For credential exposure, windows.hashdump and windows.cachedump (where present for the target OS/build) recover local SAM hashes and cached domain credentials directly from the in-memory registry hives — valuable for scoping whether credentials were harvestable at capture time.

Note: Volatility 3 needs network access on first run against a given Windows build to download the matching symbol table from Microsoft’s symbol server (cached thereafter under ~/.cache/volatility3). Air-gapped labs should pre-fetch and vendor the ISF JSON files for every build in scope before an engagement, not during one.

Opsec / Analyst tip: Always work against a copy of the image and record its SHA256 for chain of custody before running any plugin. pslist alone is not sufficient evidence of ‘no malicious process’ — always cross-check with psscan, and treat process count mismatches between the two as a hidden-process indicator worth investigating with malfind and dlllist.

Detection and Defense

Memory forensics is primarily an *investigative* capability, but it also informs prevention and detection strategy:

  • Build memory acquisition into IR playbooks for any host suspected of hosting fileless malware or process injection — volatile evidence is lost on reboot or extended runtime.
  • Cross-check pslist against psscan routinely; a mismatch is a strong indicator of DKOM-style process hiding.
  • Treat RWX/anonymous executable memory regions as high-signal both in memory forensics and in EDR telemetry (many EDR products expose an equivalent live check, e.g. Sysmon-adjacent memory-scan integrations).
  • Correlate netscan output with firewall/proxy logs to confirm whether an in-memory implant’s C2 connections actually egressed.
  • Snapshot memory for VMs before remediation — a hypervisor snapshot is often faster and less disruptive than a dedicated acquisition tool.

Real-World Impact

Memory forensics is standard practice in ransomware and APT incident response because so much modern tradecraft — Cobalt Strike beacons, reflective DLL loaders, credential-dumping tools like Mimikatz run in-memory, and PowerShell-based droppers — deliberately avoids writing a persistent artifact to disk specifically to defeat static forensics. malfind-style VAD analysis remains one of the most reliable ways to surface exactly this class of implant during an investigation, regardless of how the initial file-based defenses were bypassed.

Conclusion

Volatility 3’s symbol-table-driven architecture makes memory forensics practical against current Windows builds without hand-maintained profiles, and a disciplined plugin sequence — pslist/psscan for process integrity, malfind for injected code, netscan for live connections, and dumpfiles/hashdump for extraction — turns a raw RAM capture into a concrete, defensible account of what was actually executing on a compromised host.

You Might Also Like

If you found this useful, these related deep-dives cover adjacent techniques and their defenses:

Comments

Copied title and URL