Memory Forensics with Volatility
Acquire and analyze RAM dumps to detect active malware, injected code, hidden processes, network connections, encryption keys, and attacker artifacts using Volatility 3.
Learning Objectives
- → Acquire a memory dump from a live Windows system
- → List processes, network connections, and loaded modules with Volatility
- → Detect process injection by comparing VAD and PE headers
- → Carve files and extract artifacts from memory
- → Identify rootkit hiding techniques: DKOM, SSDT hooks
Why Memory Forensics?
Memory contains what disk cannot:
- Running processes (including fileless malware — no disk artifact)
- Network connections active at time of capture
- Decrypted data (ransomware before encryption completes)
- Passwords and encryption keys in memory
- Registry hives loaded in RAM
- Recently accessed files (even deleted ones)
- Process injection artifacts
- Evidence of rootkits hiding from OS
Memory is volatile — power off destroys it!
Capture BEFORE rebooting or shutting down.
Memory Acquisition
# Windows — tools for live capture:
# 1. WinPmem (free, open source):
winpmem.exe -o memory.raw
# Or: winpmem.exe -o memory.dmp --format raw
# 2. Magnet RAM Capture (free GUI):
# https://www.magnetforensics.com/resources/magnet-ram-capture/
# 3. DumpIt:
DumpIt.exe
# 4. via Meterpreter (post-exploitation):
meterpreter > run post/windows/manage/multi_meterpreter_inject
# Or: meterpreter > download C:\Windows\pagefile.sys
# Note: pagefile.sys is NOT a full RAM dump
# Linux live capture:
sudo dd if=/dev/mem of=memory.raw bs=1M
# Or: LiME module:
sudo insmod lime.ko "path=/tmp/memory.raw format=raw"
# Virtual machine memory:
# VMware: suspend VM → find .vmem file
# VirtualBox: take snapshot → find .sav file
# Both are directly usable with Volatility
Volatility 3 Setup
# Install Volatility 3:
git clone https://github.com/volatilityfoundation/volatility3
cd volatility3
pip3 install -r requirements.txt
# Run:
python3 vol.py -f memory.raw windows.info
# -f: memory dump file
# Auto-detects OS profile (Volatility 3 doesn't need profile specification)
# For Windows NT-10, Linux, macOS
# Volatility 2 (legacy, still used):
volatility -f memory.raw --profile=Win10x64_18362 imageinfo
Core Plugins: Process Analysis
# List all processes (from process list — rootkits can hide here):
python3 vol.py -f memory.raw windows.pslist
# Process TREE (parent-child relationships):
python3 vol.py -f memory.raw windows.pstree
# Look for: cmd.exe child of Word.exe (malicious macro)
# powershell.exe child of svchost.exe (suspicious)
# unusual parent-child combinations
# Process scan (from pool tags — finds hidden processes):
python3 vol.py -f memory.raw windows.psscan
# Compare pslist vs psscan: processes in psscan but NOT pslist = HIDDEN (rootkit!)
# Dump a specific process memory:
python3 vol.py -f memory.raw windows.memmap --pid 1234 --dump
# DLL list for a process (loaded modules):
python3 vol.py -f memory.raw windows.dlllist --pid 1234
# Unusual DLL paths (temp folder, no version info) = suspicious
# Handles (open files, registry keys, mutexes):
python3 vol.py -f memory.raw windows.handles --pid 1234
Network Connections
# Active network connections:
python3 vol.py -f memory.raw windows.netscan
# Shows: PID, process, local addr, remote addr, state, time
# Look for:
# - Unusual processes with network connections (calc.exe → network?)
# - Connections to known malicious IPs
# - C2 beaconing (repeated connections to same external IP)
# - Suspicious ports (4444, 1337, 8888 = common C2 ports)
# netstat comparison:
python3 vol.py -f memory.raw windows.netstat
# Historical connections (including recently closed)
Detecting Process Injection
malfind Plugin
# malfind: finds memory regions with suspicious characteristics
# - Executable permission (PAGE_EXECUTE_READWRITE)
# - No mapped file (memory-only — injected code)
# - Header looks like PE (MZ at start)
python3 vol.py -f memory.raw windows.malfind
# Output shows: PID, process, address, protection, MZ header bytes
# Dump suspicious regions:
python3 vol.py -f memory.raw windows.malfind --dump
# Analyze dumped regions:
file pid.1234.0x400000.dmp # file type
strings pid.1234.0x400000.dmp # strings in injected code
yara malware_rules.yar pid.1234.0x400000.dmp # YARA scan
# Common injection techniques detected by malfind:
# - Shellcode injection (no PE header, just shellcode)
# - Process hollowing (legitimate process with replaced code)
# - DLL injection (PE header with suspicious DLL)
# - Reflective DLL injection
VAD (Virtual Address Descriptor) Analysis
# VAD: describes virtual memory regions for each process
# Compare VAD permissions vs PE headers for anomalies
python3 vol.py -f memory.raw windows.vadinfo --pid 1234
# Look for: Executable + no file path = suspicious injected code
python3 vol.py -f memory.raw windows.vadwalk --pid 1234
# Walk VAD tree
# Process hollowing detection:
# Legitimate process (svchost.exe) starts
# Real code replaced with malware code in memory
# PE header in memory doesn't match file on disk
# Detection: compare PEB ImageBaseAddress code with disk version
File and Registry Carving
# Files cached in memory (file objects):
python3 vol.py -f memory.raw windows.filescan
# Find specific file:
python3 vol.py -f memory.raw windows.filescan | grep -i ".pdf\|.docx\|.exe"
# Dump file from memory:
python3 vol.py -f memory.raw windows.dumpfiles --virtaddr 0xffff...
# Registry hives in memory:
python3 vol.py -f memory.raw windows.registry.hivelist
# Dump registry hive:
python3 vol.py -f memory.raw windows.registry.printkey --key "Software\Microsoft\Windows\CurrentVersion\Run"
# Password extraction (lsass.exe memory):
python3 vol.py -f memory.raw windows.hashdump
# SAM NTLM hashes — crack offline
python3 vol.py -f memory.raw windows.lsadump
# LSA secrets — service account passwords
Rootkit Detection
# DKOM (Direct Kernel Object Manipulation):
# Rootkit unlinks process from process list → pslist misses it
# psscan finds it (scans physical memory for pool tags)
# Compare pslist and psscan:
python3 vol.py -f memory.raw windows.pslist > pslist.txt
python3 vol.py -f memory.raw windows.psscan > psscan.txt
diff pslist.txt psscan.txt
# Processes in psscan but not pslist = HIDDEN by rootkit!
# SSDT hooks (System Service Descriptor Table):
# Rootkit replaces function pointers in SSDT to hide files/processes/registry
python3 vol.py -f memory.raw windows.ssdt
# Look for: addresses pointing outside ntoskrnl.exe (hooked by rootkit!)
# Kernel modules:
python3 vol.py -f memory.raw windows.modules
python3 vol.py -f memory.raw windows.modscan
# modscan vs modules: hidden kernel modules (rootkit drivers)
Memory Forensics Workflow
Incident Response Memory Analysis:
1. Capture memory (before rebooting!)
2. windows.info → confirm OS version
3. windows.pstree → suspicious process trees?
4. windows.netscan → suspicious connections?
5. windows.malfind → injected code?
6. windows.pslist vs psscan → hidden processes?
7. windows.cmdline → command lines of suspicious PIDs?
8. windows.filescan → dropped malware files?
9. windows.hashdump → extract credentials
10. windows.timeliner → timeline of events
Analyze a memory dump (use a sample from MemLabs: github.com/stuxnet999/MemLabs — free forensic challenges): (1) python3 vol.py -f mem.raw windows.info (confirm OS), (2) windows.pstree → note unusual parent-child relationships, (3) windows.netscan → identify external connections, (4) windows.cmdline → check command lines of suspicious processes, (5) windows.dlllist for suspicious process → note unusual DLL paths.
Why is seeing cmd.exe as a child of winword.exe suspicious?
What does windows.cmdline reveal that pslist does not?
Detect process injection in a memory dump: (1) run windows.malfind on a suspicious memory image, (2) identify regions with PAGE_EXECUTE_READWRITE + no file path, (3) dump the suspicious memory region, (4) run 'file' and 'strings' on the dump to identify injected payload type, (5) run YARA rules against the dumped region to identify malware family, (6) check what process was injected into (PID and process name).
Why is PAGE_EXECUTE_READWRITE permission suspicious in a memory region?
Extract credentials and detect rootkits: (1) windows.hashdump to extract NTLM hashes, (2) save hashes and crack with hashcat -m 1000, (3) compare windows.pslist and windows.psscan — are any PIDs in psscan but missing from pslist? (4) run windows.ssdt and look for function pointers outside ntoskrnl.exe range, (5) compare windows.modules and windows.modscan for hidden kernel modules.
Why does psscan detect processes that pslist misses?