mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-09-07 17:00:50 +03:00
Initial commit - 611 cybersecurity skills across all subdomains
This commit is contained in:
@@ -0,0 +1,261 @@
|
||||
---
|
||||
name: performing-windows-artifact-analysis-with-eric-zimmerman-tools
|
||||
description: Perform comprehensive Windows forensic artifact analysis using Eric Zimmerman's open-source EZ Tools suite including KAPE, MFTECmd, PECmd, LECmd, JLECmd, and Timeline Explorer for parsing registry hives, prefetch files, event logs, and file system metadata.
|
||||
domain: cybersecurity
|
||||
subdomain: digital-forensics
|
||||
tags: [eric-zimmerman, ez-tools, kape, mftecmd, pecmd, lecmd, jlecmd, registry-forensics, windows-forensics, timeline-explorer, dfir, artifact-analysis]
|
||||
version: "1.0"
|
||||
author: mahipal
|
||||
license: MIT
|
||||
---
|
||||
|
||||
# Performing Windows Artifact Analysis with Eric Zimmerman Tools
|
||||
|
||||
## Overview
|
||||
|
||||
Eric Zimmerman's EZ Tools suite is a collection of open-source forensic utilities that have become the global standard for Windows digital forensics investigations. Originally developed by a former FBI agent and current SANS instructor, these tools parse and analyze critical Windows artifacts including the Master File Table ($MFT), registry hives, prefetch files, event logs, shortcut (LNK) files, and jump lists. The suite integrates with KAPE (Kroll Artifact Parser and Extractor) for automated artifact collection and processing, producing structured CSV output that can be ingested into Timeline Explorer for visual analysis. EZ Tools are widely used by law enforcement, corporate incident responders, and forensic consultants worldwide.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Windows 10/11 or Windows Server 2016+ analysis workstation
|
||||
- .NET 6 Runtime installed (required for EZ Tools v2.x+)
|
||||
- Administrative privileges on the analysis workstation
|
||||
- Forensic disk image or triage collection from target system
|
||||
- At least 8 GB RAM (16 GB recommended for large datasets)
|
||||
- Familiarity with NTFS file system structures and Windows internals
|
||||
|
||||
## Tool Suite Components
|
||||
|
||||
### KAPE (Kroll Artifact Parser and Extractor)
|
||||
|
||||
KAPE is the primary orchestration tool that automates artifact collection (Targets) and processing (Modules). It uses configuration files (.tkape and .mkape) to define what artifacts to collect and which EZ Tools to run against them.
|
||||
|
||||
**Installation and Setup:**
|
||||
|
||||
```powershell
|
||||
# Download KAPE from https://www.kroll.com/en/services/cyber-risk/incident-response-litigation-support/kroll-artifact-parser-extractor-kape
|
||||
# Extract to C:\Tools\KAPE
|
||||
|
||||
# Update KAPE targets and modules
|
||||
C:\Tools\KAPE\gkape.exe # GUI version
|
||||
C:\Tools\KAPE\kape.exe # CLI version
|
||||
|
||||
# Sync latest EZ Tools binaries
|
||||
C:\Tools\KAPE\Get-KAPEUpdate.ps1
|
||||
```
|
||||
|
||||
**Running KAPE Collection and Processing:**
|
||||
|
||||
```powershell
|
||||
# Collect artifacts from E: drive (mounted forensic image) and process with EZ Tools
|
||||
kape.exe --tsource E: --tdest C:\Cases\Case001\Collection --target KapeTriage --mdest C:\Cases\Case001\Processed --module !EZParser
|
||||
|
||||
# Collect specific artifact categories
|
||||
kape.exe --tsource E: --tdest C:\Cases\Case001\Collection --target FileSystem,RegistryHives,EventLogs --mdest C:\Cases\Case001\Processed --module MFTECmd,RECmd,EvtxECmd
|
||||
|
||||
# Live system triage collection (run as administrator)
|
||||
kape.exe --tsource C: --tdest D:\LiveTriage\Collection --target KapeTriage --mdest D:\LiveTriage\Processed --module !EZParser --vhdx LiveTriageImage
|
||||
```
|
||||
|
||||
### MFTECmd - Master File Table Parser
|
||||
|
||||
MFTECmd parses the NTFS $MFT, $J (USN Journal), $Boot, $SDS, and $LogFile into human-readable CSV format.
|
||||
|
||||
```powershell
|
||||
# Parse the $MFT file
|
||||
MFTECmd.exe -f "C:\Cases\Evidence\$MFT" --csv C:\Cases\Output --csvf MFT_output.csv
|
||||
|
||||
# Parse the USN Journal ($J)
|
||||
MFTECmd.exe -f "C:\Cases\Evidence\$J" --csv C:\Cases\Output --csvf USNJournal_output.csv
|
||||
|
||||
# Parse $Boot for volume information
|
||||
MFTECmd.exe -f "C:\Cases\Evidence\$Boot" --csv C:\Cases\Output --csvf Boot_output.csv
|
||||
|
||||
# Parse $SDS for security descriptors
|
||||
MFTECmd.exe -f "C:\Cases\Evidence\$SDS" --csv C:\Cases\Output --csvf SDS_output.csv
|
||||
```
|
||||
|
||||
**Key Fields in MFT Output:**
|
||||
|
||||
| Field | Description |
|
||||
|-------|-------------|
|
||||
| EntryNumber | MFT record number |
|
||||
| ParentEntryNumber | Parent directory MFT record |
|
||||
| InUse | Whether the record is active or deleted |
|
||||
| FileName | Name of the file or directory |
|
||||
| Created0x10 | $STANDARD_INFORMATION creation timestamp |
|
||||
| Created0x30 | $FILE_NAME creation timestamp |
|
||||
| LastModified0x10 | $STANDARD_INFORMATION modification timestamp |
|
||||
| IsDirectory | Boolean indicating directory or file |
|
||||
| FileSize | Logical file size in bytes |
|
||||
| Extension | File extension |
|
||||
|
||||
### PECmd - Prefetch File Parser
|
||||
|
||||
PECmd parses Windows Prefetch files (.pf) to provide evidence of program execution, including run counts and timestamps.
|
||||
|
||||
```powershell
|
||||
# Parse all prefetch files from a directory
|
||||
PECmd.exe -d "C:\Cases\Evidence\Windows\Prefetch" --csv C:\Cases\Output --csvf Prefetch_output.csv
|
||||
|
||||
# Parse a single prefetch file with verbose output
|
||||
PECmd.exe -f "C:\Cases\Evidence\Windows\Prefetch\CMD.EXE-4A81B364.pf" --json C:\Cases\Output
|
||||
|
||||
# Parse prefetch with keyword filtering
|
||||
PECmd.exe -d "C:\Cases\Evidence\Windows\Prefetch" -k "powershell,cmd,wscript,cscript,mshta" --csv C:\Cases\Output --csvf SuspiciousExec.csv
|
||||
```
|
||||
|
||||
### RECmd - Registry Explorer Command Line
|
||||
|
||||
RECmd processes Windows registry hives using batch files that define which keys and values to extract.
|
||||
|
||||
```powershell
|
||||
# Process all registry hives with the default batch file
|
||||
RECmd.exe --bn C:\Tools\KAPE\Modules\bin\RECmd\BatchExamples\RECmd_Batch_MC.reb -d "C:\Cases\Evidence\Registry" --csv C:\Cases\Output --csvf Registry_output.csv
|
||||
|
||||
# Process a single NTUSER.DAT hive
|
||||
RECmd.exe -f "C:\Cases\Evidence\Users\suspect\NTUSER.DAT" --bn C:\Tools\KAPE\Modules\bin\RECmd\BatchExamples\RECmd_Batch_MC.reb --csv C:\Cases\Output
|
||||
|
||||
# Process SYSTEM hive for USB device history
|
||||
RECmd.exe -f "C:\Cases\Evidence\Registry\SYSTEM" --bn C:\Tools\KAPE\Modules\bin\RECmd\BatchExamples\RECmd_Batch_MC.reb --csv C:\Cases\Output
|
||||
```
|
||||
|
||||
### EvtxECmd - Windows Event Log Parser
|
||||
|
||||
EvtxECmd parses Windows Event Log (.evtx) files into structured CSV format with customizable event ID maps.
|
||||
|
||||
```powershell
|
||||
# Parse all event logs from a directory
|
||||
EvtxECmd.exe -d "C:\Cases\Evidence\Windows\System32\winevt\Logs" --csv C:\Cases\Output --csvf EventLogs_output.csv
|
||||
|
||||
# Parse a single event log
|
||||
EvtxECmd.exe -f "C:\Cases\Evidence\Security.evtx" --csv C:\Cases\Output --csvf Security_output.csv
|
||||
|
||||
# Parse with custom maps for enhanced field extraction
|
||||
EvtxECmd.exe -d "C:\Cases\Evidence\Logs" --csv C:\Cases\Output --maps C:\Tools\KAPE\Modules\bin\EvtxECmd\Maps
|
||||
```
|
||||
|
||||
### LECmd and JLECmd - Shortcut and Jump List Parsers
|
||||
|
||||
```powershell
|
||||
# Parse LNK files from Recent directory
|
||||
LECmd.exe -d "C:\Cases\Evidence\Users\suspect\AppData\Roaming\Microsoft\Windows\Recent" --csv C:\Cases\Output --csvf LNK_output.csv
|
||||
|
||||
# Parse Jump Lists (automatic destinations)
|
||||
JLECmd.exe -d "C:\Cases\Evidence\Users\suspect\AppData\Roaming\Microsoft\Windows\Recent\AutomaticDestinations" --csv C:\Cases\Output --csvf JumpLists_auto.csv
|
||||
|
||||
# Parse Jump Lists (custom destinations)
|
||||
JLECmd.exe -d "C:\Cases\Evidence\Users\suspect\AppData\Roaming\Microsoft\Windows\Recent\CustomDestinations" --csv C:\Cases\Output --csvf JumpLists_custom.csv
|
||||
```
|
||||
|
||||
### SBECmd - Shellbag Explorer Command Line
|
||||
|
||||
```powershell
|
||||
# Parse shellbags from a directory of registry hives
|
||||
SBECmd.exe -d "C:\Cases\Evidence\Registry" --csv C:\Cases\Output --csvf Shellbags_output.csv
|
||||
|
||||
# Parse shellbags from a live system (requires admin)
|
||||
SBECmd.exe --live --csv C:\Cases\Output --csvf LiveShellbags_output.csv
|
||||
```
|
||||
|
||||
### Timeline Explorer - Visual Analysis
|
||||
|
||||
Timeline Explorer is the GUI tool for analyzing CSV output from all EZ Tools. It supports filtering, sorting, column grouping, and conditional formatting.
|
||||
|
||||
```powershell
|
||||
# Launch Timeline Explorer and open CSV output
|
||||
TimelineExplorer.exe "C:\Cases\Output\MFT_output.csv"
|
||||
```
|
||||
|
||||
**Key Timeline Explorer Features:**
|
||||
- Column-level filtering with regular expressions
|
||||
- Conditional formatting for timestamp anomalies
|
||||
- Multi-column sorting for chronological analysis
|
||||
- Export filtered results to new CSV files
|
||||
- Bookmarking rows of interest
|
||||
|
||||
## Investigation Workflow
|
||||
|
||||
### Step 1: Artifact Collection with KAPE
|
||||
|
||||
```powershell
|
||||
# Full triage collection from forensic image mounted at E:
|
||||
kape.exe --tsource E: --tdest C:\Cases\Case001\Collected --target KapeTriage --vhdx TriageImage --zv false
|
||||
```
|
||||
|
||||
### Step 2: Artifact Processing with EZ Tools
|
||||
|
||||
```powershell
|
||||
# Process all collected artifacts
|
||||
kape.exe --msource C:\Cases\Case001\Collected --mdest C:\Cases\Case001\Processed --module !EZParser
|
||||
```
|
||||
|
||||
### Step 3: Timeline Analysis
|
||||
|
||||
1. Open processed CSV files in Timeline Explorer
|
||||
2. Sort by timestamp columns to establish chronological order
|
||||
3. Filter for specific file extensions, paths, or event IDs
|
||||
4. Cross-reference MFT timestamps with event log entries
|
||||
5. Identify timestomping by comparing $SI and $FN timestamps
|
||||
6. Document findings with bookmarks and exported filtered views
|
||||
|
||||
### Step 4: Timestomping Detection
|
||||
|
||||
```powershell
|
||||
# In Timeline Explorer, compare these columns:
|
||||
# Created0x10 ($STANDARD_INFORMATION) vs Created0x30 ($FILE_NAME)
|
||||
# If Created0x10 < Created0x30, timestomping is indicated
|
||||
# $FILE_NAME timestamps are harder to manipulate than $STANDARD_INFORMATION
|
||||
```
|
||||
|
||||
## Forensic Artifacts Reference
|
||||
|
||||
| Tool | Artifact | Location |
|
||||
|------|----------|----------|
|
||||
| MFTECmd | $MFT | Root of NTFS volume |
|
||||
| MFTECmd | $J (USN Journal) | $Extend\$UsnJrnl:$J |
|
||||
| PECmd | Prefetch files | C:\Windows\Prefetch\*.pf |
|
||||
| RECmd | NTUSER.DAT | C:\Users\{user}\NTUSER.DAT |
|
||||
| RECmd | SYSTEM hive | C:\Windows\System32\config\SYSTEM |
|
||||
| RECmd | SAM hive | C:\Windows\System32\config\SAM |
|
||||
| RECmd | SOFTWARE hive | C:\Windows\System32\config\SOFTWARE |
|
||||
| EvtxECmd | Event logs | C:\Windows\System32\winevt\Logs\*.evtx |
|
||||
| LECmd | LNK files | C:\Users\{user}\AppData\Roaming\Microsoft\Windows\Recent\ |
|
||||
| JLECmd | Jump lists | C:\Users\{user}\AppData\Roaming\Microsoft\Windows\Recent\AutomaticDestinations\ |
|
||||
| SBECmd | Shellbags | NTUSER.DAT and UsrClass.dat registry hives |
|
||||
|
||||
## Common Investigation Scenarios
|
||||
|
||||
### Malware Execution Evidence
|
||||
1. Parse Prefetch with PECmd to identify executed binaries
|
||||
2. Cross-reference with MFT for file creation timestamps
|
||||
3. Check Amcache.hve with RECmd for SHA1 hashes of executables
|
||||
4. Correlate with Event Log entries for process creation (Event ID 4688)
|
||||
|
||||
### Data Exfiltration Investigation
|
||||
1. Parse USN Journal with MFTECmd for file rename/delete operations
|
||||
2. Analyze LNK files with LECmd for recently accessed documents
|
||||
3. Review Shellbags with SBECmd for directory browsing activity
|
||||
4. Check for USB device connections in SYSTEM registry with RECmd
|
||||
|
||||
### Lateral Movement Detection
|
||||
1. Parse Security.evtx with EvtxECmd for logon events (4624, 4625)
|
||||
2. Analyze RDP-related event logs (Microsoft-Windows-TerminalServices)
|
||||
3. Cross-reference with network share access from SMB logs
|
||||
4. Review scheduled tasks and services for persistence mechanisms
|
||||
|
||||
## Output Format and Integration
|
||||
|
||||
All EZ Tools produce CSV output that can be:
|
||||
- Analyzed in Timeline Explorer for visual investigation
|
||||
- Imported into Splunk, Elastic, or other SIEM platforms
|
||||
- Processed by Python/PowerShell scripts for automated analysis
|
||||
- Combined into super timelines using log2timeline/Plaso
|
||||
|
||||
## References
|
||||
|
||||
- Eric Zimmerman's Tools: https://ericzimmerman.github.io/
|
||||
- KAPE Documentation: https://ericzimmerman.github.io/KapeDocs/
|
||||
- SANS EZ Tools Training: https://www.sans.org/tools/ez-tools
|
||||
- SANS FOR508: Advanced Incident Response and Threat Hunting
|
||||
- SANS FOR498: Battlefield Forensics & Data Acquisition
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
# EZ Tools Forensic Analysis Report Template
|
||||
|
||||
## Case Information
|
||||
|
||||
| Field | Value |
|
||||
|-------|-------|
|
||||
| Case Number | |
|
||||
| Examiner | |
|
||||
| Date of Analysis | |
|
||||
| Evidence Source | |
|
||||
| Evidence Hash (SHA-256) | |
|
||||
| EZ Tools Version | |
|
||||
|
||||
## Artifacts Processed
|
||||
|
||||
| Artifact | Tool Used | Status | Records Parsed |
|
||||
|----------|-----------|--------|----------------|
|
||||
| $MFT | MFTECmd | | |
|
||||
| $J (USN Journal) | MFTECmd | | |
|
||||
| Prefetch Files | PECmd | | |
|
||||
| LNK Files | LECmd | | |
|
||||
| Jump Lists | JLECmd | | |
|
||||
| Event Logs | EvtxECmd | | |
|
||||
| Registry Hives | RECmd | | |
|
||||
| Shellbags | SBECmd | | |
|
||||
| Recycle Bin | RBCmd | | |
|
||||
| Amcache | AmcacheParser | | |
|
||||
| ShimCache | AppCompatCacheParser | | |
|
||||
|
||||
## Key Findings
|
||||
|
||||
### Program Execution Evidence
|
||||
| Executable | First Execution | Last Execution | Run Count | Source |
|
||||
|-----------|----------------|---------------|-----------|--------|
|
||||
| | | | | |
|
||||
|
||||
### Timestomping Indicators
|
||||
| File | $SI Created | $FN Created | Anomaly |
|
||||
|------|------------|------------|---------|
|
||||
| | | | |
|
||||
|
||||
### User Activity Timeline
|
||||
| Timestamp | Activity | Artifact Source | Details |
|
||||
|-----------|----------|----------------|---------|
|
||||
| | | | |
|
||||
|
||||
### Lateral Movement Indicators
|
||||
| Timestamp | Source IP | Target System | Logon Type | Event ID |
|
||||
|-----------|----------|--------------|------------|----------|
|
||||
| | | | | |
|
||||
|
||||
### USB Device Connections
|
||||
| Device | Serial Number | First Connected | Last Connected | Volume Name |
|
||||
|--------|--------------|----------------|---------------|-------------|
|
||||
| | | | | |
|
||||
|
||||
## Conclusion
|
||||
|
||||
_(Summary of findings based on artifact analysis)_
|
||||
|
||||
## Chain of Custody
|
||||
|
||||
| Date/Time | Action | Performed By | Notes |
|
||||
|-----------|--------|-------------|-------|
|
||||
| | | | |
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
# Standards and References - EZ Tools Windows Forensics
|
||||
|
||||
## Industry Standards
|
||||
|
||||
### NIST SP 800-86 - Guide to Integrating Forensic Techniques
|
||||
- Framework for collecting, examining, and analyzing digital evidence
|
||||
- Defines procedures for forensic acquisition and chain of custody
|
||||
- EZ Tools align with NIST evidence handling and analysis guidelines
|
||||
|
||||
### ISO/IEC 27037 - Digital Evidence Collection
|
||||
- International standard for identification, collection, acquisition, and preservation
|
||||
- KAPE collection follows ISO 27037 acquisition methodology
|
||||
- Timeline Explorer output supports ISO-compliant reporting
|
||||
|
||||
### SWGDE Best Practices for Computer Forensics
|
||||
- Scientific Working Group on Digital Evidence guidelines
|
||||
- Defines validation requirements for forensic tools
|
||||
- EZ Tools undergo community-driven validation testing
|
||||
|
||||
## Tool References
|
||||
|
||||
### EZ Tools Suite Components
|
||||
| Tool | Version | Purpose |
|
||||
|------|---------|---------|
|
||||
| KAPE | 1.3+ | Artifact collection and processing orchestration |
|
||||
| MFTECmd | 1.2+ | NTFS Master File Table parser |
|
||||
| PECmd | 1.5+ | Windows Prefetch file parser |
|
||||
| RECmd | 2.0+ | Registry hive parser with batch processing |
|
||||
| EvtxECmd | 1.5+ | Windows Event Log parser with maps |
|
||||
| LECmd | 1.5+ | LNK shortcut file parser |
|
||||
| JLECmd | 1.5+ | Jump List parser |
|
||||
| SBECmd | 2.0+ | Shellbag parser |
|
||||
| Timeline Explorer | 2.0+ | CSV analysis and visualization |
|
||||
| Registry Explorer | 2.0+ | GUI registry hive viewer |
|
||||
| ShellBags Explorer | 2.0+ | GUI shellbag viewer |
|
||||
| AmcacheParser | 1.5+ | Amcache.hve parser |
|
||||
| AppCompatCacheParser | 1.5+ | ShimCache parser |
|
||||
| WxTCmd | 1.0+ | Windows Timeline database parser |
|
||||
| RBCmd | 1.5+ | Recycle Bin artifact parser |
|
||||
| bstrings | 1.5+ | Binary string extraction |
|
||||
|
||||
### SANS Training Courses
|
||||
- FOR500: Windows Forensic Analysis
|
||||
- FOR508: Advanced Incident Response, Threat Hunting, and Digital Forensics
|
||||
- FOR498: Battlefield Forensics & Data Acquisition
|
||||
- FOR610: Reverse-Engineering Malware
|
||||
|
||||
### MITRE ATT&CK Relevance
|
||||
- T1070 - Indicator Removal: Timestomping detection via MFT analysis
|
||||
- T1547 - Boot or Logon Autostart Execution: Registry persistence detection
|
||||
- T1053 - Scheduled Task/Job: Task scheduler artifact analysis
|
||||
- T1059 - Command and Scripting Interpreter: Prefetch execution evidence
|
||||
- T1021 - Remote Services: Lateral movement via event log analysis
|
||||
|
||||
## Official Resources
|
||||
- Eric Zimmerman's GitHub: https://ericzimmerman.github.io/
|
||||
- KAPE GitHub Targets/Modules: https://github.com/EricZimmerman/KapeFiles
|
||||
- EZ Tools Changelog: https://ericzimmerman.github.io/#!index.md
|
||||
- SANS DFIR Blog: https://www.sans.org/blog/?focus-area=digital-forensics
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
# Workflows - EZ Tools Windows Forensic Analysis
|
||||
|
||||
## Workflow 1: Full Triage Collection and Processing
|
||||
|
||||
```
|
||||
Step 1: Mount forensic image as read-only drive (E:)
|
||||
|
|
||||
Step 2: Run KAPE with KapeTriage target
|
||||
|-- Collects: $MFT, $J, Registry, Event Logs, Prefetch, LNK, Jump Lists
|
||||
|
|
||||
Step 3: Run KAPE with !EZParser module
|
||||
|-- Processes all collected artifacts with appropriate EZ Tools
|
||||
|
|
||||
Step 4: Open CSV outputs in Timeline Explorer
|
||||
|-- Sort by timestamp, filter by artifact type
|
||||
|
|
||||
Step 5: Build investigation timeline
|
||||
|-- Cross-reference MFT, Event Logs, Prefetch, Registry
|
||||
|
|
||||
Step 6: Document findings and export filtered results
|
||||
```
|
||||
|
||||
## Workflow 2: Timestomping Detection
|
||||
|
||||
```
|
||||
Step 1: Parse $MFT with MFTECmd
|
||||
|
|
||||
Step 2: Open MFT CSV in Timeline Explorer
|
||||
|
|
||||
Step 3: Compare $SI timestamps (Created0x10) vs $FN timestamps (Created0x30)
|
||||
|-- Flag entries where Created0x10 < Created0x30
|
||||
|-- Flag entries where all four $SI timestamps are identical
|
||||
|
|
||||
Step 4: Cross-reference flagged files with USN Journal entries
|
||||
|
|
||||
Step 5: Verify with event log correlation (process creation, file access)
|
||||
```
|
||||
|
||||
## Workflow 3: Program Execution Timeline
|
||||
|
||||
```
|
||||
Step 1: Parse Prefetch with PECmd
|
||||
|
|
||||
Step 2: Parse Amcache.hve with AmcacheParser
|
||||
|
|
||||
Step 3: Parse ShimCache with AppCompatCacheParser
|
||||
|
|
||||
Step 4: Parse UserAssist from NTUSER.DAT with RECmd
|
||||
|
|
||||
Step 5: Merge and correlate execution timestamps
|
||||
|-- Prefetch: Run count + last 8 execution times
|
||||
|-- Amcache: First execution + SHA1 hash
|
||||
|-- ShimCache: Last modified time (execution indicator)
|
||||
|-- UserAssist: GUI program execution tracking
|
||||
|
|
||||
Step 6: Build execution timeline in Timeline Explorer
|
||||
```
|
||||
|
||||
## Workflow 4: Lateral Movement Investigation
|
||||
|
||||
```
|
||||
Step 1: Parse Security.evtx with EvtxECmd
|
||||
|-- Filter Event ID 4624 (Logon Type 3, 10)
|
||||
|-- Filter Event ID 4625 (Failed logons)
|
||||
|
|
||||
Step 2: Parse TerminalServices event logs
|
||||
|-- Microsoft-Windows-TerminalServices-LocalSessionManager
|
||||
|-- Microsoft-Windows-TerminalServices-RDPClient
|
||||
|
|
||||
Step 3: Correlate with registry RDP MRU entries
|
||||
|-- NTUSER.DAT\Software\Microsoft\Terminal Server Client\Servers
|
||||
|
|
||||
Step 4: Analyze LNK files for network path access
|
||||
|
|
||||
Step 5: Review scheduled task creation from event logs
|
||||
|
|
||||
Step 6: Map lateral movement path across systems
|
||||
```
|
||||
|
||||
## Workflow 5: USB Device Investigation
|
||||
|
||||
```
|
||||
Step 1: Parse SYSTEM hive with RECmd
|
||||
|-- SYSTEM\CurrentControlSet\Enum\USBSTOR
|
||||
|-- SYSTEM\CurrentControlSet\Enum\USB
|
||||
|-- SYSTEM\MountedDevices
|
||||
|
|
||||
Step 2: Parse NTUSER.DAT with RECmd
|
||||
|-- MountPoints2 for user-level device associations
|
||||
|
|
||||
Step 3: Parse setupapi.dev.log for device installation timestamps
|
||||
|
|
||||
Step 4: Analyze LNK files referencing removable drive letters
|
||||
|
|
||||
Step 5: Check Shellbags for folder browsing on USB devices
|
||||
|
|
||||
Step 6: Correlate with Event Logs (Microsoft-Windows-Partition/Diagnostic)
|
||||
```
|
||||
+295
@@ -0,0 +1,295 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
EZ Tools Forensic Artifact Processor
|
||||
|
||||
Automates the execution of Eric Zimmerman's tools against collected
|
||||
forensic artifacts and generates consolidated analysis reports.
|
||||
"""
|
||||
|
||||
import subprocess
|
||||
import csv
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
import hashlib
|
||||
from pathlib import Path
|
||||
from datetime import datetime
|
||||
from collections import defaultdict
|
||||
|
||||
|
||||
class EZToolsProcessor:
|
||||
"""Orchestrates EZ Tools processing against forensic artifact collections."""
|
||||
|
||||
def __init__(self, ez_tools_path: str, evidence_path: str, output_path: str):
|
||||
self.ez_tools_path = Path(ez_tools_path)
|
||||
self.evidence_path = Path(evidence_path)
|
||||
self.output_path = Path(output_path)
|
||||
self.output_path.mkdir(parents=True, exist_ok=True)
|
||||
self.results = {}
|
||||
self.tools = {
|
||||
"MFTECmd": self.ez_tools_path / "MFTECmd.exe",
|
||||
"PECmd": self.ez_tools_path / "PECmd.exe",
|
||||
"LECmd": self.ez_tools_path / "LECmd.exe",
|
||||
"JLECmd": self.ez_tools_path / "JLECmd.exe",
|
||||
"SBECmd": self.ez_tools_path / "SBECmd.exe",
|
||||
"EvtxECmd": self.ez_tools_path / "EvtxECmd.exe",
|
||||
"RECmd": self.ez_tools_path / "RECmd.exe",
|
||||
"RBCmd": self.ez_tools_path / "RBCmd.exe",
|
||||
"AmcacheParser": self.ez_tools_path / "AmcacheParser.exe",
|
||||
"AppCompatCacheParser": self.ez_tools_path / "AppCompatCacheParser.exe",
|
||||
}
|
||||
|
||||
def verify_tools(self) -> dict:
|
||||
"""Verify which EZ Tools are available on the system."""
|
||||
availability = {}
|
||||
for name, path in self.tools.items():
|
||||
availability[name] = path.exists()
|
||||
return availability
|
||||
|
||||
def run_tool(self, tool_name: str, args: list) -> dict:
|
||||
"""Execute an EZ Tool with given arguments."""
|
||||
tool_path = self.tools.get(tool_name)
|
||||
if not tool_path or not tool_path.exists():
|
||||
return {"status": "error", "message": f"{tool_name} not found at {tool_path}"}
|
||||
|
||||
cmd = [str(tool_path)] + args
|
||||
try:
|
||||
result = subprocess.run(
|
||||
cmd,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=300
|
||||
)
|
||||
return {
|
||||
"status": "success" if result.returncode == 0 else "error",
|
||||
"stdout": result.stdout,
|
||||
"stderr": result.stderr,
|
||||
"returncode": result.returncode
|
||||
}
|
||||
except subprocess.TimeoutExpired:
|
||||
return {"status": "error", "message": f"{tool_name} timed out after 300 seconds"}
|
||||
except Exception as e:
|
||||
return {"status": "error", "message": str(e)}
|
||||
|
||||
def process_mft(self, mft_path: str = None) -> dict:
|
||||
"""Parse the $MFT file with MFTECmd."""
|
||||
if mft_path is None:
|
||||
mft_candidates = list(self.evidence_path.rglob("$MFT"))
|
||||
if not mft_candidates:
|
||||
return {"status": "skipped", "message": "$MFT not found"}
|
||||
mft_path = str(mft_candidates[0])
|
||||
|
||||
output_file = "MFT_output.csv"
|
||||
args = ["-f", mft_path, "--csv", str(self.output_path), "--csvf", output_file]
|
||||
result = self.run_tool("MFTECmd", args)
|
||||
result["output_file"] = str(self.output_path / output_file)
|
||||
self.results["MFT"] = result
|
||||
return result
|
||||
|
||||
def process_usn_journal(self, journal_path: str = None) -> dict:
|
||||
"""Parse the USN Journal ($J) with MFTECmd."""
|
||||
if journal_path is None:
|
||||
j_candidates = list(self.evidence_path.rglob("$J"))
|
||||
if not j_candidates:
|
||||
return {"status": "skipped", "message": "$J not found"}
|
||||
journal_path = str(j_candidates[0])
|
||||
|
||||
output_file = "USNJournal_output.csv"
|
||||
args = ["-f", journal_path, "--csv", str(self.output_path), "--csvf", output_file]
|
||||
result = self.run_tool("MFTECmd", args)
|
||||
result["output_file"] = str(self.output_path / output_file)
|
||||
self.results["USNJournal"] = result
|
||||
return result
|
||||
|
||||
def process_prefetch(self, prefetch_dir: str = None) -> dict:
|
||||
"""Parse Prefetch files with PECmd."""
|
||||
if prefetch_dir is None:
|
||||
pf_candidates = list(self.evidence_path.rglob("Prefetch"))
|
||||
if not pf_candidates:
|
||||
return {"status": "skipped", "message": "Prefetch directory not found"}
|
||||
prefetch_dir = str(pf_candidates[0])
|
||||
|
||||
output_file = "Prefetch_output.csv"
|
||||
args = ["-d", prefetch_dir, "--csv", str(self.output_path), "--csvf", output_file]
|
||||
result = self.run_tool("PECmd", args)
|
||||
result["output_file"] = str(self.output_path / output_file)
|
||||
self.results["Prefetch"] = result
|
||||
return result
|
||||
|
||||
def process_lnk_files(self, lnk_dir: str = None) -> dict:
|
||||
"""Parse LNK shortcut files with LECmd."""
|
||||
if lnk_dir is None:
|
||||
recent_candidates = list(self.evidence_path.rglob("Recent"))
|
||||
if not recent_candidates:
|
||||
return {"status": "skipped", "message": "Recent directory not found"}
|
||||
lnk_dir = str(recent_candidates[0])
|
||||
|
||||
output_file = "LNK_output.csv"
|
||||
args = ["-d", lnk_dir, "--csv", str(self.output_path), "--csvf", output_file]
|
||||
result = self.run_tool("LECmd", args)
|
||||
result["output_file"] = str(self.output_path / output_file)
|
||||
self.results["LNK"] = result
|
||||
return result
|
||||
|
||||
def process_jump_lists(self, jl_dir: str = None) -> dict:
|
||||
"""Parse Jump List files with JLECmd."""
|
||||
if jl_dir is None:
|
||||
auto_dest = list(self.evidence_path.rglob("AutomaticDestinations"))
|
||||
if not auto_dest:
|
||||
return {"status": "skipped", "message": "AutomaticDestinations not found"}
|
||||
jl_dir = str(auto_dest[0])
|
||||
|
||||
output_file = "JumpLists_output.csv"
|
||||
args = ["-d", jl_dir, "--csv", str(self.output_path), "--csvf", output_file]
|
||||
result = self.run_tool("JLECmd", args)
|
||||
result["output_file"] = str(self.output_path / output_file)
|
||||
self.results["JumpLists"] = result
|
||||
return result
|
||||
|
||||
def process_event_logs(self, evtx_dir: str = None) -> dict:
|
||||
"""Parse Windows Event Logs with EvtxECmd."""
|
||||
if evtx_dir is None:
|
||||
logs_candidates = list(self.evidence_path.rglob("winevt"))
|
||||
if logs_candidates:
|
||||
evtx_dir = str(logs_candidates[0] / "Logs")
|
||||
else:
|
||||
evtx_files = list(self.evidence_path.rglob("*.evtx"))
|
||||
if not evtx_files:
|
||||
return {"status": "skipped", "message": "Event logs not found"}
|
||||
evtx_dir = str(evtx_files[0].parent)
|
||||
|
||||
output_file = "EventLogs_output.csv"
|
||||
args = ["-d", evtx_dir, "--csv", str(self.output_path), "--csvf", output_file]
|
||||
result = self.run_tool("EvtxECmd", args)
|
||||
result["output_file"] = str(self.output_path / output_file)
|
||||
self.results["EventLogs"] = result
|
||||
return result
|
||||
|
||||
def process_shellbags(self, registry_dir: str = None) -> dict:
|
||||
"""Parse Shellbag artifacts with SBECmd."""
|
||||
if registry_dir is None:
|
||||
registry_dir = str(self.evidence_path)
|
||||
|
||||
output_file = "Shellbags_output.csv"
|
||||
args = ["-d", registry_dir, "--csv", str(self.output_path), "--csvf", output_file]
|
||||
result = self.run_tool("SBECmd", args)
|
||||
result["output_file"] = str(self.output_path / output_file)
|
||||
self.results["Shellbags"] = result
|
||||
return result
|
||||
|
||||
def process_recycle_bin(self, recycle_dir: str = None) -> dict:
|
||||
"""Parse Recycle Bin artifacts with RBCmd."""
|
||||
if recycle_dir is None:
|
||||
rb_candidates = list(self.evidence_path.rglob("$Recycle.Bin"))
|
||||
if not rb_candidates:
|
||||
return {"status": "skipped", "message": "$Recycle.Bin not found"}
|
||||
recycle_dir = str(rb_candidates[0])
|
||||
|
||||
output_file = "RecycleBin_output.csv"
|
||||
args = ["-d", recycle_dir, "--csv", str(self.output_path), "--csvf", output_file]
|
||||
result = self.run_tool("RBCmd", args)
|
||||
result["output_file"] = str(self.output_path / output_file)
|
||||
self.results["RecycleBin"] = result
|
||||
return result
|
||||
|
||||
def detect_timestomping(self, mft_csv_path: str) -> list:
|
||||
"""Analyze MFT CSV output to detect timestomping indicators."""
|
||||
timestomped = []
|
||||
try:
|
||||
with open(mft_csv_path, "r", encoding="utf-8-sig") as f:
|
||||
reader = csv.DictReader(f)
|
||||
for row in reader:
|
||||
si_created = row.get("Created0x10", "")
|
||||
fn_created = row.get("Created0x30", "")
|
||||
if si_created and fn_created:
|
||||
try:
|
||||
si_dt = datetime.fromisoformat(si_created.replace("Z", "+00:00"))
|
||||
fn_dt = datetime.fromisoformat(fn_created.replace("Z", "+00:00"))
|
||||
if si_dt < fn_dt:
|
||||
timestomped.append({
|
||||
"file": row.get("FileName", "Unknown"),
|
||||
"entry_number": row.get("EntryNumber", ""),
|
||||
"si_created": si_created,
|
||||
"fn_created": fn_created,
|
||||
"indicator": "$SI Created before $FN Created"
|
||||
})
|
||||
except (ValueError, TypeError):
|
||||
continue
|
||||
except FileNotFoundError:
|
||||
return [{"error": f"MFT CSV not found: {mft_csv_path}"}]
|
||||
return timestomped
|
||||
|
||||
def process_all(self) -> dict:
|
||||
"""Run all available EZ Tools processors against evidence."""
|
||||
print("[*] Starting comprehensive EZ Tools processing...")
|
||||
print(f"[*] Evidence path: {self.evidence_path}")
|
||||
print(f"[*] Output path: {self.output_path}")
|
||||
|
||||
available = self.verify_tools()
|
||||
print(f"[*] Available tools: {sum(v for v in available.values())}/{len(available)}")
|
||||
|
||||
processors = [
|
||||
("MFT", self.process_mft),
|
||||
("USN Journal", self.process_usn_journal),
|
||||
("Prefetch", self.process_prefetch),
|
||||
("LNK Files", self.process_lnk_files),
|
||||
("Jump Lists", self.process_jump_lists),
|
||||
("Event Logs", self.process_event_logs),
|
||||
("Shellbags", self.process_shellbags),
|
||||
("Recycle Bin", self.process_recycle_bin),
|
||||
]
|
||||
|
||||
for name, processor in processors:
|
||||
print(f"[*] Processing {name}...")
|
||||
result = processor()
|
||||
status = result.get("status", "unknown")
|
||||
print(f" [{status.upper()}] {name}")
|
||||
|
||||
return self.results
|
||||
|
||||
def generate_report(self) -> str:
|
||||
"""Generate a summary report of all processing results."""
|
||||
report = {
|
||||
"timestamp": datetime.now().isoformat(),
|
||||
"evidence_path": str(self.evidence_path),
|
||||
"output_path": str(self.output_path),
|
||||
"results": {}
|
||||
}
|
||||
|
||||
for artifact, result in self.results.items():
|
||||
report["results"][artifact] = {
|
||||
"status": result.get("status", "unknown"),
|
||||
"output_file": result.get("output_file", ""),
|
||||
}
|
||||
output_file = result.get("output_file", "")
|
||||
if output_file and os.path.exists(output_file):
|
||||
file_size = os.path.getsize(output_file)
|
||||
report["results"][artifact]["output_size_bytes"] = file_size
|
||||
with open(output_file, "rb") as f:
|
||||
report["results"][artifact]["sha256"] = hashlib.sha256(f.read()).hexdigest()
|
||||
|
||||
report_path = self.output_path / "processing_report.json"
|
||||
with open(report_path, "w") as f:
|
||||
json.dump(report, f, indent=2)
|
||||
|
||||
print(f"\n[*] Report saved to: {report_path}")
|
||||
return str(report_path)
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) < 4:
|
||||
print("Usage: python process.py <ez_tools_path> <evidence_path> <output_path>")
|
||||
print("Example: python process.py C:\\Tools\\EZTools C:\\Cases\\Evidence C:\\Cases\\Output")
|
||||
sys.exit(1)
|
||||
|
||||
ez_tools_path = sys.argv[1]
|
||||
evidence_path = sys.argv[2]
|
||||
output_path = sys.argv[3]
|
||||
|
||||
processor = EZToolsProcessor(ez_tools_path, evidence_path, output_path)
|
||||
processor.process_all()
|
||||
processor.generate_report()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user