Memory Forensics with Volatility: Finding What Attackers Hide in RAM
Why memory matters, how Volatility works, and the plugins that catch modern attacks
Search for a command to run...
Why memory matters, how Volatility works, and the plugins that catch modern attacks
No comments yet. Be the first to comment.
Digital forensics fundamentals and memory analysis with Volatility. Evidence collection, order of volatility, and finding what attackers hide in RAM.
The forensic process, evidence collection, order of volatility, and the tools that actually work
Static, dynamic, and memory analysis tradecraft
Hypothesis-driven proactive defense across endpoint and network
Display filters, scan detection, and PCAP investigation patterns
NIDS, Snort modes, and detection technique fundamentals
Why four years on a Korean securities trading desk maps to Tier 1 SOC work
Disk forensics misses the stuff that matters most. Fileless malware, running processes, C2 connections, encryption keys, hidden rootkits, these live in RAM and disappear the moment the system powers off. This post covers memory forensics with Volatility, the de facto tool for analyzing memory dumps.
Modern attackers know disk forensics exists. They adapt.
If you're only doing disk forensics, you're missing half the picture.
| Artifact | Forensic Value |
| Processes & Threads | Active/hidden programs, parent-child relationships, injection |
| Network Connections | C2 communication, lateral movement, exfiltration |
| Loaded Modules (DLLs) | Malicious code injection, rootkit drivers |
| Registry Keys | Persistence mechanisms, system config |
| File System (MFT) | File creation/deletion/modification timeline |
| Malware Binaries | Extractable for reverse engineering |
| Command History | What the attacker actually typed |
| Clipboard & Screenshots | What was visible on the screen |
| Credentials & Keys | Plaintext passwords, SSL keys |
Volatility is the primary open-source framework for memory forensics.
| Aspect | Volatility 2 | Volatility 3 |
| Python | Python 2 | Python 3 |
| Profile | Required (--profile=Win7SP1x64) | Auto-detected via symbol tables |
| Plugin naming | Generic (pslist) | OS-specific (windows.pslist) |
| Maturity | Full plugin library | Still porting plugins |
| Command | vol.py -f dump.mem --profile=X plugin | python3 vol.py -f dump.mem windows.plugin |
Vol2 has more plugins but is dying. Vol3 is the future. Most blue teamers still use Vol2 because the plugins they need haven't been ported yet.
Standalone Windows GUI for Vol3. No Python install needed. Useful when you want to avoid command-line friction.
The first thing you check in any memory dump is the process list.
# Volatility 2
vol.py -f dump.mem --profile=Win7SP1x64 pslist
# Volatility 3
python3 vol.py -f dump.mem windows.pslist
pslist enumerates processes from PsActiveProcessHead. Key fields: PID, PPID, start/exit time, session, Wow64 flag.
vol.py -f dump.mem --profile=Win7SP1x64 pstree
pstree shows the parent-child relationships. This is where you catch anomalies:
cmd.exe spawned by winword.exe → someone opened a malicious docpowershell.exe spawned by excel.exe → macro executionlsass.exe with unexpected child processes → credential dumpingAttackers hide processes by unlinking them from PsActiveProcessHead. Standard tools can't see them. Volatility can.
# Scan raw memory for process structures
vol.py -f dump.mem --profile=Win7SP1x64 psscan
# Cross-reference 7 different enumeration methods
vol.py -f dump.mem --profile=Win7SP1x64 psxview
psxview is the killer. It shows a process across seven different views: pslist, psscan, thrdproc, pspcid, csrss, session, deskthrd. A process that shows False in pslist but True in psscan is a strong indicator of rootkit activity.
Singleton violations: core Windows processes should only have one instance:
lsass.exe, one instance onlyservices.exe, one instance onlywininit.exe, one instance onlycsrss.exe, one per sessionDuplicates suggest malware impersonation.
Suspicious paths: legitimate Windows processes run from specific locations:
lsass.exe must be in C:\Windows\System32\C:\Users\Public\, not C:\Temp\Code injection: use malfind to detect injected code:
vol.py -f dump.mem --profile=Win7SP1x64 malfind
Look for:
PAGE_EXECUTE_READWRITE memory regions (should be rare in normal processes)MZ headers in process memory outside the main executable (injected PE)The netscan plugin scans for pool tags (TcpL, TcpE, UdpA) to extract connection data.
vol.py -f dump.mem --profile=Win7SP1x64 netscan
You get:
What to look for:
This is how you trace C2 servers and lateral movement.
Most persistence techniques leave registry traces. Even for memory-only malware, the "how does it come back after reboot" question usually has a registry answer.
Use printkey to inspect specific keys:
vol.py -f dump.mem --profile=Win7SP1x64 printkey -K "SOFTWARE\Microsoft\Windows\CurrentVersion\Run"
Common persistence keys to check:
SOFTWARE\Microsoft\Windows\CurrentVersion\Run, Run keysSOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce, RunOnce keysSYSTEM\CurrentControlSet\Services, Service persistenceSOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache, Scheduled tasksSOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon, Userinit, Shell hijackingAppInit_DLLs, loads malicious DLLs into every process linking User32.dllCompare against a known-clean baseline to spot malicious additions.
The NTFS $MFT is cached in memory. Volatility can parse it to get file activity without examining the disk.
# Scan for file objects
vol.py -f dump.mem --profile=Win7SP1x64 filescan
# Extract files from memory
vol.py -f dump.mem --profile=Win7SP1x64 dumpfiles -n --dump-dir=./extracted/
# Parse MFT entries
vol.py -f dump.mem --profile=Win7SP1x64 mftparser
This gives you file names, timestamps, paths, deletion status, without touching the disk.
Even without a memory dump, you might find memory remnants in these files:
| Source | Description |
| pagefile.sys | Paged-out RAM data; may contain forensic remnants |
| hiberfil.sys | Full RAM snapshot from hibernation; great for dead acquisition |
| MEMORY.DMP | Created during BSOD; partial memory content |
Volatility can analyze hiberfil.sys directly, no need to convert it first.
imageinfo # Identify OS profile (Vol2)
kdbgscan # Scan for KDBG signatures
pslist # List processes
pstree # Process tree
psscan # Scan for hidden processes
psxview # Cross-view detection
cmdline -p PID # Command-line args
procdump -p PID # Dump process executable
netscan # Active/closed connections (Win7+)
connections # Active connections (WinXP/2003)
connscan # Connection scan (legacy)
malfind # Detect injected code
ssdt # SSDT hooks (rootkit detection)
modules # Loaded kernel modules
modscan # Scan for hidden modules
moddump # Dump kernel driver to disk
printkey -K "path" # Print registry key values
hivelist # List registry hives
filescan # Scan for file objects
dumpfiles -n --dump-dir=./ # Extract files
mftparser # Parse MFT entries
timeliner # Build chronological timeline
iehistory # IE browsing history
cmdscan # Command history (CMD)
consoles # Console contents
Memory forensics rewards the analyst who pauses to ask better questions, not the analyst who runs every plugin. The mindset shift is from "what tool do I run next?" to "what am I trying to confirm or rule out?"
The questions I returned to repeatedly:
"Why is psscan showing a process that pslist isn't?": that gap is the entire point of memory forensics. A process can be hidden from the active list but still resident in memory. The instinct: when two views disagree, follow the disagreement.
"What's the parent of this suspicious child process?": if cmd.exe spawned powershell.exe, that's banal. If outlook.exe spawned cmd.exe, that's a phishing chain. Process tree context turns a single process into a story.
"What did this process touch?": cmdline shows arguments. handles shows files and registry keys. netscan shows network connections. The process is the protagonist; everything around it is supporting evidence.
"What happened immediately before the dump was taken?": memory captures a single moment. What was the user doing? Was a known incident triggering the acquisition? The memory dump alone tells you what's running. The context around the dump tells you why it matters.
"What would I miss by closing this investigation here?": the 30-second pause before declaring an investigation done is where senior analysts catch what junior analysts miss. The plugins won't tell you when to stop; the plugins always run more.
The plugins below are the tools. The questions above are the discipline. Mastering the plugins without the questions produces an analyst who runs commands; mastering both produces an analyst who investigates.
Here's the order I typically run Volatility plugins:
1. imageinfo # Identify profile
2. pslist # Baseline processes
3. pstree # Parent-child anomalies
4. psscan # Hidden processes
5. psxview # Cross-view detection
6. netscan # Network connections
7. cmdline # Suspicious command-line args
8. malfind # Code injection
9. printkey # Persistence keys
10. filescan + dumpfiles # Suspicious files
11. procdump # Extract malicious process
12. strings on dumps # Find IOCs (URLs, IPs, keys)
Anomalies flag the targets for deeper investigation. Dump and analyze.
When you find something suspicious in memory:
procdump -p <PID> --dump-dir=./strings -a <dumped_file> (look for URLs, IPs, credentials)PAGE_EXECUTE_READWRITE + MZhiberfil.sys and pagefile.sys