Collecting Volatile Evidence from Compromised Hosts When to Use - Security incident confirmed and compromised host identified - Before system isolation, shutdown, or remediation begins - Memory-resident malware suspected (fileless attacks) - Need to capture network connections, running processes, and system state - Legal proceedings may require forensic evidence preservation - Incident requires root cause analysis with volatile data Prerequisites - Forensic collection toolkit on USB or network share (trusted tools) - WinPmem/LiME for memory acquisition - Write-blocker or forensic workstation…

); do\n echo \"=== PID $pid ===\" >> \"$EVIDENCE_DIR/proc_maps.txt\"\n cat \"/proc/$pid/maps\" 2>/dev/null >> \"$EVIDENCE_DIR/proc_maps.txt\"\ndone\n\n# Open file handles\nhandle.exe -accepteula > \"$EVIDENCE_DIR/open_handles.txt\" # Windows (Sysinternals)\nlsof > \"$EVIDENCE_DIR/open_files.txt\" # Linux\n```\n\n### Step 5: Capture Logged-in Users and Sessions\n```bash\n# Windows\nquery user > \"$EVIDENCE_DIR/logged_in_users.txt\"\nquery session > \"$EVIDENCE_DIR/active_sessions.txt\"\nnet session > \"$EVIDENCE_DIR/net_sessions.txt\" 2>&1\nnet use > \"$EVIDENCE_DIR/mapped_drives.txt\" 2>&1\n\n# Linux\nwho > \"$EVIDENCE_DIR/who_output.txt\"\nw > \"$EVIDENCE_DIR/w_output.txt\"\nlast -50 > \"$EVIDENCE_DIR/last_logins.txt\"\nlastlog > \"$EVIDENCE_DIR/lastlog.txt\"\ncat /var/log/auth.log | tail -200 > \"$EVIDENCE_DIR/recent_auth.txt\" 2>/dev/null\n```\n\n### Step 6: Capture System Configuration State\n```bash\n# System time (critical for timeline)\ndate -u > \"$EVIDENCE_DIR/system_time_utc.txt\"\nw32tm /query /status > \"$EVIDENCE_DIR/ntp_status.txt\" # Windows\nntpq -p > \"$EVIDENCE_DIR/ntp_status.txt\" # Linux\n\n# Environment variables\nset > \"$EVIDENCE_DIR/environment_vars.txt\" # Windows\nenv > \"$EVIDENCE_DIR/environment_vars.txt\" # Linux\n\n# Scheduled tasks / Cron jobs\nschtasks /query /fo CSV /v > \"$EVIDENCE_DIR/scheduled_tasks.csv\" # Windows\ncrontab -l > \"$EVIDENCE_DIR/crontab_current.txt\" 2>/dev/null # Linux\nls -la /etc/cron.* > \"$EVIDENCE_DIR/cron_dirs.txt\" 2>/dev/null\n\n# Services\nsc queryex type=service state=all > \"$EVIDENCE_DIR/services_all.txt\" # Windows\nsystemctl list-units --type=service --all > \"$EVIDENCE_DIR/systemd_services.txt\" # Linux\n\n# Windows Registry - key autostart locations\nreg export \"HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run\" \"$EVIDENCE_DIR/reg_run_hklm.reg\" /y\nreg export \"HKCU\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run\" \"$EVIDENCE_DIR/reg_run_hkcu.reg\" /y\nreg export \"HKLM\\SYSTEM\\CurrentControlSet\\Services\" \"$EVIDENCE_DIR/reg_services.reg\" /y\n```\n\n### Step 7: Hash All Evidence and Document Chain of Custody\n```bash\n# Generate SHA256 hashes for all collected evidence\ncd \"$EVIDENCE_DIR\"\nsha256sum * > evidence_manifest.sha256\n\n# Create chain of custody record\ncat > \"$EVIDENCE_DIR/chain_of_custody.txt\" \u003c\u003c EOF\nCHAIN OF CUSTODY RECORD\n========================\nCase ID: IR-YYYY-NNN\nCollection Date: $(date -u)\nCollected By: $(whoami)\nSystem: $(hostname)\nSystem IP: $(hostname -I 2>/dev/null || ipconfig | grep IPv4)\nCollection Method: Live forensic collection via trusted USB toolkit\n\nEvidence Items:\n$(ls -la \"$EVIDENCE_DIR/\" | grep -v chain_of_custody)\n\nSHA256 Manifest: evidence_manifest.sha256\nTransfer: [TO BE COMPLETED]\nStorage Location: [TO BE COMPLETED]\nEOF\n```\n\n## Key Concepts\n\n| Concept | Description |\n|---------|-------------|\n| Order of Volatility | RFC 3227 - Collect most volatile data first: registers > cache > memory > disk |\n| Live Forensics | Collecting evidence from a running system before shutdown |\n| Chain of Custody | Documentation tracking evidence handling from collection to court |\n| Forensic Soundness | Ensuring evidence collection doesn't alter the original evidence |\n| Trusted Tools | Using verified tools from external media, not from the compromised system |\n| Evidence Integrity | SHA256 hashing of all evidence immediately after collection |\n| Locard's Exchange Principle | Every contact leaves a trace - minimize investigator artifacts |\n\n## Tools & Systems\n\n| Tool | Purpose |\n|------|---------|\n| WinPmem | Windows memory acquisition |\n| LiME (Linux Memory Extractor) | Linux kernel memory acquisition |\n| Sysinternals Suite | Process, handle, and DLL analysis (Windows) |\n| Velociraptor | Remote forensic collection at scale |\n| KAPE (Kroll Artifact Parser) | Automated artifact collection on Windows |\n| CyLR | Cross-platform live response collection |\n| GRR Rapid Response | Remote live forensics framework |\n\n## Common Scenarios\n\n1. **Fileless Malware Attack**: PowerShell-based attack with no files on disk. Memory dump is critical evidence containing the malicious scripts.\n2. **Active C2 Session**: Attacker has live connection. Network connections and process data reveal C2 infrastructure.\n3. **Insider Data Theft**: Employee copying files. Process list, mapped drives, and network connections show exfiltration activity.\n4. **Compromised Web Server**: Web shell detected. Memory may contain additional backdoors not yet written to disk.\n5. **Lateral Movement in Progress**: Attacker moving between systems. Authentication tokens and network sessions in memory reveal scope.\n\n## Output Format\n- Memory dump file (.raw or .lime format) with SHA256 hash\n- Network state captures (connections, ARP, DNS, routes)\n- Process listings with command lines and parent processes\n- User session and authentication data\n- System configuration snapshots\n- Evidence manifest with SHA256 checksums\n- Chain of custody documentation\n---","attachment_filenames":["assets/template.md","references/api-reference.md","references/standards.md","references/workflows.md","scripts/agent.py","scripts/process.py"],"attachments":[{"filename":"assets/template.md","content":"# Volatile Evidence Collection Report\n\n## Case Information\n| Field | Value |\n|-------|-------|\n| Case ID | |\n| System Hostname | |\n| System IP Address | |\n| System OS | |\n| Collection Date/Time (UTC) | |\n| Collector Name | |\n| Authorization | [IR Plan / Legal Hold / HR Approval] |\n\n## Collection Summary\n| Evidence Category | Items Collected | Status |\n|------------------|----------------|--------|\n| Memory Dump | | Collected/Failed/Skipped |\n| Network Connections | | Collected/Failed/Skipped |\n| ARP Cache | | Collected/Failed/Skipped |\n| DNS Cache | | Collected/Failed/Skipped |\n| Routing Table | | Collected/Failed/Skipped |\n| Running Processes | | Collected/Failed/Skipped |\n| Open File Handles | | Collected/Failed/Skipped |\n| Logged-in Users | | Collected/Failed/Skipped |\n| System Configuration | | Collected/Failed/Skipped |\n| Services | | Collected/Failed/Skipped |\n| Scheduled Tasks | | Collected/Failed/Skipped |\n| Registry/Config | | Collected/Failed/Skipped |\n\n## Evidence Manifest\n| Filename | SHA256 Hash | Size | Category |\n|----------|------------|------|----------|\n| | | | |\n\n## Chain of Custody\n| Date/Time (UTC) | Action | Person | Notes |\n|-----------------|--------|--------|-------|\n| | Evidence collected from live system | | |\n| | Evidence transferred to forensic storage | | |\n| | Evidence hash verified | | |\n| | Evidence accessed for analysis | | |\n\n## System Time Verification\n| Field | Value |\n|-------|-------|\n| System Clock (UTC) | |\n| Reference Time (UTC) | |\n| Time Offset | |\n| NTP Synchronized | Yes/No |\n| NTP Server | |\n\n## Notable Findings During Collection\n[Any suspicious processes, connections, or artifacts noted during collection]\n\n## Collection Tool Information\n| Tool | Version | Source | SHA256 Hash |\n|------|---------|--------|-------------|\n| | | | |\n\n## Collector Certification\nI certify that the evidence described above was collected using forensically sound methods, from external trusted tools, and that all evidence was hashed immediately upon collection.\n\n| Field | Value |\n|-------|-------|\n| Collector Name | |\n| Collector Title | |\n| Date | |\n| Signature | |\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":2125,"content_sha256":"c5cebbbe7dcd08ba14425345e384a8ce1fd5b5fb1e0d4354aafba5ee911d3666"},{"filename":"references/api-reference.md","content":"# API Reference: Collecting Volatile Evidence from Compromised Host\n\n## RFC 3227 Order of Volatility\n| Priority | Source | Persistence |\n|----------|--------|------------|\n| 1 | CPU registers, cache | Nanoseconds |\n| 2 | Physical memory (RAM) | Power cycle |\n| 3 | Network state | Seconds-minutes |\n| 4 | Running processes | Minutes |\n| 5 | Disk (filesystem) | Persistent |\n| 6 | Remote logging / monitoring | Persistent |\n| 7 | Physical configuration | Persistent |\n| 8 | Archival media | Long-term |\n\n## Memory Acquisition Tools\n| Tool | Platform | Command |\n|------|----------|---------|\n| AVML | Linux | `avml /path/to/output.lime` |\n| WinPmem | Windows | `winpmem_mini_x64.exe output.raw` |\n| LiME | Linux | `insmod lime.ko \"path=/tmp/mem.lime format=lime\"` |\n| Magnet RAM Capture | Windows | GUI-based acquisition |\n\n## Linux Collection Commands\n```bash\n# Network connections\nss -tunap > /evidence/netstat.txt\n\n# Process list with tree\nps auxwwf > /evidence/processes.txt\n\n# Open files\nlsof -nP > /evidence/open_files.txt\n\n# Network config\nip addr show > /evidence/ifconfig.txt\nip route show > /evidence/routes.txt\nip neigh show > /evidence/arp.txt\n\n# Logged-in users\nw > /evidence/users.txt\nlast -50 > /evidence/last_logins.txt\n\n# Cron jobs\ncrontab -l > /evidence/crontab.txt\nls -la /etc/cron.d/ >> /evidence/crontab.txt\n```\n\n## Windows Collection Commands\n```cmd\n:: Network connections\nnetstat -anob > C:\\evidence\\netstat.txt\n\n:: Process list\ntasklist /V /FO CSV > C:\\evidence\\processes.csv\nwmic process get ProcessId,Name,CommandLine /format:csv > C:\\evidence\\wmic_procs.csv\n\n:: Network config\nipconfig /all > C:\\evidence\\ipconfig.txt\nroute print > C:\\evidence\\routes.txt\narp -a > C:\\evidence\\arp.txt\n\n:: DNS cache\nipconfig /displaydns > C:\\evidence\\dns_cache.txt\n\n:: Scheduled tasks\nschtasks /query /FO CSV /V > C:\\evidence\\schtasks.csv\n\n:: Logged-in users\nquery user > C:\\evidence\\users.txt\n```\n\n## Evidence Integrity\n```bash\n# Hash collected files\nsha256sum /evidence/*.txt > /evidence/checksums.sha256\n\n# Verify later\nsha256sum -c /evidence/checksums.sha256\n```\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":2075,"content_sha256":"45d2b074e5f8ea3464ae922d449038b3220187fce5f21e1296795425b2cab44f"},{"filename":"references/standards.md","content":"# Standards and Framework References - Volatile Evidence Collection\n\n## RFC 3227 - Guidelines for Evidence Collection and Archiving\n- Defines the order of volatility for digital evidence:\n 1. Registers, cache\n 2. Routing table, ARP cache, process table, kernel statistics, memory\n 3. Temporary file systems\n 4. Disk\n 5. Remote logging and monitoring data\n 6. Physical configuration, network topology\n 7. Archival media\n- Key principles: minimize data alteration, document actions, use trusted tools\n- Reference: https://www.rfc-editor.org/rfc/rfc3227\n\n## NIST SP 800-86 - Guide to Integrating Forensic Techniques\n- Section 4: Using Data from Data Sources\n - 4.2: Data Files - Volatile and non-volatile OS data\n - 4.3: Operating System Data - Memory, processes, network connections\n- Forensic process: Collection, Examination, Analysis, Reporting\n- Emphasis on preserving data integrity through proper acquisition\n- Reference: https://csrc.nist.gov/pubs/sp/800/86/final\n\n## NIST SP 800-61 Rev. 3 - Evidence Handling\n- **Respond (RS)** function alignment:\n - RS.AN-03: Analysis to establish incident scope\n- Evidence must be collected in a forensically sound manner\n- Document all collection activities and maintain chain of custody\n\n## SANS DFIR - Live Evidence Collection Best Practices\n- Collect evidence from most volatile to least volatile\n- Use external trusted tools (not tools from compromised system)\n- Hash all evidence immediately after collection\n- Document system time offset from UTC\n- Minimize footprint on compromised system\n- Reference: https://www.sans.org/white-papers/\n\n## MITRE ATT&CK - Evidence Sources for Detection\n| Data Source | ATT&CK Reference | Evidence Type |\n|------------|-------------------|---------------|\n| Process (DS0009) | Process creation, command line | Running processes |\n| Network Traffic (DS0029) | Connection creation, flow | Network connections |\n| File (DS0022) | File creation, modification | Open handles, temp files |\n| Windows Registry (DS0024) | Registry key modification | Autostart entries |\n| Logon Session (DS0028) | Logon creation | Active user sessions |\n| Module (DS0011) | Module load | Loaded DLLs/shared objects |\n\n## ACPO Good Practice Guide for Digital Evidence\n- Principle 1: No action should change data on digital devices\n- Principle 2: Competent person must access original data when necessary\n- Principle 3: Audit trail of all processes applied to evidence\n- Principle 4: Person in charge ensures law and principles are adhered to\n\n## ISO/IEC 27037 - Guidelines for Identification, Collection, Acquisition, and Preservation\n- Defines procedures for handling digital evidence\n- Specifies requirements for first responders and forensic specialists\n- Covers volatile and non-volatile evidence acquisition\n- Emphasizes competency of evidence handlers\n\n## SWGDE Best Practices for Computer Forensics\n- Scientific Working Group on Digital Evidence\n- Standards for evidence acquisition, examination, and reporting\n- Quality assurance requirements for forensic processes\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":3041,"content_sha256":"2c7a806a23c89a27c7573199e0de7d34913502f0d2396f9d55121b2b5d75a41d"},{"filename":"references/workflows.md","content":"# Volatile Evidence Collection - Detailed Workflow\n\n## Order of Volatility Collection Sequence\n\n### Priority 1: Memory (Most Volatile) - Collect First\n1. Connect forensic USB with memory acquisition tool\n2. Run memory dump tool from USB (NOT from compromised disk)\n3. Save memory image to external storage\n4. Record start time, end time, and memory size\n5. Generate SHA256 hash of memory image immediately\n6. Document any errors during acquisition\n\n### Priority 2: Network State\n1. Capture all active TCP/UDP connections with process IDs\n2. Capture ARP cache (maps IP to MAC addresses)\n3. Capture DNS resolver cache\n4. Capture routing table\n5. Capture active firewall rules\n6. Capture listening ports and associated processes\n7. Hash all network evidence files\n\n### Priority 3: Running Processes\n1. List all processes with full command lines\n2. List parent-child process relationships (process tree)\n3. List all loaded modules/DLLs per process\n4. List all open file handles per process\n5. List process network connections per PID\n6. Capture process creation timestamps\n7. Hash all process evidence files\n\n### Priority 4: User Sessions\n1. List all currently logged-in users\n2. List active remote sessions (RDP, SSH, SMB)\n3. List mapped network drives\n4. Capture recent authentication events\n5. List active tokens and session keys (if accessible)\n\n### Priority 5: System Configuration\n1. Capture system time and UTC offset\n2. Export autostart/persistence locations (Registry Run keys, crontab)\n3. List all services and their states\n4. Capture environment variables\n5. List installed software\n6. Export relevant event log entries\n\n### Priority 6: Temporary/Cache Data\n1. Capture browser history and cache (if relevant)\n2. Capture clipboard contents (if accessible)\n3. Capture temp directory contents\n4. Capture recent file lists\n5. Capture prefetch files (Windows)\n\n## Platform-Specific Collection Procedures\n\n### Windows Collection Checklist\n```\n[ ] Memory: WinPmem/Magnet RAM Capture\n[ ] Processes: tasklist /V, wmic process, Get-Process\n[ ] Network: netstat -anob, Get-NetTCPConnection\n[ ] Users: query user, net session\n[ ] Registry: Run keys, Services, Startup\n[ ] Services: sc queryex, Get-Service\n[ ] Scheduled Tasks: schtasks /query\n[ ] DNS Cache: ipconfig /displaydns\n[ ] ARP: arp -a\n[ ] Firewall: netsh advfirewall\n[ ] Event Logs: wevtutil (Security, System, Application)\n[ ] Prefetch: %SystemRoot%\\Prefetch\\*\n[ ] Time: w32tm /query /status\n```\n\n### Linux Collection Checklist\n```\n[ ] Memory: LiME kernel module or /proc/kcore\n[ ] Processes: ps auxwwf, /proc/*/cmdline, /proc/*/maps\n[ ] Network: ss -tulnp, /proc/net/tcp, /proc/net/udp\n[ ] Users: who, w, last\n[ ] Cron: crontab -l, /etc/cron.*\n[ ] Services: systemctl list-units\n[ ] DNS: systemd-resolve, /etc/resolv.conf\n[ ] ARP: ip neigh\n[ ] Firewall: iptables -L -n -v, nftables\n[ ] Logs: /var/log/auth.log, /var/log/syslog\n[ ] Open Files: lsof\n[ ] Time: timedatectl\n[ ] Loaded Modules: lsmod\n```\n\n## Evidence Integrity Procedures\n\n### Hashing Protocol\n1. Hash EVERY collected file immediately after creation\n2. Use SHA256 (minimum) - SHA512 preferred for legal cases\n3. Store hash manifest in separate file\n4. Verify hashes before and after any transfer\n5. Include hash in chain of custody documentation\n\n### Chain of Custody Requirements\n1. Record who collected each evidence item\n2. Record exact time of collection (UTC)\n3. Record collection method and tool version\n4. Record any transfer of evidence\n5. Record storage location and access controls\n6. Record any analysis performed on copies (never originals)\n\n## Common Pitfalls to Avoid\n1. Running tools from the compromised system's disk\n2. Forgetting to hash evidence immediately\n3. Not recording system time offset from UTC\n4. Installing collection tools on the compromised system\n5. Rebooting the system before memory collection\n6. Modifying file timestamps by browsing the filesystem\n7. Not documenting collection steps in real-time\n8. Collecting evidence without proper authorization\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":4004,"content_sha256":"06bbfdb0e4a5608ceba1ea71c12f4777e6af9d33cb0b2558cf0ba3e4abe397e6"},{"filename":"scripts/agent.py","content":"#!/usr/bin/env python3\n\"\"\"Volatile evidence collection agent for compromised hosts.\n\nCollects volatile forensic artifacts following RFC 3227 order of volatility:\nregisters, memory, network state, running processes, disk, and logs.\nUses platform-native tools for live response evidence gathering.\n\"\"\"\n\nimport sys\nimport json\nimport os\nimport datetime\nimport subprocess\nimport shlex\nimport platform\nimport hashlib\n\n\nVOLATILITY_ORDER = [\n {\"priority\": 1, \"source\": \"memory\", \"description\": \"Physical memory (RAM) dump\",\n \"tool_linux\": \"avml\", \"tool_windows\": \"winpmem_mini_x64.exe\"},\n {\"priority\": 2, \"source\": \"network_connections\", \"description\": \"Active network connections\",\n \"tool_linux\": \"ss -tunap\", \"tool_windows\": \"netstat -anob\"},\n {\"priority\": 3, \"source\": \"running_processes\", \"description\": \"Running process list with details\",\n \"tool_linux\": \"ps auxwwf\", \"tool_windows\": \"tasklist /V /FO CSV\"},\n {\"priority\": 4, \"source\": \"open_files\", \"description\": \"Open file handles\",\n \"tool_linux\": \"lsof -nP\", \"tool_windows\": \"handle64.exe -a\"},\n {\"priority\": 5, \"source\": \"network_config\", \"description\": \"Network interface configuration\",\n \"tool_linux\": \"ip addr show\", \"tool_windows\": \"ipconfig /all\"},\n {\"priority\": 6, \"source\": \"routing_table\", \"description\": \"Network routing table\",\n \"tool_linux\": \"ip route show\", \"tool_windows\": \"route print\"},\n {\"priority\": 7, \"source\": \"arp_cache\", \"description\": \"ARP cache entries\",\n \"tool_linux\": \"ip neigh show\", \"tool_windows\": \"arp -a\"},\n {\"priority\": 8, \"source\": \"dns_cache\", \"description\": \"DNS resolver cache\",\n \"tool_linux\": \"cat /etc/resolv.conf\", \"tool_windows\": \"ipconfig /displaydns\"},\n {\"priority\": 9, \"source\": \"logged_users\", \"description\": \"Currently logged-in users\",\n \"tool_linux\": \"w\", \"tool_windows\": \"query user\"},\n {\"priority\": 10, \"source\": \"scheduled_tasks\", \"description\": \"Scheduled tasks and cron jobs\",\n \"tool_linux\": [\"crontab -l\", \"ls /etc/cron.d/\"], \"tool_windows\": \"schtasks /query /FO CSV /V\"},\n]\n\n\ndef _run_single_cmd(cmd_str, timeout=60):\n \"\"\"Run a single command string without shell, return stdout and stderr.\"\"\"\n return subprocess.run(\n shlex.split(cmd_str), capture_output=True, text=True, timeout=timeout\n )\n\n\ndef collect_artifact(source_config, output_dir):\n \"\"\"Collect a single volatile artifact.\"\"\"\n is_windows = platform.system() == \"Windows\"\n cmd = source_config[\"tool_windows\"] if is_windows else source_config[\"tool_linux\"]\n source_name = source_config[\"source\"]\n output_file = os.path.join(output_dir, source_name + \".txt\")\n\n result = {\n \"source\": source_name,\n \"priority\": source_config[\"priority\"],\n \"command\": cmd if isinstance(cmd, str) else \"; \".join(cmd),\n \"timestamp\": datetime.datetime.utcnow().isoformat() + \"Z\",\n \"status\": \"pending\",\n }\n\n try:\n # Run multiple commands sequentially if cmd is a list, combining output\n if isinstance(cmd, list):\n combined_stdout = \"\"\n combined_stderr = \"\"\n last_rc = 0\n for sub_cmd in cmd:\n sub_proc = _run_single_cmd(sub_cmd, timeout=60)\n combined_stdout += sub_proc.stdout\n combined_stderr += sub_proc.stderr\n last_rc = sub_proc.returncode\n proc = type(\"CombinedResult\", (), {\n \"stdout\": combined_stdout,\n \"stderr\": combined_stderr,\n \"returncode\": last_rc,\n })()\n else:\n proc = _run_single_cmd(cmd, timeout=60)\n result[\"status\"] = \"collected\"\n result[\"output_lines\"] = len(proc.stdout.splitlines())\n result[\"output_file\"] = output_file\n result[\"exit_code\"] = proc.returncode\n\n with open(output_file, \"w\", encoding=\"utf-8\") as f:\n f.write(\"# Collected: {}\\n\".format(result[\"timestamp\"]))\n f.write(\"# Command: {}\\n\".format(cmd))\n f.write(\"# Exit code: {}\\n\\n\".format(proc.returncode))\n f.write(proc.stdout)\n if proc.stderr:\n f.write(\"\\n# STDERR:\\n\" + proc.stderr)\n\n sha256 = hashlib.sha256(proc.stdout.encode()).hexdigest()\n result[\"sha256\"] = sha256\n except subprocess.TimeoutExpired:\n result[\"status\"] = \"timeout\"\n except Exception as e:\n result[\"status\"] = \"error\"\n result[\"error\"] = str(e)\n\n return result\n\n\ndef run_collection(output_dir, sources=None):\n \"\"\"Run full volatile evidence collection.\"\"\"\n os.makedirs(output_dir, exist_ok=True)\n if sources is None:\n sources = VOLATILITY_ORDER\n\n manifest = {\n \"collection_start\": datetime.datetime.utcnow().isoformat() + \"Z\",\n \"hostname\": platform.node(),\n \"platform\": platform.system(),\n \"output_dir\": output_dir,\n \"artifacts\": [],\n }\n\n for source_config in sorted(sources, key=lambda x: x[\"priority\"]):\n if source_config[\"source\"] == \"memory\":\n manifest[\"artifacts\"].append({\n \"source\": \"memory\",\n \"priority\": 1,\n \"status\": \"skipped\",\n \"note\": \"Memory dump requires elevated privileges and dedicated tool\",\n })\n continue\n\n result = collect_artifact(source_config, output_dir)\n manifest[\"artifacts\"].append(result)\n\n manifest[\"collection_end\"] = datetime.datetime.utcnow().isoformat() + \"Z\"\n manifest[\"total_collected\"] = sum(1 for a in manifest[\"artifacts\"] if a[\"status\"] == \"collected\")\n\n manifest_path = os.path.join(output_dir, \"collection_manifest.json\")\n with open(manifest_path, \"w\", encoding=\"utf-8\") as f:\n json.dump(manifest, f, indent=2)\n manifest[\"manifest_file\"] = manifest_path\n\n return manifest\n\n\nif __name__ == \"__main__\":\n print(\"=\" * 60)\n print(\"Volatile Evidence Collection Agent\")\n print(\"RFC 3227 order of volatility, live response artifacts\")\n print(\"=\" * 60)\n print(\" Platform: {}\".format(platform.system()))\n print(\" Hostname: {}\".format(platform.node()))\n\n output_dir = sys.argv[1] if len(sys.argv) > 1 else os.path.join(\n os.path.expanduser(\"~\"), \"volatile_evidence_\" + datetime.datetime.utcnow().strftime(\"%Y%m%d_%H%M%S\")\n )\n\n print(\"\\n--- RFC 3227 Volatility Order ---\")\n for v in VOLATILITY_ORDER:\n tool = v[\"tool_windows\"] if platform.system() == \"Windows\" else v[\"tool_linux\"]\n print(\" P{}: {:25s} [{}]\".format(v[\"priority\"], v[\"source\"], tool))\n\n print(\"\\n[*] Collecting volatile evidence to: {}\".format(output_dir))\n manifest = run_collection(output_dir)\n\n print(\"\\n--- Collection Results ---\")\n for a in manifest[\"artifacts\"]:\n status_marker = \"+\" if a[\"status\"] == \"collected\" else \"-\"\n print(\" [{}] P{}: {} -> {}\".format(\n status_marker, a[\"priority\"], a[\"source\"], a[\"status\"]))\n\n print(\"\\nTotal collected: {}/{}\".format(\n manifest[\"total_collected\"], len(manifest[\"artifacts\"])))\n print(\"Manifest: {}\".format(manifest.get(\"manifest_file\", \"\")))\n\n print(\"\\n\" + json.dumps({\"artifacts_collected\": manifest[\"total_collected\"]}, indent=2))\n","content_type":"text/x-python; charset=utf-8","language":"python","size":7167,"content_sha256":"cf7b13f31250c2a2725e6a4a304bed95edab6818c96294285a3add429f9d504b"},{"filename":"scripts/process.py","content":"#!/usr/bin/env python3\n\"\"\"\nVolatile Evidence Collection Script\n\nCollects volatile forensic evidence from a live system following\nRFC 3227 order of volatility. Runs from external media.\n\nCollects:\n- Network connections and state\n- Running processes with command lines\n- Logged-in users and sessions\n- System configuration and state\n- DNS cache, ARP table, routing table\n- Hashes all evidence files\n\nRequirements:\n pip install psutil\n\"\"\"\n\nimport argparse\nimport csv\nimport hashlib\nimport json\nimport logging\nimport os\nimport platform\nimport socket\nimport subprocess\nimport sys\nfrom datetime import datetime, timezone\nfrom pathlib import Path\n\ntry:\n import psutil\nexcept ImportError:\n print(\"Install psutil: pip install psutil\")\n sys.exit(1)\n\nlogging.basicConfig(\n level=logging.INFO,\n format=\"%(asctime)s [%(levelname)s] %(message)s\",\n)\nlogger = logging.getLogger(\"volatile_evidence\")\n\n\nclass EvidenceCollector:\n \"\"\"Collect volatile evidence from a live system.\"\"\"\n\n def __init__(self, output_dir: str, case_id: str):\n self.case_id = case_id\n self.hostname = socket.gethostname()\n self.timestamp = datetime.now(timezone.utc).strftime(\"%Y%m%d_%H%M%S\")\n self.output_dir = os.path.join(output_dir, f\"{self.hostname}_{self.timestamp}\")\n os.makedirs(self.output_dir, exist_ok=True)\n self.evidence_manifest = []\n self.collection_log = []\n\n # Start collection log\n self._log_action(\"Collection initiated\", f\"Case: {case_id}, Host: {self.hostname}\")\n self._log_action(\"System time\", datetime.now(timezone.utc).isoformat())\n self._log_action(\"Platform\", f\"{platform.system()} {platform.release()}\")\n self._log_action(\"Collector\", os.getenv(\"USERNAME\", os.getenv(\"USER\", \"unknown\")))\n\n def _log_action(self, action: str, details: str):\n entry = {\n \"timestamp\": datetime.now(timezone.utc).isoformat(),\n \"action\": action,\n \"details\": details,\n }\n self.collection_log.append(entry)\n logger.info(f\"{action}: {details}\")\n\n def _save_evidence(self, filename: str, content: str, category: str):\n filepath = os.path.join(self.output_dir, filename)\n with open(filepath, \"w\", encoding=\"utf-8\", errors=\"replace\") as f:\n f.write(content)\n file_hash = self._hash_file(filepath)\n self.evidence_manifest.append({\n \"filename\": filename,\n \"category\": category,\n \"sha256\": file_hash,\n \"size_bytes\": os.path.getsize(filepath),\n \"collected_at\": datetime.now(timezone.utc).isoformat(),\n })\n self._log_action(f\"Evidence collected: {filename}\", f\"SHA256: {file_hash}\")\n return filepath\n\n def _save_evidence_csv(self, filename: str, data: list, category: str):\n if not data:\n self._log_action(f\"No data for {filename}\", \"Empty result set\")\n return None\n filepath = os.path.join(self.output_dir, filename)\n with open(filepath, \"w\", newline=\"\", encoding=\"utf-8\") as f:\n writer = csv.DictWriter(f, fieldnames=data[0].keys())\n writer.writeheader()\n writer.writerows(data)\n file_hash = self._hash_file(filepath)\n self.evidence_manifest.append({\n \"filename\": filename,\n \"category\": category,\n \"sha256\": file_hash,\n \"size_bytes\": os.path.getsize(filepath),\n \"collected_at\": datetime.now(timezone.utc).isoformat(),\n })\n self._log_action(f\"Evidence collected: {filename}\", f\"SHA256: {file_hash}, Rows: {len(data)}\")\n return filepath\n\n @staticmethod\n def _hash_file(filepath: str) -> str:\n sha256 = hashlib.sha256()\n with open(filepath, \"rb\") as f:\n for chunk in iter(lambda: f.read(8192), b\"\"):\n sha256.update(chunk)\n return sha256.hexdigest()\n\n def collect_network_connections(self):\n \"\"\"Collect active network connections with process information.\"\"\"\n self._log_action(\"Collecting\", \"Network connections\")\n connections = []\n for conn in psutil.net_connections(kind=\"all\"):\n try:\n proc_name = psutil.Process(conn.pid).name() if conn.pid else \"N/A\"\n except (psutil.NoSuchProcess, psutil.AccessDenied):\n proc_name = \"N/A\"\n connections.append({\n \"fd\": conn.fd,\n \"family\": str(conn.family),\n \"type\": str(conn.type),\n \"local_address\": f\"{conn.laddr.ip}:{conn.laddr.port}\" if conn.laddr else \"\",\n \"remote_address\": f\"{conn.raddr.ip}:{conn.raddr.port}\" if conn.raddr else \"\",\n \"status\": conn.status,\n \"pid\": conn.pid or \"\",\n \"process_name\": proc_name,\n })\n self._save_evidence_csv(\"network_connections.csv\", connections, \"network\")\n\n # Also save in text format\n text_output = f\"Network Connections - {datetime.now(timezone.utc).isoformat()}\\n\"\n text_output += f\"{'='*80}\\n\"\n text_output += f\"Total connections: {len(connections)}\\n\\n\"\n for conn in connections:\n text_output += f\"PID:{conn['pid']} ({conn['process_name']}) \"\n text_output += f\"{conn['local_address']} -> {conn['remote_address']} \"\n text_output += f\"[{conn['status']}]\\n\"\n self._save_evidence(\"network_connections.txt\", text_output, \"network\")\n return connections\n\n def collect_arp_table(self):\n \"\"\"Collect ARP cache.\"\"\"\n self._log_action(\"Collecting\", \"ARP table\")\n try:\n if platform.system() == \"Windows\":\n result = subprocess.run([\"arp\", \"-a\"], capture_output=True, text=True, timeout=10)\n else:\n result = subprocess.run([\"ip\", \"neigh\"], capture_output=True, text=True, timeout=10)\n self._save_evidence(\"arp_cache.txt\", result.stdout, \"network\")\n except Exception as e:\n self._log_action(\"ARP collection failed\", str(e))\n\n def collect_routing_table(self):\n \"\"\"Collect routing table.\"\"\"\n self._log_action(\"Collecting\", \"Routing table\")\n try:\n if platform.system() == \"Windows\":\n result = subprocess.run([\"route\", \"print\"], capture_output=True, text=True, timeout=10)\n else:\n result = subprocess.run([\"ip\", \"route\", \"show\"], capture_output=True, text=True, timeout=10)\n self._save_evidence(\"routing_table.txt\", result.stdout, \"network\")\n except Exception as e:\n self._log_action(\"Routing table collection failed\", str(e))\n\n def collect_dns_cache(self):\n \"\"\"Collect DNS resolver cache.\"\"\"\n self._log_action(\"Collecting\", \"DNS cache\")\n try:\n if platform.system() == \"Windows\":\n result = subprocess.run([\"ipconfig\", \"/displaydns\"], capture_output=True, text=True, timeout=30)\n if result.stdout:\n self._save_evidence(\"dns_cache.txt\", result.stdout, \"network\")\n else:\n # Linux - attempt systemd-resolved\n result = subprocess.run(\n [\"systemd-resolve\", \"--statistics\"],\n capture_output=True, text=True, timeout=10,\n )\n if result.stdout:\n self._save_evidence(\"dns_stats.txt\", result.stdout, \"network\")\n except Exception as e:\n self._log_action(\"DNS cache collection failed\", str(e))\n\n def collect_running_processes(self):\n \"\"\"Collect detailed information about all running processes.\"\"\"\n self._log_action(\"Collecting\", \"Running processes\")\n processes = []\n for proc in psutil.process_iter(\n [\"pid\", \"ppid\", \"name\", \"username\", \"cmdline\", \"exe\",\n \"create_time\", \"status\", \"cpu_percent\", \"memory_percent\",\n \"num_threads\", \"connections\"]\n ):\n try:\n info = proc.info\n cmdline = \" \".join(info[\"cmdline\"]) if info[\"cmdline\"] else \"\"\n create_time = datetime.fromtimestamp(info[\"create_time\"]).isoformat() if info[\"create_time\"] else \"\"\n num_conns = len(info[\"connections\"]) if info[\"connections\"] else 0\n processes.append({\n \"pid\": info[\"pid\"],\n \"ppid\": info[\"ppid\"],\n \"name\": info[\"name\"],\n \"username\": info[\"username\"] or \"\",\n \"command_line\": cmdline[:500],\n \"executable\": info[\"exe\"] or \"\",\n \"create_time\": create_time,\n \"status\": info[\"status\"],\n \"cpu_percent\": info[\"cpu_percent\"],\n \"memory_percent\": round(info[\"memory_percent\"] or 0, 2),\n \"threads\": info[\"num_threads\"],\n \"network_connections\": num_conns,\n })\n except (psutil.NoSuchProcess, psutil.AccessDenied):\n continue\n self._save_evidence_csv(\"running_processes.csv\", processes, \"processes\")\n\n # Process tree text format\n tree_output = f\"Process Tree - {datetime.now(timezone.utc).isoformat()}\\n{'='*80}\\n\"\n tree_output += f\"Total processes: {len(processes)}\\n\\n\"\n for p in sorted(processes, key=lambda x: x[\"pid\"]):\n tree_output += f\"PID:{p['pid']} PPID:{p['ppid']} User:{p['username']} \"\n tree_output += f\"{p['name']} [{p['status']}]\\n\"\n if p[\"command_line\"]:\n tree_output += f\" CMD: {p['command_line']}\\n\"\n self._save_evidence(\"process_tree.txt\", tree_output, \"processes\")\n return processes\n\n def collect_open_files(self):\n \"\"\"Collect open file handles for all processes.\"\"\"\n self._log_action(\"Collecting\", \"Open file handles\")\n open_files = []\n for proc in psutil.process_iter([\"pid\", \"name\"]):\n try:\n for f in proc.open_files():\n open_files.append({\n \"pid\": proc.info[\"pid\"],\n \"process_name\": proc.info[\"name\"],\n \"file_path\": f.path,\n \"fd\": f.fd,\n \"mode\": getattr(f, \"mode\", \"\"),\n })\n except (psutil.NoSuchProcess, psutil.AccessDenied):\n continue\n if open_files:\n self._save_evidence_csv(\"open_files.csv\", open_files, \"processes\")\n return open_files\n\n def collect_logged_in_users(self):\n \"\"\"Collect information about currently logged-in users.\"\"\"\n self._log_action(\"Collecting\", \"Logged-in users\")\n users = []\n for user in psutil.users():\n users.append({\n \"username\": user.name,\n \"terminal\": user.terminal or \"\",\n \"host\": user.host or \"\",\n \"started\": datetime.fromtimestamp(user.started).isoformat(),\n \"pid\": getattr(user, \"pid\", \"\"),\n })\n self._save_evidence_csv(\"logged_in_users.csv\", users, \"users\")\n\n # Text format\n text = f\"Logged-in Users - {datetime.now(timezone.utc).isoformat()}\\n{'='*80}\\n\"\n for u in users:\n text += f\"User: {u['username']} | Terminal: {u['terminal']} | \"\n text += f\"Host: {u['host']} | Since: {u['started']}\\n\"\n self._save_evidence(\"logged_in_users.txt\", text, \"users\")\n return users\n\n def collect_system_info(self):\n \"\"\"Collect system configuration and state.\"\"\"\n self._log_action(\"Collecting\", \"System information\")\n boot_time = datetime.fromtimestamp(psutil.boot_time())\n info = {\n \"hostname\": self.hostname,\n \"platform\": platform.platform(),\n \"architecture\": platform.machine(),\n \"processor\": platform.processor(),\n \"python_version\": platform.python_version(),\n \"boot_time\": boot_time.isoformat(),\n \"uptime_seconds\": (datetime.now() - boot_time).total_seconds(),\n \"cpu_count_physical\": psutil.cpu_count(logical=False),\n \"cpu_count_logical\": psutil.cpu_count(logical=True),\n \"memory_total_gb\": round(psutil.virtual_memory().total / (1024**3), 2),\n \"memory_used_percent\": psutil.virtual_memory().percent,\n \"disk_partitions\": [\n {\"device\": p.device, \"mountpoint\": p.mountpoint, \"fstype\": p.fstype}\n for p in psutil.disk_partitions()\n ],\n \"network_interfaces\": {\n name: [{\"address\": addr.address, \"family\": str(addr.family)}\n for addr in addrs]\n for name, addrs in psutil.net_if_addrs().items()\n },\n }\n self._save_evidence(\n \"system_info.json\",\n json.dumps(info, indent=2),\n \"system\",\n )\n return info\n\n def collect_services(self):\n \"\"\"Collect running services (platform-specific).\"\"\"\n self._log_action(\"Collecting\", \"Running services\")\n try:\n if platform.system() == \"Windows\":\n result = subprocess.run(\n [\"sc\", \"queryex\", \"type=\", \"service\", \"state=\", \"all\"],\n capture_output=True, text=True, timeout=30,\n )\n self._save_evidence(\"services_all.txt\", result.stdout, \"system\")\n else:\n result = subprocess.run(\n [\"systemctl\", \"list-units\", \"--type=service\", \"--all\", \"--no-pager\"],\n capture_output=True, text=True, timeout=30,\n )\n self._save_evidence(\"systemd_services.txt\", result.stdout, \"system\")\n except Exception as e:\n self._log_action(\"Service collection failed\", str(e))\n\n def collect_scheduled_tasks(self):\n \"\"\"Collect scheduled tasks / cron jobs.\"\"\"\n self._log_action(\"Collecting\", \"Scheduled tasks\")\n try:\n if platform.system() == \"Windows\":\n result = subprocess.run(\n [\"schtasks\", \"/query\", \"/fo\", \"CSV\", \"/v\"],\n capture_output=True, text=True, timeout=30,\n )\n self._save_evidence(\"scheduled_tasks.csv\", result.stdout, \"system\")\n else:\n result = subprocess.run(\n [\"crontab\", \"-l\"],\n capture_output=True, text=True, timeout=10,\n )\n self._save_evidence(\"crontab.txt\", result.stdout or \"No crontab\", \"system\")\n except Exception as e:\n self._log_action(\"Scheduled task collection failed\", str(e))\n\n def collect_environment_variables(self):\n \"\"\"Collect environment variables.\"\"\"\n self._log_action(\"Collecting\", \"Environment variables\")\n env_data = \"\\n\".join(f\"{k}={v}\" for k, v in sorted(os.environ.items()))\n self._save_evidence(\"environment_variables.txt\", env_data, \"system\")\n\n def finalize(self):\n \"\"\"Generate evidence manifest and collection log.\"\"\"\n # Save collection log\n log_path = os.path.join(self.output_dir, \"collection_log.json\")\n with open(log_path, \"w\") as f:\n json.dump(self.collection_log, f, indent=2)\n\n # Save evidence manifest\n manifest_path = os.path.join(self.output_dir, \"evidence_manifest.json\")\n manifest = {\n \"case_id\": self.case_id,\n \"hostname\": self.hostname,\n \"collection_start\": self.collection_log[0][\"timestamp\"] if self.collection_log else \"\",\n \"collection_end\": datetime.now(timezone.utc).isoformat(),\n \"total_evidence_items\": len(self.evidence_manifest),\n \"evidence\": self.evidence_manifest,\n }\n with open(manifest_path, \"w\") as f:\n json.dump(manifest, f, indent=2)\n\n # Generate SHA256 manifest text file\n hash_manifest = os.path.join(self.output_dir, \"sha256_manifest.txt\")\n with open(hash_manifest, \"w\") as f:\n for item in self.evidence_manifest:\n f.write(f\"{item['sha256']} {item['filename']}\\n\")\n\n logger.info(f\"Collection complete. Evidence directory: {self.output_dir}\")\n logger.info(f\"Total evidence items: {len(self.evidence_manifest)}\")\n return self.output_dir\n\n\ndef main():\n parser = argparse.ArgumentParser(description=\"Volatile Evidence Collection Tool\")\n parser.add_argument(\"--case-id\", required=True, help=\"Case/incident ID\")\n parser.add_argument(\"--output-dir\", default=\"./evidence_collection\", help=\"Output directory\")\n parser.add_argument(\"--skip-memory\", action=\"store_true\", help=\"Skip memory dump (use dedicated tool)\")\n parser.add_argument(\"--collect-all\", action=\"store_true\", help=\"Collect all available evidence types\")\n\n args = parser.parse_args()\n\n collector = EvidenceCollector(args.output_dir, args.case_id)\n\n if not args.skip_memory:\n logger.info(\"NOTE: For memory acquisition, use dedicated tools (WinPmem/LiME) from forensic USB\")\n\n # Collect in order of volatility\n collector.collect_network_connections()\n collector.collect_arp_table()\n collector.collect_dns_cache()\n collector.collect_routing_table()\n collector.collect_running_processes()\n collector.collect_open_files()\n collector.collect_logged_in_users()\n collector.collect_system_info()\n collector.collect_services()\n collector.collect_scheduled_tasks()\n collector.collect_environment_variables()\n\n evidence_dir = collector.finalize()\n print(f\"\\nEvidence collection complete\")\n print(f\"Output directory: {evidence_dir}\")\n print(f\"Total items: {len(collector.evidence_manifest)}\")\n\n\nif __name__ == \"__main__\":\n main()\n","content_type":"text/x-python; charset=utf-8","language":"python","size":17820,"content_sha256":"7f01c6991d2cad5e8996d0742f91ceef5361f9c45ab72247bc1ba4cf244c8360"}],"content_json":{"type":"doc","content":[{"type":"heading","attrs":{"level":1},"content":[{"text":"Collecting Volatile Evidence from Compromised Hosts","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"When to Use","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Security incident confirmed and compromised host identified","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Before system isolation, shutdown, or remediation begins","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Memory-resident malware suspected (fileless attacks)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Need to capture network connections, running processes, and system state","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Legal proceedings may require forensic evidence preservation","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Incident requires root cause analysis with volatile data","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Prerequisites","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Forensic collection toolkit on USB or network share (trusted tools)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"WinPmem/LiME for memory acquisition","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Write-blocker or forensic workstation for disk imaging","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Chain of custody documentation forms","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Secure evidence storage with integrity verification","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Authorization to collect evidence (legal/HR approval for insider cases)","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Workflow","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 1: Prepare Collection Environment","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Mount forensic USB toolkit (do NOT install tools on compromised system)\n# Verify toolkit integrity\nsha256sum /mnt/forensic_usb/tools/* > /tmp/toolkit_hashes.txt\ndiff /mnt/forensic_usb/tools/known_good_hashes.txt /tmp/toolkit_hashes.txt\n\n# Create evidence output directory with timestamps\nEVIDENCE_DIR=\"/mnt/evidence/$(hostname)_$(date +%Y%m%d_%H%M%S)\"\nmkdir -p \"$EVIDENCE_DIR\"\necho \"Collection started: $(date -u)\" > \"$EVIDENCE_DIR/collection_log.txt\"\necho \"Collector: $(whoami)\" >> \"$EVIDENCE_DIR/collection_log.txt\"\necho \"System: $(hostname)\" >> \"$EVIDENCE_DIR/collection_log.txt\"","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 2: Capture System Memory (Highest Volatility)","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Windows - WinPmem memory acquisition\nwinpmem_mini_x64.exe \"$EVIDENCE_DIR\\memdump_$(hostname).raw\"\n\n# Linux - LiME kernel module for memory acquisition\ninsmod /mnt/forensic_usb/lime.ko \"path=$EVIDENCE_DIR/memdump_$(hostname).lime format=lime\"\n\n# Linux - Alternative using /proc/kcore\ndd if=/proc/kcore of=\"$EVIDENCE_DIR/kcore_dump.raw\" bs=1M\n\n# macOS - osxpmem\nosxpmem -o \"$EVIDENCE_DIR/memdump_$(hostname).aff4\"\n\n# Hash the memory dump immediately\nsha256sum \"$EVIDENCE_DIR/memdump_\"* > \"$EVIDENCE_DIR/memory_hash.sha256\"","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 3: Capture Network State","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Active network connections\n# Windows\nnetstat -anob > \"$EVIDENCE_DIR/netstat_connections.txt\" 2>&1\nGet-NetTCPConnection | Export-Csv \"$EVIDENCE_DIR/tcp_connections.csv\" -NoTypeInformation\nGet-NetUDPEndpoint | Export-Csv \"$EVIDENCE_DIR/udp_endpoints.csv\" -NoTypeInformation\n\n# Linux\nss -tulnp > \"$EVIDENCE_DIR/socket_stats.txt\"\nnetstat -anp > \"$EVIDENCE_DIR/netstat_all.txt\" 2>/dev/null\ncat /proc/net/tcp > \"$EVIDENCE_DIR/proc_net_tcp.txt\"\ncat /proc/net/udp > \"$EVIDENCE_DIR/proc_net_udp.txt\"\n\n# ARP cache\narp -a > \"$EVIDENCE_DIR/arp_cache.txt\"\n\n# Routing table\nroute print > \"$EVIDENCE_DIR/routing_table.txt\" # Windows\nip route show > \"$EVIDENCE_DIR/routing_table.txt\" # Linux\n\n# DNS cache\nipconfig /displaydns > \"$EVIDENCE_DIR/dns_cache.txt\" # Windows\n# Linux: varies by resolver, check systemd-resolve or nscd\nsystemd-resolve --statistics > \"$EVIDENCE_DIR/dns_stats.txt\" 2>/dev/null\n\n# Active firewall rules\nnetsh advfirewall show allprofiles > \"$EVIDENCE_DIR/firewall_rules.txt\" # Windows\niptables -L -n -v > \"$EVIDENCE_DIR/iptables_rules.txt\" # Linux","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 4: Capture Running Processes","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Windows - Detailed process list\ntasklist /V /FO CSV > \"$EVIDENCE_DIR/process_list_verbose.csv\"\nwmic process list full > \"$EVIDENCE_DIR/wmic_process_full.txt\"\nGet-Process | Select-Object Id,ProcessName,Path,StartTime,CPU,WorkingSet |\n Export-Csv \"$EVIDENCE_DIR/ps_processes.csv\" -NoTypeInformation\n\n# Windows - Process with command line and parent\nwmic process get ProcessId,Name,CommandLine,ParentProcessId,ExecutablePath /FORMAT:CSV > \\\n \"$EVIDENCE_DIR/process_commandlines.csv\"\n\n# Linux - Full process tree\nps auxwwf > \"$EVIDENCE_DIR/process_tree.txt\"\nps -eo pid,ppid,user,args --forest > \"$EVIDENCE_DIR/process_forest.txt\"\ncat /proc/*/cmdline 2>/dev/null | tr '\\0' ' ' > \"$EVIDENCE_DIR/proc_cmdline_all.txt\"\n\n# Process modules/DLLs loaded\n# Windows\nlistdlls.exe -accepteula > \"$EVIDENCE_DIR/loaded_dlls.txt\"\n# Linux\nfor pid in $(ls /proc/ | grep -E '^[0-9]+

Collecting Volatile Evidence from Compromised Hosts When to Use - Security incident confirmed and compromised host identified - Before system isolation, shutdown, or remediation begins - Memory-resident malware suspected (fileless attacks) - Need to capture network connections, running processes, and system state - Legal proceedings may require forensic evidence preservation - Incident requires root cause analysis with volatile data Prerequisites - Forensic collection toolkit on USB or network share (trusted tools) - WinPmem/LiME for memory acquisition - Write-blocker or forensic workstation…

); do\n echo \"=== PID $pid ===\" >> \"$EVIDENCE_DIR/proc_maps.txt\"\n cat \"/proc/$pid/maps\" 2>/dev/null >> \"$EVIDENCE_DIR/proc_maps.txt\"\ndone\n\n# Open file handles\nhandle.exe -accepteula > \"$EVIDENCE_DIR/open_handles.txt\" # Windows (Sysinternals)\nlsof > \"$EVIDENCE_DIR/open_files.txt\" # Linux","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 5: Capture Logged-in Users and Sessions","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Windows\nquery user > \"$EVIDENCE_DIR/logged_in_users.txt\"\nquery session > \"$EVIDENCE_DIR/active_sessions.txt\"\nnet session > \"$EVIDENCE_DIR/net_sessions.txt\" 2>&1\nnet use > \"$EVIDENCE_DIR/mapped_drives.txt\" 2>&1\n\n# Linux\nwho > \"$EVIDENCE_DIR/who_output.txt\"\nw > \"$EVIDENCE_DIR/w_output.txt\"\nlast -50 > \"$EVIDENCE_DIR/last_logins.txt\"\nlastlog > \"$EVIDENCE_DIR/lastlog.txt\"\ncat /var/log/auth.log | tail -200 > \"$EVIDENCE_DIR/recent_auth.txt\" 2>/dev/null","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 6: Capture System Configuration State","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# System time (critical for timeline)\ndate -u > \"$EVIDENCE_DIR/system_time_utc.txt\"\nw32tm /query /status > \"$EVIDENCE_DIR/ntp_status.txt\" # Windows\nntpq -p > \"$EVIDENCE_DIR/ntp_status.txt\" # Linux\n\n# Environment variables\nset > \"$EVIDENCE_DIR/environment_vars.txt\" # Windows\nenv > \"$EVIDENCE_DIR/environment_vars.txt\" # Linux\n\n# Scheduled tasks / Cron jobs\nschtasks /query /fo CSV /v > \"$EVIDENCE_DIR/scheduled_tasks.csv\" # Windows\ncrontab -l > \"$EVIDENCE_DIR/crontab_current.txt\" 2>/dev/null # Linux\nls -la /etc/cron.* > \"$EVIDENCE_DIR/cron_dirs.txt\" 2>/dev/null\n\n# Services\nsc queryex type=service state=all > \"$EVIDENCE_DIR/services_all.txt\" # Windows\nsystemctl list-units --type=service --all > \"$EVIDENCE_DIR/systemd_services.txt\" # Linux\n\n# Windows Registry - key autostart locations\nreg export \"HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run\" \"$EVIDENCE_DIR/reg_run_hklm.reg\" /y\nreg export \"HKCU\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run\" \"$EVIDENCE_DIR/reg_run_hkcu.reg\" /y\nreg export \"HKLM\\SYSTEM\\CurrentControlSet\\Services\" \"$EVIDENCE_DIR/reg_services.reg\" /y","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 7: Hash All Evidence and Document Chain of Custody","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Generate SHA256 hashes for all collected evidence\ncd \"$EVIDENCE_DIR\"\nsha256sum * > evidence_manifest.sha256\n\n# Create chain of custody record\ncat > \"$EVIDENCE_DIR/chain_of_custody.txt\" \u003c\u003c EOF\nCHAIN OF CUSTODY RECORD\n========================\nCase ID: IR-YYYY-NNN\nCollection Date: $(date -u)\nCollected By: $(whoami)\nSystem: $(hostname)\nSystem IP: $(hostname -I 2>/dev/null || ipconfig | grep IPv4)\nCollection Method: Live forensic collection via trusted USB toolkit\n\nEvidence Items:\n$(ls -la \"$EVIDENCE_DIR/\" | grep -v chain_of_custody)\n\nSHA256 Manifest: evidence_manifest.sha256\nTransfer: [TO BE COMPLETED]\nStorage Location: [TO BE COMPLETED]\nEOF","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Key Concepts","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Concept","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Description","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Order of Volatility","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"RFC 3227 - Collect most volatile data first: registers > cache > memory > disk","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Live Forensics","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Collecting evidence from a running system before shutdown","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Chain of Custody","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Documentation tracking evidence handling from collection to court","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Forensic Soundness","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Ensuring evidence collection doesn't alter the original evidence","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Trusted Tools","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Using verified tools from external media, not from the compromised system","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Evidence Integrity","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"SHA256 hashing of all evidence immediately after collection","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Locard's Exchange Principle","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Every contact leaves a trace - minimize investigator artifacts","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Tools & Systems","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Tool","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Purpose","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"WinPmem","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Windows memory acquisition","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"LiME (Linux Memory Extractor)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Linux kernel memory acquisition","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Sysinternals Suite","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Process, handle, and DLL analysis (Windows)","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Velociraptor","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Remote forensic collection at scale","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"KAPE (Kroll Artifact Parser)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Automated artifact collection on Windows","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"CyLR","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Cross-platform live response collection","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"GRR Rapid Response","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Remote live forensics framework","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Common Scenarios","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Fileless Malware Attack","type":"text","marks":[{"type":"strong"}]},{"text":": PowerShell-based attack with no files on disk. Memory dump is critical evidence containing the malicious scripts.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Active C2 Session","type":"text","marks":[{"type":"strong"}]},{"text":": Attacker has live connection. Network connections and process data reveal C2 infrastructure.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Insider Data Theft","type":"text","marks":[{"type":"strong"}]},{"text":": Employee copying files. Process list, mapped drives, and network connections show exfiltration activity.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Compromised Web Server","type":"text","marks":[{"type":"strong"}]},{"text":": Web shell detected. Memory may contain additional backdoors not yet written to disk.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Lateral Movement in Progress","type":"text","marks":[{"type":"strong"}]},{"text":": Attacker moving between systems. Authentication tokens and network sessions in memory reveal scope.","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Output Format","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Memory dump file (.raw or .lime format) with SHA256 hash","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Network state captures (connections, ARP, DNS, routes)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Process listings with command lines and parent processes","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"User session and authentication data","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"System configuration snapshots","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Evidence manifest with SHA256 checksums","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Chain of custody documentation","type":"text"}]}]}]},{"type":"hr","attrs":{"markup":"---"}}]},"metadata":{"date":"2026-06-05","name":"collecting-volatile-evidence-from-compromised-host","tags":["incident-response","dfir","forensics","volatile-evidence","memory-forensics","chain-of-custody"],"author":"@skillopedia","domain":"cybersecurity","source":{"stars":13207,"repo_name":"anthropic-cybersecurity-skills","origin_url":"https://github.com/mukul975/anthropic-cybersecurity-skills/blob/HEAD/skills/collecting-volatile-evidence-from-compromised-host/SKILL.md","repo_owner":"mukul975","body_sha256":"a85f4f663030ae9d11db9616e8622dc6cfc72a154a2b0235b4bcebc6ff256ea1","cluster_key":"f887019f14465336e6deb8ff176d7ad4e362a74517fc3bdfbb703344def416f7","clean_bundle":{"format":"clean-skill-bundle-v1","source":"mukul975/anthropic-cybersecurity-skills/skills/collecting-volatile-evidence-from-compromised-host/SKILL.md","attachments":[{"id":"f2e1a074-54fa-5d95-bb58-b11865550ad4","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/f2e1a074-54fa-5d95-bb58-b11865550ad4/attachment.md","path":"assets/template.md","size":2125,"sha256":"c5cebbbe7dcd08ba14425345e384a8ce1fd5b5fb1e0d4354aafba5ee911d3666","contentType":"text/markdown; charset=utf-8"},{"id":"ad769e4c-2151-52b5-80e7-9d7163e38a11","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/ad769e4c-2151-52b5-80e7-9d7163e38a11/attachment.md","path":"references/api-reference.md","size":2075,"sha256":"45d2b074e5f8ea3464ae922d449038b3220187fce5f21e1296795425b2cab44f","contentType":"text/markdown; charset=utf-8"},{"id":"f68d2bf9-a64e-5704-b51e-64a49e2acffc","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/f68d2bf9-a64e-5704-b51e-64a49e2acffc/attachment.md","path":"references/standards.md","size":3041,"sha256":"2c7a806a23c89a27c7573199e0de7d34913502f0d2396f9d55121b2b5d75a41d","contentType":"text/markdown; charset=utf-8"},{"id":"e82d3756-811e-519a-9f84-1f6587327a76","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/e82d3756-811e-519a-9f84-1f6587327a76/attachment.md","path":"references/workflows.md","size":4004,"sha256":"06bbfdb0e4a5608ceba1ea71c12f4777e6af9d33cb0b2558cf0ba3e4abe397e6","contentType":"text/markdown; charset=utf-8"},{"id":"af500188-a2f1-5cdc-8a26-d5dfdadcd8a7","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/af500188-a2f1-5cdc-8a26-d5dfdadcd8a7/attachment.py","path":"scripts/agent.py","size":7167,"sha256":"cf7b13f31250c2a2725e6a4a304bed95edab6818c96294285a3add429f9d504b","contentType":"text/x-python; charset=utf-8"},{"id":"19ae1bd6-513d-5c7e-9d3b-fc3d42279a28","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/19ae1bd6-513d-5c7e-9d3b-fc3d42279a28/attachment.py","path":"scripts/process.py","size":17820,"sha256":"7f01c6991d2cad5e8996d0742f91ceef5361f9c45ab72247bc1ba4cf244c8360","contentType":"text/x-python; charset=utf-8"}],"bundle_sha256":"216a746386ccb2a85b8aeb4c81f81c1f0321f05dd4ccf6d68871f8d2b46fbbd6","attachment_count":6,"text_attachments":6,"attachment_storage":"skillopedia-attachments-v1","binary_attachments":0,"excluded_attachments":[]},"cluster_size":2,"skill_md_path":"skills/collecting-volatile-evidence-from-compromised-host/SKILL.md","import_metadata":{"date":"2026-06-05","author":"@skillopedia","version":"v1","category":"security","category_label":"Security"},"exact_dupes_collapsed_into_this":1},"license":"Apache-2.0","version":"v1","category":"security","nist_csf":["RS.MA-01","RS.MA-02","RS.AN-03","RC.RP-01"],"subdomain":"incident-response","import_tag":"clean-skills-v1","description":"Collect volatile forensic evidence from a compromised system following order of volatility, preserving memory, network connections, processes, and system state before they are lost.","mitre_attack":["T1003","T1055","T1059","T1547"]}},"renderedAt":1782981848785}

Collecting Volatile Evidence from Compromised Hosts When to Use - Security incident confirmed and compromised host identified - Before system isolation, shutdown, or remediation begins - Memory-resident malware suspected (fileless attacks) - Need to capture network connections, running processes, and system state - Legal proceedings may require forensic evidence preservation - Incident requires root cause analysis with volatile data Prerequisites - Forensic collection toolkit on USB or network share (trusted tools) - WinPmem/LiME for memory acquisition - Write-blocker or forensic workstation…