Week: 7 -- Network Forensics
Points: 20
Time estimate: 90 min lab + 3 hr independent
Deliverable: lab-8-report.md + custom Suricata rule
Objectives
- Import the academy
intrusion-lateral.pcapinto Zeek and generate structured logs. - Run RITA against the beaconing corpus; identify the C2 candidate.
- Reconstruct the multi-phase intrusion timeline to 3-event granularity: initial access, pivot, exfiltration.
- Write a Suricata signature that would have detected the C2 channel; verify it fires.
Part A: Timeline Reconstruction (45 min)
# Import intrusion pcap into Zeek
mkdir lab8-zeek && cd lab8-zeek
zeek -r ~/academy-corpus/intrusion-lateral.pcap LogAscii::use_json=T
# Generate a unified sorted timeline
python3 - <<'EOF'
import json, glob, sys
from datetime import datetime
events = []
for logfile in glob.glob("*.log"):
log_type = logfile.replace(".log", "")
with open(logfile) as f:
for line in f:
try:
e = json.loads(line)
if 'ts' in e:
events.append((float(e['ts']), log_type, e))
except:
pass
# Print sorted timeline
for ts, log_type, e in sorted(events)[:200]:
src = e.get('id.orig_h', e.get('src', ''))
dst = e.get('id.resp_h', e.get('dst', ''))
summary = e.get('notice', e.get('note', e.get('name', e.get('mime_type', ''))))
print(f"{datetime.utcfromtimestamp(ts).isoformat()} [{log_type}] {src} -> {dst} | {summary}")
EOF
From the timeline, identify:
- Initial access event: what was the first suspicious connection? Source IP? Destination? Protocol? Timestamp?
- Lateral movement event: what connection indicates the attacker moved from the initial foothold to another internal host? What protocol (SMB? WinRM? RPC)?
- Exfiltration event: what connection carries data outbound? Destination IP? Protocol? Data volume?
Document each event with: timestamp, source IP, destination IP, port/protocol, supporting Zeek log entry.
Part B: RITA Beaconing Analysis (20 min)
# Install RITA if not present
# See: github.com/activecountermeasures/rita
# Import the beaconing corpus
rita import lab8-zeek/ lab8_hunt_dataset
# Show beaconing candidates
rita show-beacons lab8_hunt_dataset
# Show long connections
rita show-long-connections lab8_hunt_dataset
From the RITA output, identify the top beaconing candidate:
- Source IP
- Destination IP
- Beacon interval (seconds)
- Score (jitter %)
- Connection count
Is this the same source IP as the initial access event from Part A?
Part C: JA3 Analysis (15 min)
# Check JA3 fingerprints for the beaconing candidate
cat lab8-zeek/ssl.log | python3 -c "
import sys, json, collections
ja3_by_src = collections.defaultdict(set)
for line in sys.stdin:
try:
e = json.loads(line)
src = e.get('id.orig_h', '')
ja3 = e.get('ja3', '')
if src and ja3:
ja3_by_src[src].add(ja3)
except: pass
# Print unique JA3s per source
for src, ja3s in sorted(ja3_by_src.items()):
print(f'{src}: {len(ja3s)} unique JA3 fingerprints')
for j in ja3s:
print(f' {j}')
"
Look up the beaconing candidate's JA3 fingerprints at ja3.me or sslbl.abuse.ch/ja3-fingerprints/. Is any of them associated with known malware families?
Part D: Custom Suricata Signature (10 min)
Based on your timeline and JA3 analysis, write a Suricata signature that would have detected the C2 channel:
# Example structure -- customize with actual IOCs from your investigation
alert tls any any -> any any (
msg:"NET-301 LAB8 - C2 Beacon Detected";
ja3.hash; content:"<ja3-hash-from-analysis>";
flow:established, to_server;
threshold: type both, track by_src, count 10, seconds 3600;
classtype:trojan-activity;
sid:9000001;
rev:1;
)
Test the rule against the corpus:
sudo suricata -r ~/academy-corpus/c2-beacon.pcap \
-S lab8/custom.rules \
-l /tmp/lab8-suricata/ \
--af-packet=no
cat /tmp/lab8-suricata/fast.log | grep "NET-301 LAB8"
Lab Report
Create lab-8-report.md with:
- Three-event timeline: initial access + lateral movement + exfiltration (each: timestamp, src/dst IPs, protocol, Zeek log evidence)
- RITA beaconing candidate: source IP, destination IP, interval, jitter %, connection count
- JA3 analysis: which fingerprints were found, and is any associated with a known malware family?
- Custom Suricata rule (text)
- Evidence the rule fires against the corpus (fast.log output)
- One-paragraph forensics conclusion: "Based on the network evidence, the attacker's most likely initial access vector was [X] because [Y]. The C2 mechanism was [X] because [Y]. The exfiltrated data type was likely [X] based on [Y]."
Grading
| Component | Points |
|---|---|
| Timeline: 3 events with timestamps + Zeek evidence | 8 |
| RITA: beaconing candidate identified with all fields | 4 |
| JA3: fingerprints identified; malware association checked | 3 |
| Custom Suricata rule: syntactically valid + fires | 3 |
| Forensics conclusion paragraph: evidence-grounded | 2 |
| Total | 20 |