Collect forensic evidence during security incidents for investigation and analysis.

Overview

This script automates the collection of forensic evidence from Windows and Linux systems during security incidents. It gathers volatile data including running processes, network connections, logged-in users, recent file modifications, and system logs, then packages everything into a timestamped evidence archive.

Use Case: Security incident response, forensic investigation, breach analysis, malware investigation, and compliance requirements.

Platform: Windows (PowerShell) and Linux (Bash) Requirements: Administrator/root privileges Execution Time: 2-5 minutes (varies with system size)

Windows Evidence Collection (PowerShell)

Lang: powershell
  1#
  2# evidence-collection.ps1
  3#
  4# Description:
  5#   Collects forensic evidence from Windows systems during security incidents
  6#   Creates timestamped evidence package with system state and volatile data
  7#
  8# Usage:
  9#   Run as Administrator:
 10#   .\evidence-collection.ps1 [-OutputPath C:\Evidence] [-IncidentID INC-12345]
 11#
 12# Author: glyph.sh
 13# Reference: https://glyph.sh/scripts/evidence-collection/
 14#
 15
 16[CmdletBinding()]
 17param(
 18    [Parameter(Mandatory=$false)]
 19    [string]$OutputPath = "C:\Evidence",
 20
 21    [Parameter(Mandatory=$false)]
 22    [string]$IncidentID = "INC-$(Get-Date -Format 'yyyyMMdd-HHmmss')"
 23)
 24
 25#Requires -RunAsAdministrator
 26
 27# Banner
 28Write-Host ""
 29Write-Host "========================================" -ForegroundColor Cyan
 30Write-Host " Windows Forensic Evidence Collection" -ForegroundColor Cyan
 31Write-Host "========================================" -ForegroundColor Cyan
 32Write-Host ""
 33Write-Host "Incident ID: $IncidentID" -ForegroundColor Yellow
 34Write-Host "Timestamp: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')" -ForegroundColor Yellow
 35Write-Host "Hostname: $env:COMPUTERNAME" -ForegroundColor Yellow
 36Write-Host ""
 37
 38# Create evidence directory
 39$timestamp = Get-Date -Format "yyyyMMdd-HHmmss"
 40$evidenceDir = Join-Path $OutputPath "$env:COMPUTERNAME-$timestamp-$IncidentID"
 41$null = New-Item -ItemType Directory -Force -Path $evidenceDir
 42
 43Write-Host "[+] Evidence collection started..." -ForegroundColor Green
 44Write-Host "[+] Output directory: $evidenceDir" -ForegroundColor Green
 45Write-Host ""
 46
 47# Function to capture command output
 48function Capture-Output {
 49    param(
 50        [string]$Description,
 51        [string]$FileName,
 52        [scriptblock]$Command
 53    )
 54
 55    Write-Host "  [>] $Description..." -ForegroundColor Gray
 56
 57    try {
 58        $outputFile = Join-Path $evidenceDir $FileName
 59        $output = & $Command
 60        $output | Out-File -FilePath $outputFile -Encoding UTF8
 61        Write-Host "      Saved: $FileName" -ForegroundColor Green
 62    }
 63    catch {
 64        Write-Host "      Error: $_" -ForegroundColor Red
 65    }
 66}
 67
 68#
 69# 1. System Information
 70#
 71Write-Host "[1/10] Collecting System Information" -ForegroundColor Cyan
 72
 73Capture-Output "System info" "01-systeminfo.txt" {
 74    systeminfo
 75}
 76
 77Capture-Output "Computer details" "01-computer-info.txt" {
 78    Get-ComputerInfo | Format-List
 79}
 80
 81Capture-Output "Environment variables" "01-environment.txt" {
 82    Get-ChildItem Env: | Format-Table -AutoSize
 83}
 84
 85Capture-Output "Hotfixes installed" "01-hotfixes.txt" {
 86    Get-HotFix | Sort-Object -Property InstalledOn -Descending
 87}
 88
 89Write-Host ""
 90
 91#
 92# 2. Running Processes
 93#
 94Write-Host "[2/10] Collecting Running Processes" -ForegroundColor Cyan
 95
 96Capture-Output "Process list" "02-processes.txt" {
 97    Get-Process | Select-Object Name, Id, CPU, PM, StartTime, Path, Company, Description |
 98        Sort-Object -Property CPU -Descending | Format-Table -AutoSize
 99}
100
101Capture-Output "Process tree" "02-process-tree.txt" {
102    Get-CimInstance Win32_Process | Select-Object ProcessId, ParentProcessId, Name, ExecutablePath, CommandLine |
103        Format-Table -AutoSize
104}
105
106Capture-Output "Services status" "02-services.txt" {
107    Get-Service | Select-Object Name, DisplayName, Status, StartType |
108        Sort-Object -Property Status, Name | Format-Table -AutoSize
109}
110
111Capture-Output "Scheduled tasks" "02-scheduled-tasks.txt" {
112    Get-ScheduledTask | Where-Object {$_.State -ne 'Disabled'} |
113        Select-Object TaskName, State, TaskPath, Date | Format-Table -AutoSize
114}
115
116Write-Host ""
117
118#
119# 3. Network Connections
120#
121Write-Host "[3/10] Collecting Network Information" -ForegroundColor Cyan
122
123Capture-Output "Network connections" "03-netstat.txt" {
124    Get-NetTCPConnection | Select-Object LocalAddress, LocalPort, RemoteAddress, RemotePort, State, OwningProcess,
125        @{Name="ProcessName";Expression={(Get-Process -Id $_.OwningProcess -ErrorAction SilentlyContinue).ProcessName}} |
126        Sort-Object -Property State, RemoteAddress | Format-Table -AutoSize
127}
128
129Capture-Output "Listening ports" "03-listening-ports.txt" {
130    Get-NetTCPConnection -State Listen | Select-Object LocalAddress, LocalPort, OwningProcess,
131        @{Name="ProcessName";Expression={(Get-Process -Id $_.OwningProcess -ErrorAction SilentlyContinue).ProcessName}} |
132        Sort-Object -Property LocalPort | Format-Table -AutoSize
133}
134
135Capture-Output "Network adapters" "03-network-adapters.txt" {
136    Get-NetAdapter | Select-Object Name, Status, MacAddress, LinkSpeed | Format-Table -AutoSize
137}
138
139Capture-Output "IP configuration" "03-ipconfig.txt" {
140    ipconfig /all
141}
142
143Capture-Output "ARP cache" "03-arp-cache.txt" {
144    Get-NetNeighbor | Select-Object IPAddress, LinkLayerAddress, State | Format-Table -AutoSize
145}
146
147Capture-Output "DNS cache" "03-dns-cache.txt" {
148    Get-DnsClientCache | Select-Object Entry, RecordName, RecordType, Data, TimeToLive | Format-Table -AutoSize
149}
150
151Capture-Output "Routing table" "03-routing-table.txt" {
152    Get-NetRoute | Select-Object DestinationPrefix, NextHop, InterfaceAlias, RouteMetric | Format-Table -AutoSize
153}
154
155Capture-Output "SMB sessions" "03-smb-sessions.txt" {
156    Get-SmbSession | Format-Table -AutoSize
157}
158
159Write-Host ""
160
161#
162# 4. Logged-in Users
163#
164Write-Host "[4/10] Collecting User Information" -ForegroundColor Cyan
165
166Capture-Output "Logged-in users" "04-logged-users.txt" {
167    query user 2>&1
168}
169
170Capture-Output "Local users" "04-local-users.txt" {
171    Get-LocalUser | Select-Object Name, Enabled, LastLogon, PasswordLastSet, PasswordRequired | Format-Table -AutoSize
172}
173
174Capture-Output "Local groups" "04-local-groups.txt" {
175    Get-LocalGroup | ForEach-Object {
176        $group = $_
177        $members = Get-LocalGroupMember -Group $group.Name -ErrorAction SilentlyContinue
178        [PSCustomObject]@{
179            GroupName = $group.Name
180            Members = ($members.Name -join ', ')
181        }
182    } | Format-Table -AutoSize
183}
184
185Capture-Output "Login sessions" "04-login-sessions.txt" {
186    Get-CimInstance Win32_LogonSession | Select-Object LogonId, LogonType, StartTime, AuthenticationPackage |
187        Format-Table -AutoSize
188}
189
190Write-Host ""
191
192#
193# 5. Recent File Modifications
194#
195Write-Host "[5/10] Collecting Recent File Changes" -ForegroundColor Cyan
196
197Capture-Output "Recently modified files (System32)" "05-recent-system32.txt" {
198    Get-ChildItem -Path "C:\Windows\System32" -File -Recurse -ErrorAction SilentlyContinue |
199        Where-Object {$_.LastWriteTime -gt (Get-Date).AddDays(-7)} |
200        Select-Object FullName, LastWriteTime, Length |
201        Sort-Object -Property LastWriteTime -Descending |
202        Select-Object -First 100 |
203        Format-Table -AutoSize
204}
205
206Capture-Output "Recently modified files (Temp)" "05-recent-temp.txt" {
207    Get-ChildItem -Path "C:\Windows\Temp", "C:\Users\*\AppData\Local\Temp" -File -Recurse -ErrorAction SilentlyContinue |
208        Where-Object {$_.LastWriteTime -gt (Get-Date).AddDays(-7)} |
209        Select-Object FullName, LastWriteTime, Length |
210        Sort-Object -Property LastWriteTime -Descending |
211        Select-Object -First 100 |
212        Format-Table -AutoSize
213}
214
215Capture-Output "Recently created files (Downloads)" "05-recent-downloads.txt" {
216    Get-ChildItem -Path "C:\Users\*\Downloads" -File -Recurse -ErrorAction SilentlyContinue |
217        Where-Object {$_.CreationTime -gt (Get-Date).AddDays(-7)} |
218        Select-Object FullName, CreationTime, LastWriteTime, Length |
219        Sort-Object -Property CreationTime -Descending |
220        Format-Table -AutoSize
221}
222
223Capture-Output "Startup programs" "05-startup-programs.txt" {
224    Get-CimInstance Win32_StartupCommand | Select-Object Name, Command, Location, User | Format-Table -AutoSize
225}
226
227Write-Host ""
228
229#
230# 6. Registry Autoruns
231#
232Write-Host "[6/10] Collecting Registry Information" -ForegroundColor Cyan
233
234Capture-Output "Registry Run keys" "06-registry-run.txt" {
235    $runKeys = @(
236        "HKLM:\Software\Microsoft\Windows\CurrentVersion\Run",
237        "HKLM:\Software\Microsoft\Windows\CurrentVersion\RunOnce",
238        "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run",
239        "HKCU:\Software\Microsoft\Windows\CurrentVersion\RunOnce"
240    )
241
242    foreach ($key in $runKeys) {
243        if (Test-Path $key) {
244            Write-Output "=== $key ==="
245            Get-ItemProperty -Path $key | Format-List
246        }
247    }
248}
249
250Capture-Output "Installed software" "06-installed-software.txt" {
251    Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* |
252        Select-Object DisplayName, DisplayVersion, Publisher, InstallDate |
253        Sort-Object -Property DisplayName |
254        Format-Table -AutoSize
255}
256
257Write-Host ""
258
259#
260# 7. Event Logs
261#
262Write-Host "[7/10] Collecting Event Logs (Last 24 Hours)" -ForegroundColor Cyan
263
264$startTime = (Get-Date).AddDays(-1)
265
266Capture-Output "Security log - Failed logons" "07-security-failed-logons.txt" {
267    Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4625; StartTime=$startTime} -ErrorAction SilentlyContinue |
268        Select-Object TimeCreated, Message |
269        Format-Table -Wrap -AutoSize
270}
271
272Capture-Output "Security log - Successful logons" "07-security-successful-logons.txt" {
273    Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4624; StartTime=$startTime} -ErrorAction SilentlyContinue |
274        Select-Object TimeCreated, Message |
275        Format-Table -Wrap -AutoSize
276}
277
278Capture-Output "Security log - Account lockouts" "07-security-lockouts.txt" {
279    Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4740; StartTime=$startTime} -ErrorAction SilentlyContinue |
280        Select-Object TimeCreated, Message |
281        Format-Table -Wrap -AutoSize
282}
283
284Capture-Output "System log - Errors" "07-system-errors.txt" {
285    Get-WinEvent -FilterHashtable @{LogName='System'; Level=2; StartTime=$startTime} -ErrorAction SilentlyContinue |
286        Select-Object TimeCreated, ProviderName, Id, Message |
287        Format-Table -Wrap -AutoSize
288}
289
290Capture-Output "Application log - Errors" "07-application-errors.txt" {
291    Get-WinEvent -FilterHashtable @{LogName='Application'; Level=2; StartTime=$startTime} -ErrorAction SilentlyContinue |
292        Select-Object TimeCreated, ProviderName, Id, Message |
293        Format-Table -Wrap -AutoSize
294}
295
296Write-Host ""
297
298#
299# 8. Windows Defender
300#
301Write-Host "[8/10] Collecting Windows Defender Information" -ForegroundColor Cyan
302
303Capture-Output "Defender status" "08-defender-status.txt" {
304    Get-MpComputerStatus | Format-List
305}
306
307Capture-Output "Defender threats" "08-defender-threats.txt" {
308    Get-MpThreat | Format-List
309}
310
311Capture-Output "Defender scan history" "08-defender-scans.txt" {
312    Get-MpThreatDetection | Format-Table -AutoSize
313}
314
315Write-Host ""
316
317#
318# 9. Firewall Rules
319#
320Write-Host "[9/10] Collecting Firewall Configuration" -ForegroundColor Cyan
321
322Capture-Output "Firewall profiles" "09-firewall-profiles.txt" {
323    Get-NetFirewallProfile | Select-Object Name, Enabled, DefaultInboundAction, DefaultOutboundAction | Format-Table -AutoSize
324}
325
326Capture-Output "Firewall rules (Enabled)" "09-firewall-rules.txt" {
327    Get-NetFirewallRule | Where-Object {$_.Enabled -eq $true} |
328        Select-Object DisplayName, Direction, Action, Enabled |
329        Sort-Object -Property Direction, DisplayName |
330        Format-Table -AutoSize
331}
332
333Write-Host ""
334
335#
336# 10. Create Summary Report
337#
338Write-Host "[10/10] Creating Summary Report" -ForegroundColor Cyan
339
340$summaryFile = Join-Path $evidenceDir "00-SUMMARY.txt"
341
342@"
343========================================
344FORENSIC EVIDENCE COLLECTION SUMMARY
345========================================
346
347Incident ID: $IncidentID
348Collection Date: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')
349Hostname: $env:COMPUTERNAME
350Domain: $env:USERDOMAIN
351Current User: $env:USERNAME
352OS Version: $([System.Environment]::OSVersion.VersionString)
353PowerShell Version: $($PSVersionTable.PSVersion)
354
355========================================
356EVIDENCE FILES COLLECTED
357========================================
358
359$((Get-ChildItem -Path $evidenceDir -File | Select-Object Name, Length, LastWriteTime | Format-Table -AutoSize | Out-String))
360
361========================================
362SYSTEM SNAPSHOT
363========================================
364
365Uptime: $((Get-CimInstance Win32_OperatingSystem).LastBootUpTime)
366Active Processes: $((Get-Process).Count)
367Active Network Connections: $((Get-NetTCPConnection).Count)
368Listening Ports: $((Get-NetTCPConnection -State Listen).Count)
369Logged-in Users: $((query user 2>&1 | Measure-Object -Line).Lines - 1)
370
371========================================
372IMPORTANT NOTES
373========================================
374
3751. This evidence should be preserved in a secure location
3762. Maintain chain of custody documentation
3773. Do not modify or delete evidence files
3784. Consider creating a forensic image of the system
3795. Review all collected data for indicators of compromise
3806. Consult with legal/compliance teams before sharing
381
382========================================
383NEXT STEPS
384========================================
385
3861. Review evidence for suspicious activity
3872. Analyze network connections for C2 traffic
3883. Check running processes for malware
3894. Review event logs for security events
3905. Examine recent file modifications
3916. Verify all user accounts are legitimate
3927. Check for persistence mechanisms (autoruns, scheduled tasks)
3938. Document findings in incident report
394
395========================================
396"@ | Out-File -FilePath $summaryFile -Encoding UTF8
397
398Write-Host "      Saved: 00-SUMMARY.txt" -ForegroundColor Green
399Write-Host ""
400
401#
402# Create Archive (Optional - Requires 7-Zip or similar)
403#
404Write-Host "[+] Creating Evidence Archive..." -ForegroundColor Cyan
405
406$archivePath = "$evidenceDir.zip"
407
408try {
409    Compress-Archive -Path $evidenceDir -DestinationPath $archivePath -CompressionLevel Optimal
410    Write-Host "      Archive created: $archivePath" -ForegroundColor Green
411
412    # Calculate hash
413    $hash = Get-FileHash -Path $archivePath -Algorithm SHA256
414    $hashFile = "$archivePath.sha256"
415    "$($hash.Hash)  $(Split-Path $archivePath -Leaf)" | Out-File -FilePath $hashFile
416
417    Write-Host "      SHA256: $($hash.Hash)" -ForegroundColor Green
418    Write-Host "      Hash saved: $hashFile" -ForegroundColor Green
419}
420catch {
421    Write-Host "      Error creating archive: $_" -ForegroundColor Yellow
422    Write-Host "      Evidence directory preserved: $evidenceDir" -ForegroundColor Yellow
423}
424
425Write-Host ""
426Write-Host "========================================" -ForegroundColor Cyan
427Write-Host " Evidence Collection Complete" -ForegroundColor Cyan
428Write-Host "========================================" -ForegroundColor Cyan
429Write-Host ""
430Write-Host "Evidence Location: $evidenceDir" -ForegroundColor Green
431Write-Host "Archive Location: $archivePath" -ForegroundColor Green
432Write-Host ""
433Write-Host "IMPORTANT: Preserve evidence integrity!" -ForegroundColor Yellow
434Write-Host "  - Store in secure location" -ForegroundColor Yellow
435Write-Host "  - Document chain of custody" -ForegroundColor Yellow
436Write-Host "  - Do not modify collected data" -ForegroundColor Yellow
437Write-Host ""

Linux Evidence Collection (Bash)

Lang: bash
  1#!/bin/bash
  2
  3#
  4# evidence-collection.sh
  5#
  6# Description:
  7#   Collects forensic evidence from Linux systems during security incidents
  8#   Creates timestamped evidence package with system state and volatile data
  9#
 10# Usage:
 11#   sudo ./evidence-collection.sh [output-directory] [incident-id]
 12#
 13# Author: glyph.sh
 14# Reference: https://glyph.sh/scripts/evidence-collection/
 15#
 16
 17set -euo pipefail
 18
 19# Colors
 20RED='\033[0;31m'
 21GREEN='\033[0;32m'
 22YELLOW='\033[1;33m'
 23CYAN='\033[0;36m'
 24NC='\033[0m' # No Color
 25
 26# Check if running as root
 27if [[ $EUID -ne 0 ]]; then
 28    echo -e "${RED}This script must be run as root${NC}"
 29    exit 1
 30fi
 31
 32# Parameters
 33OUTPUT_BASE="${1:-/tmp/evidence}"
 34INCIDENT_ID="${2:-INC-$(date +%Y%m%d-%H%M%S)}"
 35
 36# Banner
 37echo ""
 38echo -e "${CYAN}========================================${NC}"
 39echo -e "${CYAN} Linux Forensic Evidence Collection${NC}"
 40echo -e "${CYAN}========================================${NC}"
 41echo ""
 42echo -e "${YELLOW}Incident ID: $INCIDENT_ID${NC}"
 43echo -e "${YELLOW}Timestamp: $(date '+%Y-%m-%d %H:%M:%S')${NC}"
 44echo -e "${YELLOW}Hostname: $(hostname)${NC}"
 45echo ""
 46
 47# Create evidence directory
 48TIMESTAMP=$(date +%Y%m%d-%H%M%S)
 49EVIDENCE_DIR="$OUTPUT_BASE/$(hostname)-$TIMESTAMP-$INCIDENT_ID"
 50mkdir -p "$EVIDENCE_DIR"
 51
 52echo -e "${GREEN}[+] Evidence collection started...${NC}"
 53echo -e "${GREEN}[+] Output directory: $EVIDENCE_DIR${NC}"
 54echo ""
 55
 56# Function to capture command output
 57capture_output() {
 58    local description="$1"
 59    local filename="$2"
 60    local command="$3"
 61
 62    echo -e "  ${CYAN}[>]${NC} $description..."
 63
 64    if eval "$command" > "$EVIDENCE_DIR/$filename" 2>&1; then
 65        echo -e "      ${GREEN}Saved: $filename${NC}"
 66    else
 67        echo -e "      ${YELLOW}Warning: Failed to collect $description${NC}"
 68    fi
 69}
 70
 71#
 72# 1. System Information
 73#
 74echo -e "${CYAN}[1/10] Collecting System Information${NC}"
 75
 76capture_output "System information" "01-system-info.txt" "uname -a"
 77capture_output "OS release" "01-os-release.txt" "cat /etc/os-release"
 78capture_output "Kernel version" "01-kernel-version.txt" "cat /proc/version"
 79capture_output "System uptime" "01-uptime.txt" "uptime"
 80capture_output "Current date/time" "01-datetime.txt" "date"
 81capture_output "Timezone" "01-timezone.txt" "timedatectl"
 82capture_output "Hostname" "01-hostname.txt" "hostname -f"
 83capture_output "CPU info" "01-cpu-info.txt" "cat /proc/cpuinfo"
 84capture_output "Memory info" "01-memory-info.txt" "cat /proc/meminfo"
 85
 86echo ""
 87
 88#
 89# 2. Running Processes
 90#
 91echo -e "${CYAN}[2/10] Collecting Running Processes${NC}"
 92
 93capture_output "Process list (detailed)" "02-processes-full.txt" "ps auxwwf"
 94capture_output "Process list (tree)" "02-processes-tree.txt" "pstree -ap"
 95capture_output "Process list (sorted by CPU)" "02-processes-cpu.txt" "ps aux --sort=-%cpu | head -50"
 96capture_output "Process list (sorted by memory)" "02-processes-mem.txt" "ps aux --sort=-%mem | head -50"
 97capture_output "Process environment" "02-process-environ.txt" "find /proc/*/environ -type f 2>/dev/null | while read f; do echo \"=== \$f ===\"&&tr '\0' '\n' < \$f 2>/dev/null; done"
 98capture_output "Open files by processes" "02-lsof.txt" "lsof -n 2>/dev/null || echo 'lsof not available'"
 99
100echo ""
101
102#
103# 3. Network Connections
104#
105echo -e "${CYAN}[3/10] Collecting Network Information${NC}"
106
107capture_output "Network connections" "03-netstat.txt" "netstat -anptu 2>/dev/null || ss -anptu"
108capture_output "Network statistics" "03-netstat-stats.txt" "netstat -s"
109capture_output "Listening ports" "03-listening.txt" "netstat -nlptu 2>/dev/null || ss -nlptu"
110capture_output "IP configuration" "03-ip-addr.txt" "ip addr show"
111capture_output "IP routes" "03-ip-routes.txt" "ip route show"
112capture_output "ARP table" "03-arp.txt" "ip neigh show"
113capture_output "Network interfaces" "03-interfaces.txt" "ifconfig -a 2>/dev/null || ip link show"
114capture_output "DNS configuration" "03-resolv.txt" "cat /etc/resolv.conf"
115capture_output "Hosts file" "03-hosts.txt" "cat /etc/hosts"
116capture_output "Active connections summary" "03-connections-summary.txt" "netstat -an 2>/dev/null | awk '/tcp/ {print \$6}' | sort | uniq -c"
117
118echo ""
119
120#
121# 4. Logged-in Users
122#
123echo -e "${CYAN}[4/10] Collecting User Information${NC}"
124
125capture_output "Currently logged-in users" "04-who.txt" "who -a"
126capture_output "Last logged users" "04-last.txt" "last -F -n 50"
127capture_output "Failed login attempts" "04-lastb.txt" "lastb -F -n 50"
128capture_output "User accounts" "04-passwd.txt" "cat /etc/passwd"
129capture_output "Group accounts" "04-group.txt" "cat /etc/group"
130capture_output "Shadow file (hashes)" "04-shadow.txt" "cat /etc/shadow 2>/dev/null || echo 'Permission denied'"
131capture_output "Sudo configuration" "04-sudoers.txt" "cat /etc/sudoers 2>/dev/null || echo 'Permission denied'"
132capture_output "SSH authorized keys" "04-ssh-keys.txt" "find /home -name authorized_keys -exec echo '=== {} ===' \; -exec cat {} \; 2>/dev/null"
133
134echo ""
135
136#
137# 5. Recent File Modifications
138#
139echo -e "${CYAN}[5/10] Collecting Recent File Changes${NC}"
140
141capture_output "Recently modified files (/tmp)" "05-recent-tmp.txt" "find /tmp -type f -mtime -7 -ls 2>/dev/null"
142capture_output "Recently modified files (/var/tmp)" "05-recent-var-tmp.txt" "find /var/tmp -type f -mtime -7 -ls 2>/dev/null"
143capture_output "Recently modified files (/etc)" "05-recent-etc.txt" "find /etc -type f -mtime -7 -ls 2>/dev/null"
144capture_output "Recently modified files (/home)" "05-recent-home.txt" "find /home -type f -mtime -7 -ls 2>/dev/null | head -200"
145capture_output "SUID files" "05-suid-files.txt" "find / -type f \( -perm -4000 -o -perm -2000 \) -ls 2>/dev/null"
146capture_output "World-writable files" "05-world-writable.txt" "find / -xdev -type f -perm -0002 -ls 2>/dev/null | head -200"
147
148echo ""
149
150#
151# 6. Scheduled Tasks
152#
153echo -e "${CYAN}[6/10] Collecting Scheduled Tasks${NC}"
154
155capture_output "User crontabs" "06-crontabs.txt" "for user in \$(cut -f1 -d: /etc/passwd); do echo \"=== Crontab for \$user ===\"&&crontab -u \$user -l 2>/dev/null; done"
156capture_output "System crontab" "06-crontab-system.txt" "cat /etc/crontab"
157capture_output "Cron.d entries" "06-cron-d.txt" "ls -la /etc/cron.d/ 2>/dev/null && cat /etc/cron.d/* 2>/dev/null"
158capture_output "Cron daily" "06-cron-daily.txt" "ls -la /etc/cron.daily/ 2>/dev/null"
159capture_output "Cron hourly" "06-cron-hourly.txt" "ls -la /etc/cron.hourly/ 2>/dev/null"
160capture_output "Systemd timers" "06-systemd-timers.txt" "systemctl list-timers --all 2>/dev/null || echo 'systemd not available'"
161capture_output "At jobs" "06-at-jobs.txt" "atq 2>/dev/null || echo 'at not available'"
162
163echo ""
164
165#
166# 7. System Services
167#
168echo -e "${CYAN}[7/10] Collecting System Services${NC}"
169
170capture_output "Running services" "07-services-running.txt" "systemctl list-units --type=service --state=running 2>/dev/null || service --status-all 2>/dev/null"
171capture_output "All services" "07-services-all.txt" "systemctl list-unit-files --type=service 2>/dev/null || chkconfig --list 2>/dev/null"
172capture_output "Failed services" "07-services-failed.txt" "systemctl list-units --type=service --state=failed 2>/dev/null"
173
174echo ""
175
176#
177# 8. System Logs
178#
179echo -e "${CYAN}[8/10] Collecting System Logs (Last 24 Hours)${NC}"
180
181capture_output "Auth log" "08-auth.log" "tail -1000 /var/log/auth.log 2>/dev/null || tail -1000 /var/log/secure 2>/dev/null"
182capture_output "System log" "08-syslog.txt" "tail -1000 /var/log/syslog 2>/dev/null || tail -1000 /var/log/messages 2>/dev/null"
183capture_output "Kernel log" "08-kern.log" "tail -1000 /var/log/kern.log 2>/dev/null || dmesg"
184capture_output "Journal (last 24h)" "08-journal.txt" "journalctl --since '24 hours ago' --no-pager 2>/dev/null || echo 'journalctl not available'"
185capture_output "Failed login attempts (grep)" "08-failed-logins.txt" "grep -i 'failed\|failure' /var/log/auth.log 2>/dev/null | tail -200 || grep -i 'failed\|failure' /var/log/secure 2>/dev/null | tail -200"
186
187echo ""
188
189#
190# 9. Firewall and Security
191#
192echo -e "${CYAN}[9/10] Collecting Firewall and Security Configuration${NC}"
193
194capture_output "iptables rules (filter)" "09-iptables-filter.txt" "iptables -L -n -v --line-numbers 2>/dev/null"
195capture_output "iptables rules (nat)" "09-iptables-nat.txt" "iptables -t nat -L -n -v --line-numbers 2>/dev/null"
196capture_output "iptables rules (mangle)" "09-iptables-mangle.txt" "iptables -t mangle -L -n -v --line-numbers 2>/dev/null"
197capture_output "ip6tables rules" "09-ip6tables.txt" "ip6tables -L -n -v --line-numbers 2>/dev/null"
198capture_output "firewalld status" "09-firewalld.txt" "firewall-cmd --list-all 2>/dev/null || echo 'firewalld not available'"
199capture_output "UFW status" "09-ufw.txt" "ufw status verbose 2>/dev/null || echo 'ufw not available'"
200capture_output "SELinux status" "09-selinux.txt" "sestatus 2>/dev/null || echo 'SELinux not available'"
201capture_output "AppArmor status" "09-apparmor.txt" "aa-status 2>/dev/null || echo 'AppArmor not available'"
202
203echo ""
204
205#
206# 10. Create Summary Report
207#
208echo -e "${CYAN}[10/10] Creating Summary Report${NC}"
209
210SUMMARY_FILE="$EVIDENCE_DIR/00-SUMMARY.txt"
211
212cat > "$SUMMARY_FILE" << EOF
213========================================
214FORENSIC EVIDENCE COLLECTION SUMMARY
215========================================
216
217Incident ID: $INCIDENT_ID
218Collection Date: $(date '+%Y-%m-%d %H:%M:%S')
219Hostname: $(hostname)
220FQDN: $(hostname -f 2>/dev/null || hostname)
221Current User: $(whoami)
222OS: $(cat /etc/os-release 2>/dev/null | grep PRETTY_NAME | cut -d'"' -f2)
223Kernel: $(uname -r)
224Architecture: $(uname -m)
225
226========================================
227EVIDENCE FILES COLLECTED
228========================================
229
230$(ls -lh "$EVIDENCE_DIR" | tail -n +2)
231
232========================================
233SYSTEM SNAPSHOT
234========================================
235
236Uptime: $(uptime -p)
237Load Average: $(uptime | awk -F'load average:' '{print $2}')
238Active Processes: $(ps aux | wc -l)
239Active Network Connections: $(netstat -an 2>/dev/null | grep ESTABLISHED | wc -l)
240Listening Ports: $(netstat -ln 2>/dev/null | grep LISTEN | wc -l)
241Logged-in Users: $(who | wc -l)
242Memory Usage: $(free -h | awk '/^Mem:/ {print $3 " / " $2}')
243Disk Usage: $(df -h / | awk 'NR==2 {print $3 " / " $2 " (" $5 ")"}')
244
245========================================
246IMPORTANT NOTES
247========================================
248
2491. This evidence should be preserved in a secure location
2502. Maintain chain of custody documentation
2513. Do not modify or delete evidence files
2524. Consider creating a forensic image of the system
2535. Review all collected data for indicators of compromise
2546. Consult with legal/compliance teams before sharing
255
256========================================
257NEXT STEPS
258========================================
259
2601. Review evidence for suspicious activity
2612. Analyze network connections for C2 traffic
2623. Check running processes for malware
2634. Review system logs for security events
2645. Examine recent file modifications
2656. Verify all user accounts are legitimate
2667. Check for persistence mechanisms (cron, systemd timers)
2678. Document findings in incident report
268
269========================================
270EOF
271
272echo -e "      ${GREEN}Saved: 00-SUMMARY.txt${NC}"
273echo ""
274
275#
276# Create Archive
277#
278echo -e "${CYAN}[+] Creating Evidence Archive...${NC}"
279
280ARCHIVE_PATH="$EVIDENCE_DIR.tar.gz"
281tar -czf "$ARCHIVE_PATH" -C "$(dirname "$EVIDENCE_DIR")" "$(basename "$EVIDENCE_DIR")" 2>/dev/null
282
283if [[ -f "$ARCHIVE_PATH" ]]; then
284    echo -e "      ${GREEN}Archive created: $ARCHIVE_PATH${NC}"
285
286    # Calculate hash
287    HASH=$(sha256sum "$ARCHIVE_PATH" | awk '{print $1}')
288    echo "$HASH  $(basename "$ARCHIVE_PATH")" > "$ARCHIVE_PATH.sha256"
289
290    echo -e "      ${GREEN}SHA256: $HASH${NC}"
291    echo -e "      ${GREEN}Hash saved: $ARCHIVE_PATH.sha256${NC}"
292else
293    echo -e "      ${YELLOW}Warning: Failed to create archive${NC}"
294    echo -e "      ${YELLOW}Evidence directory preserved: $EVIDENCE_DIR${NC}"
295fi
296
297echo ""
298echo -e "${CYAN}========================================${NC}"
299echo -e "${CYAN} Evidence Collection Complete${NC}"
300echo -e "${CYAN}========================================${NC}"
301echo ""
302echo -e "${GREEN}Evidence Location: $EVIDENCE_DIR${NC}"
303echo -e "${GREEN}Archive Location: $ARCHIVE_PATH${NC}"
304echo ""
305echo -e "${YELLOW}IMPORTANT: Preserve evidence integrity!${NC}"
306echo -e "${YELLOW}  - Store in secure location${NC}"
307echo -e "${YELLOW}  - Document chain of custody${NC}"
308echo -e "${YELLOW}  - Do not modify collected data${NC}"
309echo ""

Usage

Windows (PowerShell)

Basic Collection

Lang: powershell
1# Run as Administrator
2.\evidence-collection.ps1

Specify Output Path

Lang: powershell
1.\evidence-collection.ps1 -OutputPath "D:\Forensics"

Specify Incident ID

Lang: powershell
1.\evidence-collection.ps1 -IncidentID "INC-2024-11-02-001"

Full Command

Lang: powershell
1.\evidence-collection.ps1 -OutputPath "D:\Forensics" -IncidentID "INC-2024-11-02-001"

Linux (Bash)

Basic Collection

Lang: bash
1sudo ./evidence-collection.sh

Specify Output Directory

Lang: bash
1sudo ./evidence-collection.sh /mnt/forensics

Specify Incident ID

Lang: bash
1sudo ./evidence-collection.sh /tmp/evidence INC-2024-11-02-001

Full Command

Lang: bash
1sudo ./evidence-collection.sh /mnt/forensics INC-2024-11-02-001

What It Collects

1. System Information

  • OS version and kernel details
  • System uptime and boot time
  • Hardware information (CPU, memory)
  • Installed hotfixes/patches
  • Environment variables

2. Running Processes

  • Complete process list with details
  • Process tree showing parent-child relationships
  • Process command lines and paths
  • Services status
  • Scheduled tasks and jobs

3. Network Connections

  • Active TCP/UDP connections
  • Listening ports and services
  • Network adapter configuration
  • ARP and DNS caches
  • Routing tables
  • SMB/CIFS sessions (Windows)

4. Logged-in Users

  • Currently logged-in users
  • Recent login history
  • Failed login attempts
  • User account information
  • Group memberships
  • SSH authorized keys (Linux)

5. Recent File Modifications

  • Files modified in last 7 days
  • System directories (/etc, /tmp, System32)
  • User directories (Downloads, AppData)
  • SUID/SGID files (Linux)
  • World-writable files (Linux)
  • Startup programs

6. Scheduled Tasks

  • Cron jobs (Linux)
  • Systemd timers (Linux)
  • Windows scheduled tasks
  • At jobs and batch files

7. System Logs

  • Authentication logs (successful/failed logins)
  • System event logs
  • Security logs
  • Application logs
  • Windows Defender alerts
  • Journal entries (Linux)

8. Security Configuration

  • Firewall rules and status
  • Windows Defender configuration
  • SELinux/AppArmor status (Linux)
  • Registry autoruns (Windows)
  • SSH configuration (Linux)

9. Summary Report

  • Collection metadata
  • System snapshot statistics
  • File inventory
  • Next steps recommendations
  • Chain of custody notes

10. Evidence Package

  • Compressed archive (ZIP/TAR.GZ)
  • SHA256 hash for integrity verification
  • Timestamped directory structure
  • Incident ID tracking

Evidence Package Structure

Lang:
hostname-20251102-151700-INC-12345/
├── 00-SUMMARY.txt                    # Summary report
├── 01-system-info.txt               # System information
├── 02-processes.txt                  # Running processes
├── 03-netstat.txt                    # Network connections
├── 04-logged-users.txt               # User information
├── 05-recent-tmp.txt                 # Recent file changes
├── 06-crontabs.txt                   # Scheduled tasks
├── 07-auth.log                       # Authentication logs
├── 08-syslog.txt                     # System logs
└── 09-iptables-filter.txt            # Firewall rules

Archive:
hostname-20251102-151700-INC-12345.tar.gz
hostname-20251102-151700-INC-12345.tar.gz.sha256

Chain of Custody Documentation

When collecting evidence, document:

  1. Who - Name of person collecting evidence
  2. What - Description of evidence collected
  3. When - Date and time of collection
  4. Where - System/location where evidence collected
  5. Why - Incident ID or case number
  6. How - Method used (this script)

Example Chain of Custody Form

Lang:
CHAIN OF CUSTODY RECORD

Case Number: INC-2024-11-02-001
Evidence Item: Forensic Evidence Collection Archive
File Name: webserver-20251102-151700-INC-12345.tar.gz
SHA256: a1b2c3d4e5f6... (from .sha256 file)

Collection:
  Date/Time: 2025-11-02 15:17:00 EST
  Collected By: John Smith
  System: webserver.company.com
  Method: evidence-collection.sh script

Storage:
  Location: Secure evidence server (//evidence/2025/INC-12345/)
  Date/Time: 2025-11-02 15:30:00 EST
  Stored By: John Smith

Access Log:
  2025-11-02 15:17:00 - John Smith - Collected
  2025-11-02 15:30:00 - John Smith - Stored
  2025-11-03 09:00:00 - Jane Doe - Analyzed

Integration with Incident Response

When to Collect Evidence

Based on the Incident Response Runbook:

  • Severity 1 (Critical): Collect immediately, but prioritize containment
  • Severity 2 (High): Collect within first hour
  • Severity 3 (Medium): Collect within 4 hours
  • Severity 4 (Low): Collect during investigation phase

Evidence Collection Workflow

  1. Identify affected systems from incident detection
  2. Isolate systems if needed (disconnect network but keep powered on)
  3. Run collection script on each affected system
  4. Transfer evidence to secure storage location
  5. Document chain of custody for each evidence package
  6. Verify integrity using SHA256 hash
  7. Begin analysis using collected evidence

Incident Response Phases

This script supports the Detection & Analysis phase:

  • Collect volatile data before it’s lost
  • Preserve evidence for forensic analysis
  • Document system state at time of incident
  • Support timeline reconstruction
  • Enable threat hunting and IOC identification

Important Considerations

Volatile Data Priority

Data is collected in order of volatility (most volatile first):

  1. Network connections and processes (can change instantly)
  2. Logged-in users and sessions
  3. Running services and scheduled tasks
  4. Recent file modifications
  5. System logs
  6. Configuration files

System Impact

  • Performance: Minimal impact (mostly read operations)
  • Disk Space: Requires 50-500MB depending on system size
  • Time: 2-5 minutes average collection time
  • Risk: Read-only operations, no system changes
  • Ensure authorization before collecting evidence
  • Follow company policies and legal requirements
  • Maintain chain of custody documentation
  • Consult legal team for sensitive incidents
  • Consider privacy regulations (GDPR, HIPAA, etc.)

Limitations

  • Does not capture memory dumps (use separate forensic tool)
  • Does not create disk images (use dd or forensic imaging tools)
  • May miss some artifacts if systems are severely compromised
  • Some data requires root/administrator privileges
  • Rootkits may hide processes or connections

Best Practices

Before Incident

  • Test script on non-production systems
  • Verify required permissions and tools
  • Prepare secure storage location
  • Document evidence collection procedures
  • Train IR team on script usage

During Incident

  • Collect from all affected systems
  • Document why evidence was collected
  • Preserve original evidence (don’t modify)
  • Use write-protected storage if possible
  • Note any anomalies during collection

After Collection

  • Verify archive integrity (check SHA256)
  • Store in multiple secure locations (backups)
  • Restrict access to authorized personnel only
  • Begin analysis promptly (evidence degrades over time)
  • Document findings in incident report

Advanced Usage

Automated Collection via SSH (Linux)

Lang: bash
 1#!/bin/bash
 2# Collect evidence from multiple servers
 3
 4SERVERS="web1 web2 db1 app1"
 5INCIDENT_ID="INC-2024-11-02-001"
 6
 7for server in $SERVERS; do
 8    echo "Collecting from $server..."
 9    ssh root@$server "bash -s" < evidence-collection.sh /tmp/evidence $INCIDENT_ID
10    scp root@$server:/tmp/evidence/*.tar.gz ./evidence/
11    scp root@$server:/tmp/evidence/*.sha256 ./evidence/
12done

Scheduled Evidence Collection

Note: Only schedule if required by policy. Normally run on-demand during incidents.

Lang: bash
1# Weekly evidence snapshots (cron)
20 2 * * 0 /usr/local/bin/evidence-collection.sh /var/evidence/weekly

Integration with SIEM

Send evidence collection trigger from SIEM when high-severity alert detected:

Lang: bash
1# Example SIEM response action
2curl -X POST https://server/api/collect-evidence \
3  -d "host=webserver01&incident=$ALERT_ID"

Troubleshooting

Permission Denied Errors

Some data requires elevated privileges:

Lang: bash
1# Linux
2sudo ./evidence-collection.sh
3
4# Windows (PowerShell as Administrator)
5.\evidence-collection.ps1

Missing Commands

Install required tools:

Lang: bash
1# Ubuntu/Debian
2sudo apt-get install lsof netstat psmisc
3
4# RHEL/CentOS
5sudo yum install lsof net-tools psmisc

Large Evidence Packages

Limit file collection or exclude directories:

Lang: bash
1# Modify script to reduce scope
2find /home -type f -mtime -7 -ls 2>/dev/null | head -100

Insufficient Disk Space

Specify alternate location with more space:

Lang: bash
1sudo ./evidence-collection.sh /mnt/storage

See Also

Download

Windows (PowerShell)

Lang: powershell
1curl -O https://glyph.sh/scripts/evidence-collection.ps1
2.\evidence-collection.ps1

Linux (Bash)

Lang: bash
1curl -O https://glyph.sh/scripts/evidence-collection.sh
2chmod +x evidence-collection.sh
3sudo ./evidence-collection.sh

References

  • NIST SP 800-86: Guide to Integrating Forensic Techniques into Incident Response
  • SANS Digital Forensics and Incident Response (DFIR) Guidelines
  • RFC 3227: Guidelines for Evidence Collection and Archiving