Install this skill
npx skills add mukul975/Anthropic-Cybersecurity-SkillsFramework mappings
MITRE ATT&CK
When to Use
- When investigating security incidents that require analyzing memory forensics with lime and volatility
- When building detection rules or threat hunting queries for this domain
- When SOC analysts need structured procedures for this analysis type
- When validating security monitoring coverage for related attack techniques
Prerequisites
- Familiarity with security operations concepts and tools
- Access to a test or lab environment for safe execution
- Python 3.8+ with required dependencies installed
- Appropriate authorization for any testing activities
Instructions
Acquire Linux memory using LiME kernel module, then analyze with Volatility 3 to extract forensic artifacts from the memory image.
# LiME acquisition
insmod lime-$(uname -r).ko "path=/evidence/memory.lime format=lime"
# Volatility 3 analysis
vol3 -f /evidence/memory.lime linux.pslist
vol3 -f /evidence/memory.lime linux.bash
vol3 -f /evidence/memory.lime linux.sockstatimport volatility3
from volatility3.framework import contexts, automagic
from volatility3.plugins.linux import pslist, bash, sockstat
# Programmatic Volatility 3 usage
context = contexts.Context()
automagics = automagic.available(context)Key analysis steps:
- Acquire memory with LiME (format=lime or format=raw)
- List processes with linux.pslist, compare with linux.psscan
- Extract bash command history with linux.bash
- List network connections with linux.sockstat
- Check loaded kernel modules with linux.lsmod for rootkits
Examples
# Full forensic workflow
vol3 -f memory.lime linux.pslist | grep -v "\[kthread\]"
vol3 -f memory.lime linux.bash
vol3 -f memory.lime linux.malfind
vol3 -f memory.lime linux.lsmodSource materials
References and resources
Everything below is rendered for inspection. Script files are read-only and never run.
References 1
api-reference.md1.6 KB
API Reference: Analyzing Memory Forensics with LiME and Volatility
LiME (Linux Memory Extractor)
# Build LiME module
cd LiME/src && make
# Acquire memory (lime format - includes metadata)
insmod lime-$(uname -r).ko "path=/evidence/mem.lime format=lime"
# Acquire memory (raw format)
insmod lime-$(uname -r).ko "path=/evidence/mem.raw format=raw"
# Acquire over network
insmod lime.ko "path=tcp:4444 format=lime"
# On forensic workstation: nc target 4444 > mem.limeVolatility 3 Linux Plugins
| Plugin | Description |
|---|---|
linux.pslist |
List processes via task_struct |
linux.psscan |
Brute-force scan for task_struct |
linux.bash |
Recovered bash command history |
linux.sockstat |
Network connections |
linux.lsmod |
Loaded kernel modules |
linux.malfind |
Detect injected code |
linux.check_afinfo |
Detect network hooking |
linux.tty_check |
Detect TTY hooking |
linux.proc.Maps |
Process memory maps |
Volatility 3 CLI
vol3 -f memory.lime linux.pslist
vol3 -f memory.lime linux.bash
vol3 -f memory.lime linux.sockstat
vol3 -f memory.lime linux.malfind
vol3 -f memory.lime linux.lsmod
vol3 -f memory.lime linux.check_afinfoHidden Process Detection
# Compare pslist (linked list) vs psscan (brute force)
vol3 -f mem.lime linux.pslist > pslist.txt
vol3 -f mem.lime linux.psscan > psscan.txt
diff pslist.txt psscan.txtReferences
- LiME: https://github.com/504ensicsLabs/LiME
- Volatility 3: https://github.com/volatilityfoundation/volatility3
- Volatility 3 docs: https://volatility3.readthedocs.io/
Scripts 1
agent.py7.2 KB
Display-only source. This catalog never executes bundled scripts.
#!/usr/bin/env python3
"""Agent for Linux memory forensics using LiME acquisition and Volatility 3."""
import json
import subprocess
import argparse
from datetime import datetime
from pathlib import Path
def acquire_memory_lime(output_path, lime_format="lime"):
"""Acquire memory using LiME kernel module."""
kernel_version = subprocess.run(
["uname", "-r"], capture_output=True, text=True, timeout=120
).stdout.strip()
lime_module = f"lime-{kernel_version}.ko"
if not Path(lime_module).exists():
lime_module = "lime.ko"
cmd = ["insmod", lime_module, f"path={output_path}", f"format={lime_format}"]
result = subprocess.run(cmd, capture_output=True, text=True, timeout=120)
return {
"status": "success" if result.returncode == 0 else "failed",
"output_path": output_path,
"format": lime_format,
"kernel": kernel_version,
"stderr": result.stderr,
}
def run_vol3_plugin(image_path, plugin_name, extra_args=None):
"""Run a Volatility 3 plugin and capture output."""
cmd = ["vol3", "-f", image_path, plugin_name]
if extra_args:
cmd.extend(extra_args)
try:
result = subprocess.run(
cmd, capture_output=True, text=True, timeout=300,
)
lines = result.stdout.strip().splitlines()
return {"plugin": plugin_name, "output": lines, "error": result.stderr.strip()}
except subprocess.TimeoutExpired:
return {"plugin": plugin_name, "output": [], "error": "Timeout"}
def parse_pslist_output(lines):
"""Parse Volatility linux.pslist output into structured data."""
processes = []
for line in lines:
parts = line.split()
if len(parts) >= 4 and parts[0].isdigit():
processes.append({
"pid": int(parts[0]),
"ppid": int(parts[1]) if parts[1].isdigit() else 0,
"name": parts[-1],
})
return processes
def list_processes(image_path):
"""List all processes from memory image."""
result = run_vol3_plugin(image_path, "linux.pslist")
return parse_pslist_output(result.get("output", []))
def extract_bash_history(image_path):
"""Extract bash command history from memory."""
result = run_vol3_plugin(image_path, "linux.bash")
commands = []
for line in result.get("output", []):
parts = line.split(None, 3)
if len(parts) >= 4 and parts[0].isdigit():
commands.append({
"pid": int(parts[0]),
"name": parts[1],
"timestamp": parts[2] if len(parts) > 2 else "",
"command": parts[3] if len(parts) > 3 else "",
})
return commands
def list_network_connections(image_path):
"""List network connections from memory."""
result = run_vol3_plugin(image_path, "linux.sockstat")
connections = []
for line in result.get("output", []):
if "TCP" in line or "UDP" in line:
connections.append(line.strip())
return connections
def list_kernel_modules(image_path):
"""List loaded kernel modules to detect rootkits."""
result = run_vol3_plugin(image_path, "linux.lsmod")
modules = []
for line in result.get("output", []):
parts = line.split()
if parts and not parts[0].startswith("Offset"):
modules.append({"name": parts[-1] if parts else line.strip()})
return modules
def detect_hidden_processes(image_path):
"""Compare pslist vs psscan to find hidden processes."""
pslist = run_vol3_plugin(image_path, "linux.pslist")
psscan = run_vol3_plugin(image_path, "linux.psscan")
pslist_pids = set()
for line in pslist.get("output", []):
parts = line.split()
if parts and parts[0].isdigit():
pslist_pids.add(int(parts[0]))
hidden = []
for line in psscan.get("output", []):
parts = line.split()
if parts and parts[0].isdigit():
pid = int(parts[0])
if pid not in pslist_pids and pid > 0:
hidden.append({"pid": pid, "line": line.strip()})
return hidden
def detect_suspicious_commands(bash_history):
"""Flag suspicious commands in bash history."""
suspicious_patterns = [
"curl.*|.*sh", "wget.*&&.*chmod", "base64.*-d",
"nc.*-e", "python.*-c.*import.*socket",
"nohup", "rm.*-rf.*/var/log", "history.*-c",
"iptables.*-F", "chmod.*777", "chattr.*-i",
]
import re
findings = []
for entry in bash_history:
cmd = entry.get("command", "")
for pattern in suspicious_patterns:
if re.search(pattern, cmd, re.IGNORECASE):
findings.append({
"pid": entry["pid"],
"command": cmd,
"pattern": pattern,
"severity": "HIGH",
})
break
return findings
def check_malfind(image_path):
"""Run malfind to detect injected code."""
result = run_vol3_plugin(image_path, "linux.malfind")
return result.get("output", [])
def main():
parser = argparse.ArgumentParser(description="LiME + Volatility 3 Forensics Agent")
parser.add_argument("--image", help="Path to memory image")
parser.add_argument("--acquire", help="Output path for LiME acquisition")
parser.add_argument("--output", default="memory_forensics_report.json")
parser.add_argument("--action", choices=[
"acquire", "pslist", "bash", "network", "modules",
"hidden", "malfind", "full_analysis"
], default="full_analysis")
args = parser.parse_args()
report = {"generated_at": datetime.utcnow().isoformat(), "findings": {}}
if args.action == "acquire" and args.acquire:
result = acquire_memory_lime(args.acquire)
report["findings"]["acquisition"] = result
print(f"[+] Memory acquisition: {result['status']}")
return
if not args.image:
print("[-] --image required for analysis actions")
return
if args.action in ("pslist", "full_analysis"):
procs = list_processes(args.image)
report["findings"]["processes"] = procs
print(f"[+] Processes: {len(procs)}")
if args.action in ("bash", "full_analysis"):
history = extract_bash_history(args.image)
report["findings"]["bash_history"] = history
suspicious = detect_suspicious_commands(history)
report["findings"]["suspicious_commands"] = suspicious
print(f"[+] Bash commands: {len(history)}, Suspicious: {len(suspicious)}")
if args.action in ("network", "full_analysis"):
conns = list_network_connections(args.image)
report["findings"]["connections"] = conns
print(f"[+] Network connections: {len(conns)}")
if args.action in ("modules", "full_analysis"):
modules = list_kernel_modules(args.image)
report["findings"]["kernel_modules"] = modules
print(f"[+] Kernel modules: {len(modules)}")
if args.action in ("hidden", "full_analysis"):
hidden = detect_hidden_processes(args.image)
report["findings"]["hidden_processes"] = hidden
print(f"[+] Hidden processes: {len(hidden)}")
with open(args.output, "w") as f:
json.dump(report, f, indent=2, default=str)
print(f"[+] Report saved to {args.output}")
if __name__ == "__main__":
main()
Keep exploring