Chapter 4.3 - Incident Response and Digital Forensics
Module 4: Defense Engineering and Hardening Prerequisites: Chapter 4.2 (SIEM, SOAR and Detection Engineering)
Table of Contents
- Incident Response Framework - PICERL and NIST SP 800-61
- Triage and Scoping - Initial Compromise Assessment
- Evidence Collection and Chain of Custody
- Memory Forensics - Volatility and Process Analysis
- Disk Forensics - Imaging, Artifact Recovery and Timeline
- Network Forensics During IR - PCAP and Flow Analysis
- Windows Artifact Analysis - Registry, Prefetch and Event Logs
- Linux Artifact Analysis - Bash History, Cron and Systemd
- Containment, Eradication and Recovery
- MITRE ATT&CK Mapping
1. Incident Response Framework - PICERL and NIST SP 800-61
PICERL Phases
The standard IR lifecycle (SANS PICERL):
| Phase | Goal | Key Activities | Common Failures |
|---|---|---|---|
| Preparation | Build capability before incidents happen | IR plan, playbooks, tooling, retainer | No plan until breach occurs |
| Identification | Detect and confirm an incident | Alert triage, scope assessment, severity classification | Slow detection - long dwell time |
| Containment | Limit damage without destroying evidence | Network isolation, credential resets, firewall blocks | Rebooting before memory capture |
| Eradication | Remove attacker presence completely | Malware removal, backdoor hunting, account cleanup | Missing persistence mechanisms |
| Recovery | Restore affected systems safely | Clean rebuild, patch, monitoring increase | Returning to production too early |
| Lessons Learned | Improve posture for next time | Post-incident review, detection gaps, playbook updates | Skipped entirely under pressure |
Incident Severity Classification
#!/usr/bin/env python3
def classify_severity(indicators: dict) -> tuple:
score = 0
reasons = []
if indicators.get('domain_admin_compromised'):
score += 50; reasons.append("Domain Admin account confirmed compromised")
if indicators.get('data_exfiltration_confirmed'):
score += 40; reasons.append("Data exfiltration confirmed")
if indicators.get('ransomware_detected'):
score += 60; reasons.append("Ransomware/encryption activity detected")
if indicators.get('lateral_movement_confirmed'):
score += 30; reasons.append("Lateral movement to multiple hosts")
if indicators.get('persistence_confirmed'):
score += 20; reasons.append("Attacker persistence mechanism found")
if indicators.get('hosts_affected', 0) > 10:
score += 20; reasons.append(f"{indicators['hosts_affected']} hosts affected")
if indicators.get('critical_system_affected'):
score += 30; reasons.append("Critical business system affected")
if score >= 80:
return ("CRITICAL", "15 minutes", ["Immediate CISO notification", "Activate IR retainer"])
elif score >= 50:
return ("HIGH", "1 hour", ["IR team lead notification", "Begin containment immediately"])
elif score >= 25:
return ("MEDIUM", "4 hours", ["Assign senior analyst", "Begin investigation"])
else:
return ("LOW", "24 hours", ["Assign to standard queue"])
2. Triage and Scoping - Initial Compromise Assessment
The first 30 minutes of an IR are critical. The goal is not full forensic analysis - it is rapid scope determination: how many systems are affected, what is the attacker doing right now, and is the attack ongoing.
Live System Triage - Windows
# Run as Administrator - collect volatile system state quickly
# 1. Current timestamp (for timeline correlation)
Get-Date -Format "yyyy-MM-dd HH:mm:ss UTC" | Out-File C:\IR\triage.txt
# 2. Running processes with full paths and hashes
Get-Process | Select-Object Name, Id, Path, CPU, WorkingSet, StartTime |
Export-Csv C:\IR\processes.csv -NoTypeInformation
Get-Process | Where-Object {$_.Path} | ForEach-Object {
$hash = (Get-FileHash $_.Path -Algorithm SHA256 -ErrorAction SilentlyContinue).Hash
[PSCustomObject]@{ Name=$_.Name; PID=$_.Id; Path=$_.Path; SHA256=$hash }
} | Export-Csv C:\IR\process_hashes.csv -NoTypeInformation
# 3. Active network connections with owning process
Get-NetTCPConnection -State Established,Listen |
Select-Object LocalAddress,LocalPort,RemoteAddress,RemotePort,State,OwningProcess |
Export-Csv C:\IR\connections.csv -NoTypeInformation
# 4. Logged-on users
query session
query user
# 5. Scheduled tasks (persistence check)
Get-ScheduledTask | Where-Object {$_.State -ne 'Disabled'} |
Select-Object TaskName, TaskPath, State,
@{N='Execute';E={$_.Actions.Execute}},
@{N='Arguments';E={$_.Actions.Arguments}} |
Export-Csv C:\IR\scheduled_tasks.csv -NoTypeInformation
# 6. Autorun locations
$autorun_keys = @(
"HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run",
"HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run",
"HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce",
"HKLM:\SYSTEM\CurrentControlSet\Services"
)
foreach ($key in $autorun_keys) {
Get-ItemProperty $key -ErrorAction SilentlyContinue | Out-File -Append C:\IR\autoruns.txt
}
# 7. Recently modified files (last 24 hours)
Get-ChildItem C:\Windows\Temp, C:\Users\*\AppData\Local\Temp, C:\ProgramData `
-Recurse -ErrorAction SilentlyContinue |
Where-Object {$_.LastWriteTime -gt (Get-Date).AddHours(-24)} |
Select-Object FullName, LastWriteTime, Length |
Export-Csv C:\IR\recent_files.csv -NoTypeInformation
Live System Triage - Linux
IR_DIR="/tmp/ir_$(date +%Y%m%d_%H%M%S)"
mkdir -p $IR_DIR
# 1. System information
date > $IR_DIR/timestamp.txt
uname -a >> $IR_DIR/sysinfo.txt
# 2. Running processes - detect deleted-but-running binaries
ps auxf > $IR_DIR/processes.txt
ls -la /proc/*/exe 2>/dev/null > $IR_DIR/proc_exe_links.txt
# KEY: "(deleted)" in exe link = binary ran then removed
# 3. Network connections
ss -tulnp > $IR_DIR/listening_ports.txt
ss -tnp state established > $IR_DIR/established.txt
arp -a > $IR_DIR/arp_cache.txt
# 4. Persistence locations
crontab -l 2>/dev/null > $IR_DIR/crontab_root.txt
for user in $(cut -f1 -d: /etc/passwd); do
crontab -l -u $user 2>/dev/null | awk -v u="$user" 'NF {print u": "$0}' \
>> $IR_DIR/crontabs_all.txt
done
# New systemd service units (modified after passwd = suspicious)
find /etc/systemd /usr/lib/systemd /lib/systemd \
-name "*.service" -newer /etc/passwd 2>/dev/null > $IR_DIR/new_systemd_units.txt
# 5. SUID/SGID files (persistence via SUID bit)
find / -not \( -path /proc -prune \) -perm -4000 -type f 2>/dev/null > $IR_DIR/suid_files.txt
# 6. Open network sockets
lsof -nP -i 2>/dev/null > $IR_DIR/open_network_files.txt
# 7. Loaded kernel modules (rootkit detection)
lsmod > $IR_DIR/kernel_modules.txt
# 8. Package integrity check
rpm -Va 2>/dev/null > $IR_DIR/rpm_verify.txt # RHEL
dpkg --verify 2>/dev/null > $IR_DIR/dpkg_verify.txt # Debian
# Lines with "5" in first column = hash changed = file modified
3. Evidence Collection and Chain of Custody
Every piece of evidence must be collected with documented chain of custody: who, when, what, how, where stored.
# Generate evidence hash immediately after collection
sha256sum /evidence/workstation01_memory.lime > /evidence/workstation01_memory.lime.sha256
md5sum /evidence/workstation01_memory.lime > /evidence/workstation01_memory.lime.md5
# Document the collection
cat > /evidence/COC_workstation01.txt << EOF
CHAIN OF CUSTODY
================
Case Number: IR-2024-042
Evidence Item: workstation01_memory.lime
Investigator: J. Smith (jsmith@corp.com)
Date Collected: $(date -u)
Hostname: WORKSTATION-01
IP Address: 192.168.1.105
Method: LiME kernel module loaded via SSH
SHA256: $(sha256sum /evidence/workstation01_memory.lime | cut -d' ' -f1)
MD5: $(md5sum /evidence/workstation01_memory.lime | cut -d' ' -f1)
Notes: System running; acquisition performed before containment
EOF
Remote Collection at Scale - Velociraptor
# Velociraptor: collect from all Windows endpoints simultaneously
velociraptor --config /etc/velociraptor/server.config.yaml \
artifacts collect Windows.System.Pslist \
--args Hunt=true --args ClientId="ALL"
# Artifacts to collect:
# - Windows.EventLogs.Evtx (Security, System, Application logs)
# - Windows.System.Pslist (running processes)
# - Windows.Network.Netstat (connections)
# - Windows.Persistence.PersistentItems (all persistence mechanisms)
# - Windows.System.Amcache (execution history)
4. Memory Forensics - Volatility and Process Analysis
Memory forensics recovers artifacts that exist only in RAM: running processes (including fileless malware), network connections at time of capture, decrypted strings, injected shellcode, and registry hives.
Acquiring Memory
# Linux memory acquisition with LiME
git clone https://github.com/504ensicsLabs/LiME
cd LiME/src && make
# Acquire over network (preferred - avoids writing to target disk)
# On collection workstation:
nc -l -p 4444 > /evidence/target_memory.lime
# On target:
sudo insmod lime-$(uname -r).ko "path=tcp:4444 format=lime"
# Windows memory acquisition
winpmem_mini_x64_rc2.exe -o C:\evidence\memory.raw
DumpIt.exe /O C:\evidence\memory.raw /Q
Volatility 3 - Memory Analysis
pip install volatility3
# List all processes
python3 vol.py -f memory.lime windows.pslist
# Process tree (shows parent-child relationships)
python3 vol.py -f memory.lime windows.pstree
# Look for: cmd.exe parent=Word, powershell parent=excel
# Scan for hidden processes (psscan scans pool tags, finds hidden/terminated)
python3 vol.py -f memory.lime windows.psscan
# Processes in psscan NOT in pslist = hidden by rootkit
# Find injected code (malfind - looks for RWX memory regions)
python3 vol.py -f memory.lime windows.malfind --pid 1234
# KEY INDICATOR: MZ header in injected region = PE file injected into process
# Dump suspicious process memory for YARA scanning
python3 vol.py -f memory.lime windows.memmap --pid 1234 --dump
# Active/recent network connections
python3 vol.py -f memory.lime windows.netstat
# Shows PID, process name, local/remote addr:port, state, creation time
# Credential extraction
python3 vol.py -f memory.lime windows.hashdump # NTLM hashes from SAM
python3 vol.py -f memory.lime windows.cachedump # Cached domain credentials
python3 vol.py -f memory.lime windows.lsadump # LSA secrets
# Command lines of all processes
python3 vol.py -f memory.lime windows.cmdline
# Detect DLL injection/sideloading
python3 vol.py -f memory.lime windows.dlllist --pid 1234
# Registry key from memory
python3 vol.py -f memory.lime windows.registry.printkey \
--key "SOFTWARE\Microsoft\Windows\CurrentVersion\Run"
# YARA scan
python3 vol.py -f memory.lime windows.yarascan \
--yara-file /etc/yara/rules/cobalt_strike.yar
# Linux equivalents
python3 vol.py -f memory.lime linux.bash
python3 vol.py -f memory.lime linux.pslist
python3 vol.py -f memory.lime linux.netstat
5. Disk Forensics - Imaging, Artifact Recovery and Timeline
Forensic Disk Imaging
# dd - bit-for-bit image with error handling
dd if=/dev/sda \
of=/evidence/sda.img \
bs=512 \
conv=noerror,sync \
status=progress
# Verify image integrity
sha256sum /dev/sda > /evidence/sda.sha256_source
sha256sum /evidence/sda.img > /evidence/sda.sha256_image
diff <(cut -d' ' -f1 /evidence/sda.sha256_source) \
<(cut -d' ' -f1 /evidence/sda.sha256_image)
# Must match exactly
# ewfacquire - Expert Witness Format with compression and metadata
ewfacquire \
-t /evidence/workstation01 \
-c deflate \
-C "IR-2024-042" \
-e "J. Smith" \
/dev/sda
# Mount image read-only for analysis
mkdir /mnt/evidence_sda
mount -o ro,noexec,loop,offset=$((512*2048)) \
/evidence/sda.img /mnt/evidence_sda
File System Timeline - The Sleuth Kit and Plaso
# List partitions in image
mmls /evidence/sda.img
# Generate MAC times bodyfile
fls -r -m / -o 2048 /evidence/sda.img > /tmp/bodyfile.txt
# Human-readable timeline
mactime -b /tmp/bodyfile.txt -d -z UTC > /tmp/timeline.csv
# Filter to incident window
grep "2024-01-15" /tmp/timeline.csv | grep -E "NTFS|ADDED|CHANGED" | head -100
# Plaso - comprehensive timeline from ALL artifacts
pip install plaso
log2timeline.py \
--storage-file /tmp/evidence.plaso \
--parsers win7 \
/mnt/evidence_sda/
# Export to CSV with date filter
psort.py \
--output-time-zone UTC \
-o l2tcsv \
-w /tmp/supertimeline.csv \
/tmp/evidence.plaso \
"date > '2024-01-14' AND date < '2024-01-16'"
# Artifacts automatically processed by Plaso:
# $MFT (NTFS Master File Table), Windows Event Logs (.evtx),
# Prefetch files, Registry hives, LNK files, Browser history,
# Shellbags, Jump lists, Recycle Bin
6. Network Forensics During IR - PCAP and Flow Analysis
# Reconstruct TCP sessions from PCAP
tcpflow -r /evidence/incident.pcap -o /tmp/tcp_sessions/ -a -g
# Extract all files transferred over HTTP
tshark -r /evidence/incident.pcap \
--export-objects "http,/tmp/http_objects/"
tshark -r /evidence/incident.pcap \
--export-objects "smb,/tmp/smb_objects/"
# Reconstruct DNS queries (C2 domain, DGA, DNS tunneling)
tshark -r /evidence/incident.pcap \
-Y 'dns.flags.response == 1' \
-T fields -e frame.time -e ip.src -e dns.qry.name -e dns.a \
> /tmp/dns_resolutions.txt
# Find data exfiltration - large outbound transfers
tshark -r /evidence/incident.pcap -q -z "conv,tcp" | \
sort -t ' ' -k 10 -rn | head -20
# Identify C2 beaconing - low jitter periodic connections
python3 << 'PYEOF'
import dpkt, socket, collections, numpy as np
sessions = collections.defaultdict(list)
with open('/evidence/incident.pcap','rb') as f:
pcap = dpkt.pcap.Reader(f)
for ts, buf in pcap:
try:
eth = dpkt.ethernet.Ethernet(buf)
ip = eth.data
if isinstance(ip.data, dpkt.tcp.TCP):
tcp = ip.data
if tcp.flags & dpkt.tcp.TH_SYN and not tcp.flags & dpkt.tcp.TH_ACK:
src = socket.inet_ntoa(ip.src)
dst = socket.inet_ntoa(ip.dst)
sessions[f"{src}->{dst}:{tcp.dport}"].append(ts)
except: pass
print(f"{'Connection':<50} {'Count':>6} {'Avg Interval':>14} {'Jitter':>8}")
for conn, timestamps in sorted(sessions.items(), key=lambda x: len(x[1]), reverse=True)[:20]:
if len(timestamps) < 5: continue
intervals = np.diff(sorted(timestamps))
avg = np.mean(intervals)
jitter = np.std(intervals) / avg if avg > 0 else 999
flag = " <- BEACON?" if jitter < 0.2 and avg < 300 else ""
print(f"{conn:<50} {len(timestamps):>6} {avg:>13.1f}s {jitter:>7.3f}{flag}")
PYEOF
7. Windows Artifact Analysis - Registry, Prefetch and Event Logs
Registry Forensics
from Registry import Registry
import datetime
# Parse SOFTWARE hive
reg = Registry.Registry("/mnt/evidence_sda/Windows/System32/config/SOFTWARE")
# Check Run key (autostart persistence)
key = reg.open("Microsoft\\Windows\\CurrentVersion\\Run")
print("=== HKLM Run Key ===")
for value in key.values():
print(f" {value.name()}: {value.value()}")
print(f" Last Modified: {key.timestamp()}")
# UserAssist - GUI program execution history (ROT-13 encoded)
import struct, codecs
user_reg = Registry.Registry("/mnt/evidence_sda/Users/victim/NTUSER.DAT")
key = user_reg.open(
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\UserAssist\\"
"{CEBFF5CD-ACE2-4F4F-9178-9926F41749EA}\\Count")
print("\n=== UserAssist (GUI Executions) ===")
for value in key.values():
name = codecs.decode(value.name(), 'rot_13')
data = value.value()
if len(data) >= 72:
run_count = struct.unpack('<I', data[4:8])[0]
ts_raw = struct.unpack('<Q', data[60:68])[0]
if ts_raw > 0:
ts = datetime.datetime(1601,1,1) + datetime.timedelta(microseconds=ts_raw//10)
print(f" [{run_count:>4}x] {ts} | {name}")
Prefetch Analysis
Prefetch files record program execution: name, run count, timestamps, and loaded files. Location: C:\Windows\Prefetch\
# Eric Zimmermann's PECmd (Windows)
PECmd.exe -d C:\Windows\Prefetch --csv C:\IR\prefetch.csv
# Key fields: executable name, run count, last 8 execution timestamps, loaded files
# High-value indicators:
# - psexec.exe, mimikatz.exe, cobalt_strike, meterpreter variants
# - Executables running from temp directories
# - Tools executed once and deleted (single run count, no disk artifact)
Windows Event Log Analysis
import Evtx.Evtx as evtx
import xml.etree.ElementTree as ET
logon_types = {
'2': 'Interactive', '3': 'Network', '4': 'Batch',
'5': 'Service', '7': 'Unlock', '8': 'NetworkCleartext',
'9': 'NewCredentials', '10': 'RemoteInteractive', '11': 'CachedInteractive'
}
# Key Event IDs for IR:
# 4624 - Logon success
# 4625 - Logon failure
# 4648 - Explicit credentials used
# 4698 - Scheduled task created
# 4720 - New account created
# 7045 - New service installed
suspicious_events = []
with evtx.Evtx("/evidence/Security.evtx") as log:
for record in log.records():
try:
root = ET.fromstring(record.xml())
ns = {'e': 'http://schemas.microsoft.com/win/2004/08/events/event'}
event_id = root.find('.//e:EventID', ns).text
if event_id in ['4624', '4625', '4648', '4698', '4720', '7045']:
time_created = root.find('.//e:TimeCreated', ns).get('SystemTime')
data = {d.get('Name'): d.text
for d in root.findall('.//e:Data', ns) if d.get('Name')}
entry = {
'time': time_created, 'event_id': event_id,
'user': data.get('TargetUserName', ''),
'src_ip': data.get('IpAddress', ''),
}
# Flag NTLM network logons (potential Pass-the-Hash)
if event_id == '4624' and data.get('LogonType') == '3' \
and data.get('AuthenticationPackageName') == 'NTLM':
entry['FLAG'] = 'POSSIBLE PtH - NTLM NETWORK LOGON'
suspicious_events.append(entry)
elif event_id in ['4698', '4720', '7045']:
entry['FLAG'] = 'PERSISTENCE/PRIVILEGE'
suspicious_events.append(entry)
except: pass
for e in sorted(suspicious_events, key=lambda x: x['time']):
print(f"{e['time'][:19]} | EID:{e['event_id']} | {e.get('FLAG','')} | "
f"User:{e['user']} | From:{e['src_ip']}")
8. Linux Artifact Analysis - Bash History, Cron and Systemd
# Bash history reconstruction
cat /home/*/.bash_history 2>/dev/null
cat /root/.bash_history 2>/dev/null
# Also check: ~/.zsh_history, ~/.fish_history
# /var/log/auth.log - authentication and sudo events
grep -E "sudo|su |Failed|Accepted|Invalid" /var/log/auth.log | tail -200
# Commands run via sudo (even if history cleared)
grep "COMMAND=" /var/log/auth.log | tail -50
# Systemd journal - comprehensive event log
journalctl \
--since "2024-01-14 00:00:00" \
--until "2024-01-15 23:59:59" \
--no-pager -o json > /tmp/journal_incident.json
# SSH service events specifically
journalctl -u sshd --since "2024-01-14" --no-pager
# Find new/modified systemd units (persistence)
find /etc/systemd /usr/lib/systemd /lib/systemd \
-name "*.service" -newer /etc/hostname 2>/dev/null -exec cat {} \;
# Detect LD_PRELOAD hijacking
cat /etc/ld.so.preload 2>/dev/null # Should be empty
# Root-equivalent accounts (UID 0)
awk -F: '$3 == 0 {print "ROOT ACCOUNT:", $1}' /etc/passwd
# SSH authorized_keys additions (persistence)
find /home /root -name "authorized_keys" -exec ls -la {} \; -exec cat {} \;
# Webshell detection
find /var/www /srv/www /opt/*/htdocs \
-name "*.php" -o -name "*.asp" -o -name "*.jsp" 2>/dev/null \
-newer /var/log/syslog -exec ls -la {} \;
grep -r --include="*.php" -l \
-E "eval\(base64_decode|system\(|passthru\(|exec\(|\$_POST\[|shell_exec" \
/var/www/ 2>/dev/null
9. Containment, Eradication and Recovery
Network Containment
# Full isolation (CRITICAL incidents) - allow only IR team
iptables -I INPUT 1 -s IR_TEAM_IP -j ACCEPT
iptables -I OUTPUT 1 -d IR_TEAM_IP -j ACCEPT
iptables -I INPUT 2 -j DROP
iptables -I OUTPUT 2 -j DROP
iptables -I FORWARD 1 -j DROP
# Targeted blocking (MEDIUM - preserve functionality)
iptables -I OUTPUT -d C2_IP -j DROP
iptables -I INPUT -s ATTACKER_IP -j DROP
Credential Containment
# If credentials were harvested - bulk password reset
$affected_users = @("jsmith", "admin", "svc-web", "helpdesk01")
foreach ($user in $affected_users) {
$newpass = ConvertTo-SecureString (New-Guid).ToString() -AsPlainText -Force
Set-ADAccountPassword -Identity $user -NewPassword $newpass -Reset
Set-ADUser $user -ChangePasswordAtLogon $true
Write-Host "Reset: $user"
}
# If DA credentials compromised: reset krbtgt TWICE (24 hours apart)
# First reset invalidates all existing tickets
# Second reset ensures no Golden Tickets remain valid
# Force Azure AD session revocation
Revoke-AzureADUserAllRefreshToken -ObjectId USER_OBJECT_ID
Eradication Checklist
# 1. Autoruns - all autostart locations
autorunsc.exe -accepteula -a * -c -h -vt > C:\IR\autoruns_scan.csv
# 2. Scheduled tasks
schtasks /query /fo csv /v > C:\IR\scheduled_tasks.csv
# 3. WMI subscriptions (stealthy persistence - often missed)
Get-WMIObject -Namespace root\subscription -Class __EventFilter
Get-WMIObject -Namespace root\subscription -Class __EventConsumer
Get-WMIObject -Namespace root\subscription -Class __FilterToConsumerBinding
# ANY results not from known software = WMI persistence
# Remove malicious WMI subscription
Get-WMIObject -Namespace root\subscription -Class __FilterToConsumerBinding |
Where-Object {$_.Consumer -like "*malicious*"} |
Remove-WMIObject
# 4. COM hijacking detection (HKCU registry override)
Get-ChildItem "HKCU:\Software\Classes\CLSID" |
Select-Object Name, @{N='Value';E={(Get-ItemProperty $_.PSPath).'(default)'}}
# 5. Validate eradication - second scan after manual removal
# Run AV/EDR full scan AFTER manual removal
# Verify no re-infection indicators in SIEM 24h post-recovery
Recovery
# NEVER restore from a backup taken after the compromise date
# Find last clean backup BEFORE attacker's initial access timestamp
# Clean rebuild is always preferred over patching compromised system:
# 1. Wipe and reimage from known-good golden image
# 2. Apply all patches before connecting to network
# 3. Restore data from pre-compromise backup only
# 4. Validate with EDR scan before production use
# 30-day enhanced monitoring post-recovery
nmap -sV -p- RECOVERED_HOST # Verify no unexpected services
cme smb RECOVERED_HOST -u admin -p pass --processes
10. MITRE ATT&CK Mapping
| Technique | ID | IR Detection Method | Evidence Source |
|---|---|---|---|
| Process Injection | T1055 | malfind - RWX memory regions | Memory dump (Volatility) |
| Fileless Malware | T1059 | In-memory artifacts, no disk file | Memory forensics only |
| Scheduled Task Persistence | T1053.005 | Task XML in System32\Tasks | Disk image + Event 4698 |
| Registry Run Key | T1547.001 | Registry hive analysis | NTUSER.DAT, SOFTWARE hive |
| WMI Subscription | T1546.003 | WMI repository query | WMI repository database |
| New Service | T1543.003 | Service binary hash check | SYSTEM hive + Event 7045 |
| Data Exfiltration | T1041 | Large outbound flows in PCAP | NetFlow + PCAP analysis |
| Credential Dumping | T1003 | LSASS memory access in EDR | Memory dump + Event 4663 |
| Lateral Movement | T1021 | Cross-host logon correlation | Event 4624 type 3 chain |
| Defense Evasion: Timestomping | T1070.006 | MFT STANDARD vs FILENAME mismatch | NTFS MFT analysis |
| Account Manipulation | T1098 | New accounts in AD, auth.log | Event 4720 + /etc/passwd |
| Boot/Logon Initialization | T1037 | Startup scripts + systemd units | Disk image + journalctl |