Ransomware Walkthrough
This chapter walks through a complete ransomware incident — LockBit 3.0 — from the perspective of network forensics. The goal: reconstruct the entire attack chain from initial access to encryption using only Zeek logs, Suricata alerts, and NetFlow data. This is the kind of analysis you present in an incident report to demonstrate the scope, timeline, and patient-zero identification.
Day 0: Users report files encrypted with .lock3d extension. Ransom note references "LockBit 3.0". You have 30 days of Zeek logs, 7 days of Arkime PCAP, and 30 days of NetFlow. Your task: determine when the attacker first gained access, what they did during the dwell time, which hosts are encrypted, and whether any data was exfiltrated before encryption.
Full Incident Timeline (Network Evidence)
LockBit 3.0 Incident — Reconstructed from Network Data
═══════════════════════════════════════════════════════════════════
Day -21 (21 days before encryption):
└── Zeek conn.log: Cobalt Strike beacon starts from 10.0.5.22
ssl.log: JA3 51c64c77e60f3980 → dst 203.0.113.14:443
Beacon interval: 60s, CV=0.03 — NOT detected at the time
Day -18:
└── Zeek kerberos.log: 10.0.5.22 → DC, 12 TGS requests in 20 seconds
Kerberoasting 12 service accounts → ticket blobs cracked offline
Day -14:
└── Zeek conn.log: 10.0.5.22 → 10.0.5.50 port 445 → PsExec pivot
└── Zeek ssl.log: Cobalt Strike beacon NOW from 10.0.5.50 too
Day -10:
└── Zeek conn.log: 10.0.5.50 → domain controller 10.0.0.10 port 445
admin$ + svcctl → indicates access to DC
Day -7 to -2:
└── NetFlow: 10.0.5.50 → external IP 51.x.x.x port 443
Total bytes: 47 GB over 5 days (exfiltration via HTTPS)
ssl.log: SNI = "backup-sync.io" (attacker domain)
Day -1:
└── Zeek conn.log: 10.0.5.50 → 64 unique internal IPs port 445
(Deploying LockBit ransomware via SMB to all accessible hosts)
Day 0 (06:30 AM):
└── SMB writes spike: >1000 file create/modify operations per minute
(Encryption in progress across file servers)
08:00 AM: Users report encrypted files.
Investigation begins with network data from Day -21.
Incident Reconstruction Queries
#!/bin/bash
ZEEK_ARCHIVE="${1:-/opt/zeek/logs}"
CS_JA3="51c64c77e60f3980eea90869b68c58a8"
echo "=== Step 1: When did the initial beacon start? ==="
find "$ZEEK_ARCHIVE" -name "ssl.log*" | sort | \
xargs -I{} zcat -f {} 2>/dev/null | \
grep "$CS_JA3" | head -5 | \
awk -F'\t' '{print "First CS beacon: " $1 " from " $3 " to " $5}'
echo ""
echo "=== Step 2: Which hosts had beacons? ==="
find "$ZEEK_ARCHIVE" -name "ssl.log*" | \
xargs -I{} zcat -f {} 2>/dev/null | \
grep "$CS_JA3" | awk -F'\t' '{print $3}' | sort | uniq -c | sort -rn | \
head -10
echo ""
echo "=== Step 3: Kerberoasting timeline ==="
find "$ZEEK_ARCHIVE" -name "kerberos.log*" | \
xargs -I{} zcat -f {} 2>/dev/null | \
awk '!/^#/' | awk -F'\t' '$7=="TGS" {print $1"\t"$3"\t"$6}' | \
awk -F'\t' '{date=substr($1,1,10); count[date"\t"$2]++}
END {for(k in count) if(count[k]>5) print count[k], k}' | sort -rn
echo ""
echo "=== Step 4: Lateral movement fan-out days ==="
find "$ZEEK_ARCHIVE" -name "conn.log*" | \
xargs -I{} zcat -f {} 2>/dev/null | \
awk '!/^#/' | \
awk -F'\t' '$6=="445" && $5 ~ /^10\./ {
date = substr($1, 1, 10)
print date"\t"$3"\t"$5
}' | sort -u | \
awk -F'\t' '{print $1"\t"$2}' | sort | uniq -c | sort -rn | \
awk '$1 > 10 {print "Day " $2 " src=" $3 " → " $1 " unique SMB targets"}'
echo ""
echo "=== Step 5: Exfiltration volume by day ==="
find "$ZEEK_ARCHIVE" -name "conn.log*" | \
xargs -I{} zcat -f {} 2>/dev/null | \
awk '!/^#/' | \
awk -F'\t' '
$5 !~ /^(10\.|172\.(1[6-9]|2[0-9]|3[01])\.|192\.168\.)/ &&
$9+0 > 0 {
date = substr($1, 1, 10)
bytes[date] += $9+0
}
END {
for(d in bytes) printf "%s %.1f MB outbound\n", d, bytes[d]/1048576
}' | sort
echo ""
echo "=== Step 6: Scope — unique hosts with SMB activity on encryption day ==="
ENCRYPTION_DAY=$(date +%Y-%m-%d) # Replace with actual encryption date
find "$ZEEK_ARCHIVE" -name "conn.log*" -path "*${ENCRYPTION_DAY}*" | \
xargs -I{} zcat -f {} 2>/dev/null | \
awk '!/^#/' | \
awk -F'\t' '$6=="445" && $5 ~ /^10\./ {print $5}' | \
sort -u | wc -l | \
xargs -I{} echo "{} unique internal hosts received SMB connections on encryption day"
Attackers routinely delete Windows Event Log entries, clear PowerShell history, and disable logging as part of covering their tracks. Endpoint forensics is valuable but unreliable when a sophisticated attacker has had administrative access. Network logs — Zeek, NetFlow, Arkime PCAP — are stored on dedicated monitoring infrastructure that the attacker may not have been able to access or modify. Even if the attacker cleared logs on every compromised endpoint, the Zeek conn.log from the network sensor still recorded every connection they made. This is the forensic value of network-based evidence: it's outside the attacker's blast radius when they control only the endpoints. For a full incident report: use endpoint logs for what happened on the host (which processes ran, which files were accessed), use network logs for what communicated where and when (source of truth for lateral movement, C2 activity, and exfiltration scope). The combination gives you the most complete picture.
Q & A
Q: The ransomware operator says no data was exfiltrated. How do I verify or refute this claim from network data?
This is a critical question for breach notification decisions. Network-evidence approach: (1) Zeek conn.log cumulative bytes: total bytes_toserver from all compromised hosts to all external IPs during the dwell period. If this sum exceeds what's explainable by normal browsing and software updates, data left the network. (2) Identify the destinations: find the specific external IPs or domains that received the most data. Look these up in threat intel, WHOIS, and BGP data — attacker infrastructure has patterns (bulletproof hosting, recently registered AS, IPs associated with ransomware groups). (3) Protocol breakdown: normal business traffic to external is mostly browsing (HTTPS to known sites). Large SFTP or raw TCP transfers to unknown IPs are anomalous. (4) PCAP review: if Arkime has PCAP for the exfiltration sessions, retrieve them. TLS encryption may prevent reading the content, but protocol (FTP data vs HTTPS upload vs TCP raw transfer) and timing are visible. If the TLS cert for the destination can be obtained (active probing), JARM can confirm it's attacker infrastructure. (5) Honest uncertainty: if encrypted channels were used and you can't decrypt them, you cannot prove data was NOT exfiltrated. The appropriate statement is: "We observed X GB of outbound encrypted traffic to Y destination during the dwell period. We cannot exclude exfiltration." This is the honest forensic conclusion from network-only evidence.