Digital Forensics and Evidence Collection

Digital Forensics and Evidence Collection

Digital forensics provides the foundation for understanding incident scope, identifying root causes, and gathering evidence for potential legal proceedings. Proper forensic procedures ensure evidence integrity while enabling thorough investigation. Understanding forensic principles and tools for both Windows and Linux systems enables effective incident investigation.

Windows forensic data collection requires careful procedures to preserve evidence:

# Windows Forensic Evidence Collection Script
[CmdletBinding()]
param(
    [Parameter(Mandatory=$true)]
    [string]$IncidentID,
    
    [Parameter(Mandatory=$true)]
    [string]$TargetComputer,
    
    [Parameter(Mandatory=$true)]
    [string]$EvidencePath
)

# Create evidence directory structure
$EvidenceRoot = Join-Path $EvidencePath $IncidentID
$Directories = @(
    "memory",
    "logs",
    "registry",
    "network",
    "processes",
    "artifacts",
    "timeline"
)

foreach ($dir in $Directories) {
    New-Item -Path (Join-Path $EvidenceRoot $dir) -ItemType Directory -Force
}

# Function to create forensic hash
function Get-ForensicHash {
    param($FilePath)
    
    $md5 = New-Object System.Security.Cryptography.MD5CryptoServiceProvider
    $sha256 = New-Object System.Security.Cryptography.SHA256CryptoServiceProvider
    
    $file = [System.IO.File]::OpenRead($FilePath)
    $md5Hash = [System.BitConverter]::ToString($md5.ComputeHash($file)).Replace("-","")
    $sha256Hash = [System.BitConverter]::ToString($sha256.ComputeHash($file)).Replace("-","")
    $file.Close()
    
    return @{
        MD5 = $md5Hash
        SHA256 = $sha256Hash
        File = $FilePath
        Timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
    }
}

# Collect volatile data first
Write-Host "Collecting volatile evidence from $TargetComputer..." -ForegroundColor Yellow

# Memory dump (requires administrative privileges)
$MemoryDump = Join-Path $EvidenceRoot "memory\memory.dmp"
if (Test-Path "C:\Tools\DumpIt.exe") {
    Start-Process -FilePath "C:\Tools\DumpIt.exe" -ArgumentList "/quiet", "/output:$MemoryDump" -Wait
    Get-ForensicHash $MemoryDump | Export-Csv -Path "$MemoryDump.hash" -NoTypeInformation
}

# Collect process information
Invoke-Command -ComputerName $TargetComputer -ScriptBlock {
    Get-Process | Select-Object Id, ProcessName, Path, StartTime, CPU, WorkingSet, Company, Description
} | Export-Csv -Path (Join-Path $EvidenceRoot "processes\running_processes.csv") -NoTypeInformation

# Collect network connections
Invoke-Command -ComputerName $TargetComputer -ScriptBlock {
    Get-NetTCPConnection | Select-Object LocalAddress, LocalPort, RemoteAddress, RemotePort, State, OwningProcess, CreationTime
} | Export-Csv -Path (Join-Path $EvidenceRoot "network\tcp_connections.csv") -NoTypeInformation

# Collect system information
$SystemInfo = Invoke-Command -ComputerName $TargetComputer -ScriptBlock {
    @{
        ComputerName = $env:COMPUTERNAME
        OSVersion = (Get-CimInstance Win32_OperatingSystem).Version
        LastBootTime = (Get-CimInstance Win32_OperatingSystem).LastBootUpTime
        TimeZone = (Get-TimeZone).DisplayName
        Domain = (Get-CimInstance Win32_ComputerSystem).Domain
        LoggedOnUsers = (Get-CimInstance Win32_LoggedOnUser | Select-Object -ExpandProperty Antecedent).Name
    }
}
$SystemInfo | ConvertTo-Json | Out-File (Join-Path $EvidenceRoot "artifacts\system_info.json")

# Collect event logs
$EventLogs = @("System", "Security", "Application", "Microsoft-Windows-PowerShell/Operational")
foreach ($LogName in $EventLogs) {
    Write-Host "Exporting $LogName log..."
    $LogFile = Join-Path $EvidenceRoot "logs\$($LogName.Replace('/', '-')).evtx"
    wevtutil export-log $LogName $LogFile /remote:$TargetComputer
    Get-ForensicHash $LogFile | Export-Csv -Path "$LogFile.hash" -NoTypeInformation
}

# Collect registry hives
Write-Host "Collecting registry hives..."
$RegistryHives = @{
    "HKLM_SYSTEM" = "HKLM:\SYSTEM"
    "HKLM_SOFTWARE" = "HKLM:\SOFTWARE"
    "HKLM_SECURITY" = "HKLM:\SECURITY"
}

foreach ($hive in $RegistryHives.GetEnumerator()) {
    $ExportPath = Join-Path $EvidenceRoot "registry\$($hive.Key).reg"
    reg export $hive.Value $ExportPath /y
}

# Create timeline
Write-Host "Creating forensic timeline..."
$TimelineEvents = @()

# File system timeline
$TimelineEvents += Get-ChildItem -Path C:\ -Recurse -ErrorAction SilentlyContinue |
    Where-Object { $_.LastWriteTime -gt (Get-Date).AddDays(-7) } |
    Select-Object FullName, CreationTime, LastWriteTime, LastAccessTime, Length

# Security event timeline
$TimelineEvents += Get-WinEvent -LogName Security -MaxEvents 10000 |
    Select-Object TimeCreated, Id, Message |
    Where-Object { $_.TimeCreated -gt (Get-Date).AddDays(-7) }

$TimelineEvents | Sort-Object { $_.TimeCreated, $_.LastWriteTime } |
    Export-Csv -Path (Join-Path $EvidenceRoot "timeline\forensic_timeline.csv") -NoTypeInformation

# Create evidence inventory
$Inventory = Get-ChildItem -Path $EvidenceRoot -Recurse -File |
    Select-Object FullName, Length, CreationTime |
    ForEach-Object {
        $hash = Get-ForensicHash $_.FullName
        [PSCustomObject]@{
            File = $_.FullName.Replace($EvidenceRoot, "")
            Size = $_.Length
            Created = $_.CreationTime
            MD5 = $hash.MD5
            SHA256 = $hash.SHA256
        }
    }

$Inventory | Export-Csv -Path (Join-Path $EvidenceRoot "evidence_inventory.csv") -NoTypeInformation

Write-Host "Forensic evidence collection completed: $EvidenceRoot" -ForegroundColor Green

Linux forensic collection requires different tools and approaches:

#!/bin/bash
# Linux Forensic Evidence Collection Script

set -euo pipefail

# Configuration
INCIDENT_ID="$1"
TARGET_HOST="${2:-localhost}"
EVIDENCE_BASE="/forensics/$INCIDENT_ID"

# Create evidence directory structure
mkdir -p "$EVIDENCE_BASE"/{memory,logs,network,processes,filesystem,artifacts}

# Logging function
log() {
    echo "[$(date +'%Y-%m-%d %H:%M:%S')] $*" | tee -a "$EVIDENCE_BASE/collection.log"
}

# Hash function for evidence integrity
create_hash() {
    local file="$1"
    md5sum "$file" > "$file.md5"
    sha256sum "$file" > "$file.sha256"
    log "Created hash for: $file"
}

# Collect volatile data first
log "Starting volatile data collection from $TARGET_HOST"

# Memory dump (if local)
if [[ "$TARGET_HOST" == "localhost" ]]; then
    if command -v LiME >/dev/null 2>&1; then
        log "Creating memory dump with LiME"
        insmod /path/to/lime.ko "path=$EVIDENCE_BASE/memory/memory.lime format=lime"
        create_hash "$EVIDENCE_BASE/memory/memory.lime"
    else
        log "WARNING: LiME not available, attempting /proc/kcore copy"
        if [[ -r /proc/kcore ]]; then
            dd if=/proc/kcore of="$EVIDENCE_BASE/memory/kcore.dump" bs=1M
            create_hash "$EVIDENCE_BASE/memory/kcore.dump"
        fi
    fi
fi

# Process information
log "Collecting process information"
ps auxww > "$EVIDENCE_BASE/processes/ps_auxww.txt"
ps -ef > "$EVIDENCE_BASE/processes/ps_ef.txt"
lsof -n > "$EVIDENCE_BASE/processes/lsof.txt" 2>/dev/null || true
pstree -p > "$EVIDENCE_BASE/processes/pstree.txt"

# Process memory maps
for pid in $(ls /proc | grep -E '^[0-9]+$'); do
    if [[ -r "/proc/$pid/maps" ]]; then
        cat "/proc/$pid/maps" > "$EVIDENCE_BASE/processes/maps_$pid.txt" 2>/dev/null || true
    fi
done

# Network connections
log "Collecting network information"
netstat -an > "$EVIDENCE_BASE/network/netstat_an.txt"
netstat -rn > "$EVIDENCE_BASE/network/netstat_rn.txt"
ss -anp > "$EVIDENCE_BASE/network/ss_anp.txt" 2>/dev/null || true
iptables -L -n -v > "$EVIDENCE_BASE/network/iptables.txt"
ip addr show > "$EVIDENCE_BASE/network/ip_addr.txt"
ip route show > "$EVIDENCE_BASE/network/ip_route.txt"
arp -a > "$EVIDENCE_BASE/network/arp.txt"

# System information
log "Collecting system information"
{
    echo "=== System Information ==="
    uname -a
    echo
    echo "=== Hostname ==="
    hostname -f
    echo
    echo "=== Date/Time ==="
    date
    echo
    echo "=== Timezone ==="
    timedatectl status 2>/dev/null || cat /etc/timezone
    echo
    echo "=== Uptime ==="
    uptime
    echo
    echo "=== Logged in users ==="
    who
    echo
    echo "=== Last logins ==="
    last -20
} > "$EVIDENCE_BASE/artifacts/system_info.txt"

# Collect logs
log "Collecting system logs"
if [[ -d /var/log ]]; then
    # Copy important logs
    for logfile in auth.log secure messages syslog kern.log; do
        if [[ -f "/var/log/$logfile" ]]; then
            cp "/var/log/$logfile"* "$EVIDENCE_BASE/logs/" 2>/dev/null || true
        fi
    done
    
    # Journal logs if systemd
    if command -v journalctl >/dev/null 2>&1; then
        journalctl --since="7 days ago" > "$EVIDENCE_BASE/logs/journalctl_7days.log"
        journalctl -p err --since="30 days ago" > "$EVIDENCE_BASE/logs/journalctl_errors.log"
    fi
fi

# Audit logs
if [[ -f /var/log/audit/audit.log ]]; then
    cp /var/log/audit/audit.log* "$EVIDENCE_BASE/logs/"
    ausearch -ts recent > "$EVIDENCE_BASE/logs/audit_recent.txt"
fi

# File system timeline
log "Creating filesystem timeline"
find / -type f -mtime -7 -ls 2>/dev/null | head -10000 > "$EVIDENCE_BASE/filesystem/modified_files_7days.txt"
find /home -type f -name ".*" -ls 2>/dev/null > "$EVIDENCE_BASE/filesystem/hidden_files_home.txt"
find / -type f -perm -4000 -ls 2>/dev/null > "$EVIDENCE_BASE/filesystem/suid_files.txt"
find / -type f -perm -2000 -ls 2>/dev/null > "$EVIDENCE_BASE/filesystem/sgid_files.txt"

# Persistence mechanisms
log "Checking persistence mechanisms"
{
    echo "=== Crontabs ==="
    for user in $(cut -f1 -d: /etc/passwd); do
        echo "User: $user"
        crontab -u "$user" -l 2>/dev/null || echo "No crontab"
        echo
    done
    
    echo "=== System cron ==="
    ls -la /etc/cron.*
    
    echo "=== Systemd timers ==="
    systemctl list-timers --all
    
    echo "=== RC scripts ==="
    ls -la /etc/rc*.d/
} > "$EVIDENCE_BASE/artifacts/persistence.txt"

# Create evidence package
log "Creating evidence package"
cd "$(dirname "$EVIDENCE_BASE")"
tar czf "$INCIDENT_ID.tar.gz" "$INCIDENT_ID/"
create_hash "$INCIDENT_ID.tar.gz"

# Generate collection report
{
    echo "Forensic Evidence Collection Report"
    echo "=================================="
    echo "Incident ID: $INCIDENT_ID"
    echo "Collection Date: $(date)"
    echo "Target Host: $TARGET_HOST"
    echo "Collector: $(whoami)@$(hostname)"
    echo
    echo "Evidence Summary:"
    find "$EVIDENCE_BASE" -type f -name "*.txt" -o -name "*.log" | while read -r file; do
        echo "- $file ($(stat -c%s "$file") bytes)"
    done
    echo
    echo "Total Evidence Size: $(du -sh "$EVIDENCE_BASE" | cut -f1)"
} > "$EVIDENCE_BASE/collection_report.txt"

log "Forensic evidence collection completed: $EVIDENCE_BASE"