1. Volatile Memory in Incident Response & Threat Hunting
Modern advanced threat groups and sophisticated ransomware cartels actively employ fileless execution, living-off-the-land techniques, and in-memory payload staging. These techniques leave zero persistent artifacts on physical disk storage. When responding to advanced intrusions, volatile memory (RAM) is the ultimate source of truth, containing decrypted command strings, active network sockets, injected shellcode, unhooked API pointers, and transient cryptographic keys.
Memory analysis requires understanding Windows kernel architectures, executive objects, and the forensic tools necessary to reconstruct operational state from raw physical address dumps.
2. Windows Kernel Internals: Executive Process Blocks & VAD Trees
Every running user-mode process in Windows is represented in kernel space by an EPROCESS (Executive Process) structure. Understanding two core kernel primitives is mandatory for memory forensics:
A. The ActiveProcessLinks Doubly-Linked List
The EPROCESS structure contains an ActiveProcessLinks field of type LIST_ENTRY. This circular doubly-linked list connects all running processes. Standard Windows administrative utilities (Task Manager, tasklist.exe) enumerate processes by traversing this list.
Adversaries utilize Direct Kernel Object Manipulation (DKOM) to unhook a malicious process’s ActiveProcessLinks (pointing the previous node’s forward pointer to the next node). This completely hides the process from Task Manager and API-based EDR hooks. However, the thread structures (ETHREAD) and memory manager allocations remain resident in memory, allowing pool-tag scanners to discover the hidden process.
B. The Virtual Address Descriptor (VAD) Tree
The Windows Virtual Memory Manager maintains a self-balancing binary search tree (AVL tree) called the VAD tree for every process. The VAD tree tracks all allocated virtual memory regions, memory protections (PAGE_READWRITE, PAGE_EXECUTE_READWRITE), and whether a region is memory-mapped to a file on disk or committed in private memory.
+-------------------------------------------------------------+
| Windows Process Memory Layout |
| |
| Virtual Memory Space |
| +-----------------------+ <--- High Memory (0x7FFFFFFF) |
| | Loaded DLLs (ntdll) | [Mapped File: PAGE_EXECUTE_READ]|
| +-----------------------+ |
| | | |
| | Injected Shellcode | [Private: PAGE_EXECUTE_READWRITE| <-- [ANOMALY!]
| | (Malfind Hit) | Unmapped, RWX Permissions] |
| +-----------------------+ |
| | PE Header / Main Code | [Mapped File: svchost.exe] |
| +-----------------------+ <--- Low Memory (0x00010000) |
+-------------------------------------------------------------+
3. Deep Dive: Process Hollowing & In-Memory Injection
Process Hollowing (T1055.012) is a stealth evasion technique where an attacker starts a legitimate, signed Windows process in a suspended state, unmaps its legitimate code, and replaces it with malicious executable payload:
- Process Creation: Spawns a legitimate binary (e.g.,
svchost.exeorcalc.exe) with theCREATE_SUSPENDEDflag viaCreateProcessW(). - Unmapping Legitimate Sections: Invokes
NtUnmapViewOfSection()to release the virtual address space containing the legitimate application’s code. - Memory Allocation & Injection: Allocates executable memory in the remote suspended process via
VirtualAllocEx()withPAGE_EXECUTE_READWRITEpermissions, and copies the malicious PE payload usingWriteProcessMemory(). - Context Hijacking & Execution: Queries the thread state with
GetThreadContext(), modifies the instruction pointer (RIPon x64,EIPon x86) to point to the newly injected entry point, and callsResumeThread().
4. Investigating In-Memory Intrusions with Volatility 3
Volatility 3 is the industry-standard memory forensics framework. When analyzing a raw memory capture (acquired via LiME, DumpIt, or FTK Imager), investigators execute specialized plugins to detect hidden processes and in-memory injection:
A. Detecting DKOM Process Hiding
# 1. Standard process list (traverses ActiveProcessLinks)
python vol.py -f memory.raw windows.pslist
# 2. Kernel pool tag scanner (scans unallocated pool memory for EPROCESS blocks)
python vol.py -f memory.raw windows.psscan
Comparing the outputs of windows.pslist and windows.psscan instantly reveals hidden processes: any PID appearing in psscan but absent from pslist has been hidden using DKOM.
B. Identifying Injected Shellcode with Malfind
The windows.malfind plugin inspects VAD trees across all processes to detect memory segments that are allocated as private, carry executable permissions (PAGE_EXECUTE_READWRITE), and contain binary headers or shellcode:
python vol.py -f memory.raw windows.malfind --pid 1420
A typical malicious finding displays an unmapped memory segment starting with 4D 5A (the MZ DOS header) or shellcode NOP sleds (90 90 90) inside what appears to be a legitimate host process.
5. Python Memory Triage Automation
The following Python script automates the triage of Volatility 3 JSON output to detect suspicious process parentage and unauthorized executable memory allocations.
# Automated Volatility 3 Triage Parser
import json
def audit_memory_triage(pslist_json_path: str, malfind_json_path: str):
print("[*] Commencing Automated Memory Triage...")
with open(pslist_json_path, "r") as f:
pslist = json.load(f)
with open(malfind_json_path, "r") as f:
malfind = json.load(f)
# 1. Build Process Map
processes = {p["PID"]: p for p in pslist}
# 2. Audit PPID Invariants (e.g. svchost must only be spawned by services.exe)
for pid, proc in processes.items():
image_name = proc.get("ImageFileName", "").lower()
ppid = proc.get("PPID", 0)
parent = processes.get(ppid, {})
parent_name = parent.get("ImageFileName", "UNKNOWN").lower()
if image_name == "svchost.exe" and parent_name != "services.exe":
print(f"[!] ANOMALY: Rogue svchost.exe (PID: {pid}) spawned by invalid parent: {parent_name} (PPID: {ppid})")
if image_name == "lsass.exe" and parent_name != "wininit.exe":
print(f"[!] CRITICAL: Rogue lsass.exe (PID: {pid}) spawned by: {parent_name} (PPID: {ppid})")
# 3. Correlate Malfind Injections
injected_pids = set()
for hit in malfind:
pid = hit.get("PID")
injected_pids.add(pid)
print(f"[!] INJECTION DETECTED: PID {pid} ({hit.get('Process')}) at base {hex(hit.get('StartVPN', 0))}")
print(f"[*] Memory Triage Complete: {len(injected_pids)} processes flagged with injected memory.")
if __name__ == "__main__":
print("[*] Volatility Memory Automation Engine initialized.")
6. Incident Response & Remediation Playbook
- Preserve Memory Before Disconnecting or Re-booting: Never reboot an infected endpoint before memory acquisition. Power cycling completely destroys volatile memory evidence and unencrypted ransomware keys.
- Enforce Driver Blocklists: Prevent kernel DKOM attacks by enforcing Microsoft Vulnerable and Malicious Driver Blocklist (HVCI – Hypervisor-Protected Code Integrity).
- Implement EDR with Kernel Telemetry: Deploy EDR solutions that monitor ETW-Ti (Event Tracing for Windows – Threat Intelligence) to intercept
VirtualAllocExandWriteProcessMemorycalls across process boundaries in real time.
Threat Hunting & Strategic Attribution Playbook
Converting forensic findings into actionable threat intelligence requires rigorous adherence to intelligence analysis standards:
- Diamond Model Activity Threading: Correlate the observed adversary capability (malware, exploits) and infrastructure (C2 domains, IP blocks, JARM hashes) against known threat actor profiles in MITRE ATT&CK. Establish analytical confidence using the Admiralty Code.
- Passive DNS & Infrastructure Pivoting: Query historical passive DNS (pDNS) repositories to map the attacker’s broader hosting topology. Identify SSL/TLS certificate reuse, common WHOIS registrant attributes, and co-located command servers.
- Defensive Engineering via MITRE D3FEND: Map identified adversary TTPs to corresponding D3FEND defensive countermeasures. Deploy canary credentials, harden process execution policies, and implement network micro-segmentation to permanently deny the threat actor operational access.
- Automated STIX/TAXII Threat Sharing: Package validated threat intelligence into standardized STIX 2.1 JSON bundles. Automate TAXII feed publication to SIEM, SOAR, and perimeter firewall blocklists for automated threat neutralization.
Test exploit payloads & solve 25+ live CTF challenges.
AI & Deep Learning StudioInteractive gradient descent, neural nets & LLM guardrails.
Online Code LabExecute Python, C++, Rust, and Java in your browser.
Threat IntelligenceLive CISA vulnerability advisories & hacker news feed.
