performing-memory-forensics-with-volatility3-plugins
Analyze memory dumps using Volatility3 plugins to detect injected code, rootkits, credential theft, and malware artifacts in Windows, Linux, and macOS memory images.
What this skill does
# Performing Memory Forensics with Volatility3 Plugins
## Overview
Volatility3 (v2.26.0+, feature parity release May 2025) is the standard framework for memory forensics, replacing the deprecated Volatility2. It analyzes RAM dumps from Windows, Linux, and macOS to detect malicious processes, code injection, rootkits, credential harvesting, and network connections that disk-based forensics cannot reveal. Key plugins include `windows.malfind` (detecting RWX memory regions indicating injection), `windows.psscan` (finding hidden processes), `windows.dlllist` (enumerating loaded modules), `windows.netscan` (active network connections), and `windows.handles` (open file/registry handles). The 2024 Plugin Contest introduced ETW Scan for extracting Event Tracing for Windows data from memory.
## When to Use
- When conducting security assessments that involve performing memory forensics with volatility3 plugins
- When following incident response procedures for related security events
- When performing scheduled security testing or auditing activities
- When validating security controls through hands-on testing
## Prerequisites
- Python 3.9+ with `volatility3` framework installed
- Memory dump files (`.raw`, `.dmp`, `.vmem`, `.lime`)
- Windows symbol tables (ISF files, auto-downloaded)
- Understanding of Windows process memory architecture
- YARA integration for in-memory pattern scanning
## Workflow
### Step 1: Process Analysis for Malware Detection
```python
#!/usr/bin/env python3
"""Volatility3-based memory forensics automation for malware analysis."""
import subprocess
import json
import sys
import os
class Vol3Analyzer:
"""Automate Volatility3 plugin execution for malware analysis."""
def __init__(self, dump_path, vol3_path="vol"):
self.dump_path = dump_path
self.vol3 = vol3_path
self.results = {}
def run_plugin(self, plugin, extra_args=None):
"""Execute a Volatility3 plugin and capture output."""
cmd = [
self.vol3, "-f", self.dump_path,
"-r", "json", plugin,
]
if extra_args:
cmd.extend(extra_args)
try:
result = subprocess.run(
cmd, capture_output=True, text=True, timeout=300
)
if result.returncode == 0:
return json.loads(result.stdout)
except (subprocess.TimeoutExpired, json.JSONDecodeError) as e:
print(f" [!] {plugin} failed: {e}")
return None
def detect_process_injection(self):
"""Use malfind to detect injected code regions."""
print("[+] Running windows.malfind (code injection detection)")
results = self.run_plugin("windows.malfind")
injected = []
if results:
for entry in results:
injected.append({
"pid": entry.get("PID"),
"process": entry.get("Process"),
"address": entry.get("Start VPN"),
"protection": entry.get("Protection"),
"hexdump": entry.get("Hexdump", "")[:200],
})
print(f" [!] Injection in PID {entry.get('PID')} "
f"({entry.get('Process')}) at {entry.get('Start VPN')}")
self.results["injected_processes"] = injected
return injected
def find_hidden_processes(self):
"""Compare pslist vs psscan to find hidden processes."""
print("[+] Running process comparison (pslist vs psscan)")
pslist = self.run_plugin("windows.pslist")
psscan = self.run_plugin("windows.psscan")
if not pslist or not psscan:
return []
list_pids = {e.get("PID") for e in pslist}
scan_pids = {e.get("PID") for e in psscan}
hidden = scan_pids - list_pids
if hidden:
print(f" [!] {len(hidden)} hidden processes found!")
for entry in psscan:
if entry.get("PID") in hidden:
print(f" PID {entry['PID']}: {entry.get('ImageFileName')}")
self.results["hidden_processes"] = list(hidden)
return list(hidden)
def analyze_network(self):
"""Extract active network connections."""
print("[+] Running windows.netscan")
results = self.run_plugin("windows.netscan")
connections = []
if results:
for entry in results:
conn = {
"pid": entry.get("PID"),
"process": entry.get("Owner"),
"local": f"{entry.get('LocalAddr')}:{entry.get('LocalPort')}",
"remote": f"{entry.get('ForeignAddr')}:{entry.get('ForeignPort')}",
"state": entry.get("State"),
"protocol": entry.get("Proto"),
}
connections.append(conn)
self.results["network_connections"] = connections
return connections
def extract_dlls(self, pid=None):
"""List loaded DLLs per process."""
print(f"[+] Running windows.dlllist{f' (PID {pid})' if pid else ''}")
args = ["--pid", str(pid)] if pid else None
results = self.run_plugin("windows.dlllist", args)
dlls = []
if results:
for entry in results:
dlls.append({
"pid": entry.get("PID"),
"process": entry.get("Process"),
"base": entry.get("Base"),
"name": entry.get("Name"),
"path": entry.get("Path"),
"size": entry.get("Size"),
})
self.results["loaded_dlls"] = dlls
return dlls
def scan_with_yara(self, rules_path):
"""Scan memory with YARA rules."""
print(f"[+] Running windows.yarascan with {rules_path}")
results = self.run_plugin(
"windows.yarascan",
["--yara-file", rules_path]
)
matches = []
if results:
for entry in results:
matches.append({
"rule": entry.get("Rule"),
"pid": entry.get("PID"),
"process": entry.get("Process"),
"offset": entry.get("Offset"),
})
self.results["yara_matches"] = matches
return matches
def full_triage(self):
"""Run full malware-focused memory triage."""
print(f"[*] Full memory triage: {self.dump_path}")
print("=" * 60)
self.detect_process_injection()
self.find_hidden_processes()
self.analyze_network()
return self.results
if __name__ == "__main__":
if len(sys.argv) < 2:
print(f"Usage: {sys.argv[0]} <memory_dump>")
sys.exit(1)
analyzer = Vol3Analyzer(sys.argv[1])
results = analyzer.full_triage()
print(json.dumps(results, indent=2, default=str))
```
## Validation Criteria
- Memory dump successfully parsed with correct OS profile
- Injected processes detected via malfind with RWX regions
- Hidden processes identified through pslist/psscan comparison
- Network connections reveal C2 communication endpoints
- YARA rules match known malware signatures in memory
- Credential artifacts extracted from lsass process memory
## References
- [Volatility Foundation](https://volatilityfoundation.org/)
- [Volatility3 GitHub](https://github.com/volatilityfoundation/volatility3)
- [2024 Volatility Plugin Contest](https://volatilityfoundation.org/the-2024-volatility-plugin-contest-results-are-in/)
- [Memory Forensics with Volatility 3](https://newtonpaul.com/malware-analysis-memory-forensics-with-volatility-3/)
- [MITRE ATT&CK T1055 - Process Injection](https://attack.mitre.org/techniques/T1055/)
Related in General
modeling-omnistudio-epc-catalog
IncludedSalesforce Industries CME EPC product-modeling skill for Product2-based catalog creation. Use when creating EPC products, configuring product attributes, building offer bundles with Product Child Items, or reviewing EPC DataPack JSON metadata for product catalog changes. TRIGGER when: user creates or updates Product2 EPC records, AttributeAssignment payloads, AttributeMetadata/AttributeDefaultValues, Offer bundles, or ProductChildItem relationships. DO NOT TRIGGER when: designing OmniScripts/FlexCards/Integration Procedures (use building-omnistudio-omniscript, building-omnistudio-flexcard, or building-omnistudio-integration-procedure), implementing Apex business logic (use generating-apex), or troubleshooting deployment pipelines (use deploying-metadata).
relationship-science-coach
IncludedUse this skill for direct, practical adult relationship coaching: couples conflict, repair, trust, marriage, dating, flirting, attachment patterns, emotional connection, sex, desire differences, eroticism, kink negotiation, affection, love languages, breakups, and long-term passion. Draw on Gottman, EFT and Hold Me Tight, attachment science, modern sex research, Perel, Nagoski, Kerner, Schnarch, Love and Stosny, and flexible love-language tools. Be concrete and low-hedge. Redirect only for imminent danger, abuse, coercive control, minors, non-consent, self-harm, stalking, or medical/legal/psychiatric decisions.
building-sf-integrations
IncludedSalesforce integration architecture and runtime plumbing with 120-point scoring. Use this skill to set up Named Credentials, External Credentials, External Services, REST/SOAP callout patterns, Platform Events, and Change Data Capture. TRIGGER when: user sets up Named Credentials, External Services, REST/SOAP callouts, Platform Events, CDC, or touches .namedCredential-meta.xml files. DO NOT TRIGGER when: Connected App/OAuth config (use configuring-connected-apps), Apex-only logic (use generating-apex), or data import/export (use handling-sf-data).
venue-templates
IncludedAccess comprehensive LaTeX templates, formatting requirements, and submission guidelines for major scientific publication venues (Nature, Science, PLOS, IEEE, ACM), academic conferences (NeurIPS, ICML, CVPR, CHI), research posters, and grant proposals (NSF, NIH, DOE, DARPA). This skill should be used when preparing manuscripts for journal submission, conference papers, research posters, or grant proposals and need venue-specific formatting requirements and templates.
let-fate-decide
IncludedDraws the 12 Houses of the Zodiac Tarot spread to inject entropy into planning when prompts are vague, ambiguous, or casually delegated. Interprets the spread to guide next steps. Use when the user says 'let fate decide', 'YOLO', 'whatever', 'idk', or other nonchalant phrases, makes Yu-Gi-Oh references, or when you are about to arbitrarily pick between multiple reasonable approaches. Prefer over ask-questions-if-underspecified when the user's tone is casual or playful rather than precision-seeking.
net-ops
IncludedCross-platform network troubleshooting (Windows, macOS, Linux) via local or remote shell. Use for: DNS broken, can't resolve hostnames, nslookup/dig works but apps fail, NRPT, WFP, scutil, /etc/resolver, systemd-resolved, /etc/resolv.conf, NetworkManager, VPN DNS leak residue (ProtonVPN/Mullvad/WireGuard/AnyConnect), AV/firewall blocking DNS or DoH, Tailscale DNS interaction, intermittent connectivity, remote diagnostics over SSH.