Memory Acquisition
A RAM image captured at the right moment contains the most complete picture of a live attack — decrypted C2 communications, injected shellcode, in-memory credentials, active network connections, and every running process. This chapter covers acquisition tools, formats, verification, and what you're capturing when you image memory.
An alert fires: a process on a critical server is making outbound connections to an unusual IP on port 443. The EDR identifies it as potential Cobalt Strike beacon activity. The malware may be entirely in memory — no files on disk. If you reboot to avoid disruption, everything in RAM is gone. If you isolate via EDR first and then take a memory image, the network state is preserved but the active connections are closed. The right sequence: (1) take live process/network snapshot via a 2-minute script, (2) immediately acquire RAM image while the beacon is still running, (3) then isolate via EDR. The memory image captures the decrypted config, the C2 IP, and the injected code — evidence you can't get from disk forensics alone.
What's in RAM: The Forensic Goldmine
Evidence Available Only in Memory
═══════════════════════════════════════════════════════════════════
Processes and threads:
├── Every running process with its full in-memory image
├── Processes injected into (hollowed or injected code visible)
├── Terminated processes (may still have memory mapped)
└── Process handles (what files/registry keys are open)
Network state:
├── Active TCP connections with remote IPs
├── Listening ports
├── Recently closed connections (cached in TCB)
└── Sockets and their associated process PIDs
Credentials:
├── LSASS process memory: NTLM hashes, Kerberos tickets, cleartext (if WDigest enabled)
├── Browser credential caches
├── VPN/Wi-Fi saved credentials
└── Application session tokens (cookies, JWTs) in process heap
Decrypted content:
├── Malware config (C2 domains, encryption keys — decrypted at runtime)
├── Ransomware encryption keys (before files are encrypted)
├── Browser HTTPS session data (SSL/TLS keys stored in NSS3 structures)
└── Any data the process decrypted to work with
Injected code:
├── Shellcode injected into legitimate processes
├── Reflective DLL injections
└── Process hollowing payloads (visible as PE in unexpected memory)
Acquisition Tools
| Tool | Platform | Output format | Notes |
|---|---|---|---|
| WinPmem | Windows | Raw or AFF4 | Open source, part of Velociraptor DFIR toolkit. Standalone EXE, no install. Most commonly used in professional IR. |
| Magnet RAM Capture | Windows | .mem (raw) | Free, GUI tool from Magnet Forensics. Good for field acquisition by non-technical first responders. |
| DumpIt (Comae) | Windows | .bin or .dmp | Minimal UI — double-click and it images RAM. Renamed to Comae DumpIt. Raw output compatible with Volatility. |
| avml | Linux | LIME format or raw | Microsoft's open-source Linux memory acquisition tool. No kernel module required — works without LiME. |
| LiME (Linux Memory Extractor) | Linux | LIME format | Loadable kernel module. Most reliable on Linux but requires kernel module loading. Gold standard for Linux memory forensics. |
| osxpmem | macOS | AFF4 or raw | macOS memory acquisition. Kernel extension required (getting harder with SIP). macOS forensics is increasingly cloud-log-dependent. |
# WinPmem memory acquisition
# Run from USB or network share — don't write to the target system's disk
param(
[string]$OutputDrive = "D:",
[string]$CaseName = "CASE001"
)
$hostname = $env:COMPUTERNAME
$timestamp = Get-Date -Format "yyyyMMdd-HHmmss"
$outDir = "$OutputDrive\evidence\$CaseName\$hostname"
$ramFile = "$outDir\$hostname-RAM-$timestamp.raw"
$winpmem = "D:\tools\winpmem_mini_x64_rc2.exe"
New-Item -ItemType Directory -Path $outDir -Force | Out-Null
# Pre-acquisition: capture volatile state FIRST
Write-Host "[*] Capturing live process list..."
Get-WmiObject Win32_Process |
Select-Object ProcessId, Name, CommandLine, ParentProcessId |
Export-Csv "$outDir\processes-live.csv" -NoTypeInformation
Write-Host "[*] Capturing network connections..."
netstat -anob 2>&1 | Out-File "$outDir\netstat-live.txt"
# RAM acquisition
Write-Host "[*] Starting RAM acquisition to $ramFile"
Write-Host "[*] Estimated time: $([Math]::Ceiling((Get-WmiObject Win32_ComputerSystem).TotalPhysicalMemory / 1GB * 3)) minutes"
$start = Get-Date
& $winpmem $ramFile
$elapsed = (Get-Date) - $start
Write-Host "[*] Acquisition complete in $($elapsed.TotalMinutes.ToString('0.0')) minutes"
# Hash verification
$hash = Get-FileHash -Path $ramFile -Algorithm SHA256
Write-Host "[*] SHA-256: $($hash.Hash)"
Write-Host "[*] Size: $('{0:N2}' -f ((Get-Item $ramFile).Length / 1GB)) GB"
# Record in chain of custody
[PSCustomObject]@{
Timestamp = (Get-Date -Format "yyyy-MM-dd HH:mm:ss UTC")
Investigator= $env:USERNAME
Host = $hostname
Action = "RAM acquisition"
File = $ramFile
SHA256 = $hash.Hash
SizeGB = (Get-Item $ramFile).Length / 1GB
} | Export-Csv "$outDir\chain-of-custody.csv" -Append -NoTypeInformation
Linux Memory Acquisition
# Linux memory acquisition with avml (no kernel module needed)
# Download: https://github.com/microsoft/avml/releases
# Install avml
curl -Lo /usr/local/bin/avml \
https://github.com/microsoft/avml/releases/latest/download/avml
chmod +x /usr/local/bin/avml
# Acquire to evidence drive
HOSTNAME=$(hostname)
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
OUTPUT="/mnt/evidence/${HOSTNAME}-RAM-${TIMESTAMP}.lime"
avml $OUTPUT
# Hash and document
sha256sum $OUTPUT | tee "${OUTPUT}.sha256"
echo "Memory acquisition complete:"
echo " File: $OUTPUT"
echo " Size: $(du -sh $OUTPUT | cut -f1)"
echo " Hash: $(cat ${OUTPUT}.sha256 | cut -d' ' -f1)"
# Alternative: LiME (requires kernel module)
# insmod lime-$(uname -r).ko "path=/mnt/evidence/mem.lime format=lime"
# The module cleans up on rmmod; format=raw also supported
Windows Crash Dumps as Memory Sources
Windows crash dumps (minidump, kernel dump, full dump) are memory images created automatically when the system encounters a BSOD. They can be analyzed with Volatility like any other memory image.
| Dump type | Location | Contents | Forensic usefulness |
|---|---|---|---|
| Full memory dump | C:\Windows\MEMORY.DMP | Complete physical RAM contents | Equivalent to WinPmem acquisition — contains everything |
| Kernel memory dump | C:\Windows\MEMORY.DMP (default) | Kernel space only — not user space | Useful for kernel-mode rootkit analysis; misses user-space credential stores |
| Automatic memory dump | C:\Windows\MEMORY.DMP | Kernel + minimal pages needed for analysis | Varies — may miss critical user-space content |
| Minidump | C:\Windows\Minidump\*.dmp | Stack trace + very limited RAM | Not useful for memory forensics — only for crash debugging |
Q & A
Q: Can you analyze memory from a virtual machine without a WinPmem-style acquisition?
Yes — hypervisors provide memory acquisition mechanisms that often give better results than in-guest tools. For VMware: the .vmem file in the VM's directory on the host is a raw memory dump of the running VM — copy it (while the VM is suspended or with atomic snapshot) and analyze directly with Volatility. For VMware, also copy the .vmss (suspend state) file — Volatility has a VMware VMSS reader. For Hyper-V: use the CheckpointVM PowerShell command to create a checkpoint (includes memory state) then export the VMRS file. For VirtualBox: take a snapshot — the .sav file contains memory. For cloud VMs (AWS/Azure): check if the hypervisor supports memory capture via the management API before trying in-guest acquisition. In-guest acquisition tools like WinPmem work correctly inside VMs, but hypervisor-level capture is "outside looking in" and is less susceptible to rootkit interference with the acquisition process.