Seized is a Medium-rated HackTheBox Forensics challenge. You receive a raw disk image of a Windows workstation. The scenario is corporate data exfiltration. The challenge tests MFT analysis, file carving, and the ability to not get distracted by
deliberate decoys.
Image mounting and initial triage
# Check image structure mmls seized.img # DOS Partition Table # Slot Start End Length Description # 000: Meta 0000000000 0000000000 Primary Table (#0) # 001: ------- 0000000000 0000002047 Unallocated # 002: 000:000 0000002048 0125827071 NTFS (0x07) # Mount the NTFS partition sudo mkdir /mnt/seized sudo mount -o ro,loop,offset=$((512*2048)) seized.img /mnt/seized # Quick inventory of recently modified files find /mnt/seized/Users -newer /mnt/seized/Windows/System32/ntoskrnl.exe \ -not -path "*/AppData/Local/Temp/Low/*" \ -not -name "*.log" \ 2>/dev/null | sort
Browser history analysis
# Chrome history is a SQLite database
cp "/mnt/seized/Users/jsmith/AppData/Local/Google/Chrome/User Data/Default/History" /tmp/
sqlite3 /tmp/History "
SELECT datetime(last_visit_time/1000000-11644473600, 'unixepoch') as visit_time,
url, title
FROM urls
WHERE last_visit_time > 0
ORDER BY last_visit_time DESC
LIMIT 50;
"
# Relevant output:
# 2023-09-18 23:41:22 | https://www.dropbox.com/upload | Upload files - Dropbox
# 2023-09-18 23:38:15 | https://pastebin.com/api/api_post | Pastebin
# 2023-09-18 23:22:07 | https://file.io/ | file.io - Super simple file sharing
Windows event log analysis
# Extract and parse relevant events
python3 -c "
import subprocess, json
# Get network connection events around the time of interest
result = subprocess.run([
'python3', '-m', 'evtx',
'/mnt/seized/Windows/System32/winevt/Logs/Microsoft-Windows-Sysmon%4Operational.evtx',
'--json'
], capture_output=True, text=True)
for line in result.stdout.split(chr(10)):
if not line: continue
try:
evt = json.loads(line)
if evt.get(chr(69)+chr(118)+chr(101)+chr(110)+chr(116)+chr(73)+chr(68)) == 3:
# EventID 3 = Network connection
print(evt)
except: pass
"
# Shows outbound connections to 185.220.x.x on port 443 at 23:38
MFT analysis — finding deleted files
# Extract the MFT sudo cp /mnt/seized/\$MFT /tmp/mft_raw # Parse with MFTECmd (Wine or native Windows) # On Linux, use analyzeMFT: pip install analyzeMFT analyzeMFT.py -f /tmp/mft_raw -o /tmp/mft_parsed.csv # Search for .zip files created around the incident time grep "2023-09-18 23:[2-4]" /tmp/mft_parsed.csv | grep "\.zip" | grep -i "deleted\|$Recycle" # Output includes: # filename: staging_package_final.zip # created: 2023-09-18 23:35:41 # parent: C:\Users\jsmith\AppData\Local\Temp # status: deleted
File carving from unallocated space
# Use foremost to carve zip files from unallocated clusters sudo foremost -t zip -i seized.img -o /tmp/carved/ # Check recovered files ls -lh /tmp/carved/zip/ # 00000000.zip 2.3M # 00001234.zip 847K <-- this is the one # The smaller file is the exfil package unzip -l /tmp/carved/zip/00001234.zip # Archive: 00001234.zip # Length Date Time Name # --------- ---------- ----- ---- # 1048576 09-18-2023 23:35 Q3_financials.xlsx # 524288 09-18-2023 23:35 customer_database_export.csv # 128 09-18-2023 23:35 flag.txt
The decoy archives in the obvious staging directory were both created at the same timestamp — a tell that they were placed deliberately rather than created through normal activity. Real staged files have slightly different creation times as each
file is added.
Forensic timeline reconstruction
# Build a super-timeline using plaso/log2timeline log2timeline.py /tmp/seized_timeline.plaso seized.img # Filter to the incident window psort.py -o l2tcsv /tmp/seized_timeline.plaso \ "date > '2023-09-18 23:00:00' AND date /tmp/timeline_filtered.csv