2024 Cyber Apocalypse: Phreaky

Challenge Information

AttributeDetails
Event2024 Cyber Apocalypse
CategoryForensics
ChallengePhreaky
DifficultyEasy

Summary

Phreaky is a forensics challenge involving packet capture analysis. A mole within an organization is exfiltrating sensitive data via SMTP email. The challenge requires analyzing the PCAP file, identifying the SMTP traffic, extracting base64-encoded attachments, decoding them, reassembling the pieces, and recovering the original document.


Analysis

Data Exfiltration Method

The attacker:

  1. Uses SMTP to send emails from inside the organization
  2. Embeds large base64-encoded files as email bodies
  3. Splits a PDF across 15 separate emails (phreaks_plan.pdf.part1 through .part15)
  4. Includes password in email subject line for zip files

Artifact Locations

  • SMTP Traffic: Starts around packet 2750 in the PCAP
  • Sender: caleb@thephreaks.com
  • Recipient: resources@thetalents.com
  • File Size: ~1514 bytes per email (including base64)
  • Format: ZIP-compressed PDF parts with password protection

Solution

Step 1: Open PCAP in Wireshark

Terminal window
wireshark phreaky.pcap

Apply filter to find SMTP traffic:

tcp.port == 25 or tcp.port == 587 or tcp.port == 465

Step 2: Follow TCP Streams

For each email (15 total):

  1. Find SMTP DATA section
  2. Right-click → Follow → TCP Stream
  3. Locate base64-encoded body
  4. Copy password from email subject line

Step 3: Extract and Decode Base64

For each part (pt1.b64 through pt15.b64):

#!/bin/bash
# Extract base64 from each email's TCP stream
for i in {1..15}; do
# (Copy base64 from Wireshark and save to pt$i.b64)
base64 -d pt$i.b64 > pt$i.zip
done

Step 4: Extract ZIP Files

#!/bin/bash
PASSWORD="password_from_subject" # Extract from email
for i in {1..15}; do
unzip -P "$PASSWORD" pt$i.zip -d part$i/
done

Each ZIP extracts to phreaks_plan.pdf.part$i

Step 5: Assemble PDF Parts

Create a Python script to concatenate parts:

#!/usr/bin/env python3
# Generate list of parts
for i in range(1, 16):
print(f"phreaks_plan.pdf.part{i}")

Save to files.txt, then create bash script:

#!/bin/bash
if [ ! -f files.txt ]; then
echo "Error: files.txt not found."
exit 1
fi
if [ ! -f phreaks_plan.pdf ]; then
touch phreaks_plan.pdf
fi
while IFS= read -r filename; do
if [ -f "$filename" ]; then
cat "$filename" >> phreaks_plan.pdf
echo "Content of $filename appended to phreaks_plan.pdf"
else
echo "Error: $filename not found."
fi
done < files.txt
echo "All files processed."
chmod +x this_script.sh
./this_script.sh

Step 6: Verify and Extract Flag

Terminal window
# Verify PDF validity
file phreaks_plan.pdf
# Open PDF
evince phreaks_plan.pdf
# Or extract text
pdftotext phreaks_plan.pdf
grep -i HTB phreaks_plan.txt

Complete Automated Script

#!/usr/bin/env python3
import subprocess
import base64
import os
import sys
import re
import zipfile
def extract_from_pcap(pcap_file):
"""Extract emails from PCAP using tshark"""
# Extract SMTP sessions
cmd = f'tshark -r {pcap_file} -Y "smtp" -T fields -e ip.src -e smtp.req -e data'
result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
emails = []
for line in result.stdout.split('\n'):
if 'From:' in line or 'To:' in line:
emails.append(line)
return emails
def extract_base64_from_pcap(pcap_file):
"""Extract base64 data from PCAP TCP streams"""
# Use Wireshark/tshark to export objects
cmd = f'tshark -r {pcap_file} -Y "smtp" --export-objects "SMTP,./exports"'
subprocess.run(cmd, shell=True)
# Find base64 files in exports
base64_data = []
for root, dirs, files in os.walk('./exports'):
for file in files:
with open(os.path.join(root, file), 'r') as f:
content = f.read()
# Look for base64-encoded data
if re.search(r'^[A-Za-z0-9+/=\n]+$', content.strip()):
base64_data.append(content)
return base64_data
def process_parts(base64_data_list, password):
"""Decode and extract parts from base64 ZIP files"""
parts = []
for idx, b64_data in enumerate(base64_data_list, 1):
# Decode base64
zip_data = base64.b64decode(b64_data)
# Write temporary ZIP
zip_path = f'/tmp/pt{idx}.zip'
with open(zip_path, 'wb') as f:
f.write(zip_data)
# Extract ZIP with password
try:
with zipfile.ZipFile(zip_path) as zf:
zf.extractall(path=f'/tmp/part{idx}', pwd=password.encode())
parts.append(f'/tmp/part{idx}/phreaks_plan.pdf.part{idx}')
except Exception as e:
print(f"[-] Failed to extract part {idx}: {e}")
return parts
def assemble_pdf(parts, output='phreaks_plan.pdf'):
"""Assemble PDF parts into complete file"""
with open(output, 'wb') as pdf:
for part_file in sorted(parts):
with open(part_file, 'rb') as f:
pdf.write(f.read())
print(f"[+] PDF assembled: {output}")
return output
def main():
pcap_file = sys.argv[1] if len(sys.argv) > 1 else 'phreaky.pcap'
password = sys.argv[2] if len(sys.argv) > 2 else 'unknown'
print("[*] Extracting data from PCAP...")
base64_data = extract_base64_from_pcap(pcap_file)
print(f"[+] Found {len(base64_data)} base64 sections")
print("[*] Decoding and extracting ZIP files...")
parts = process_parts(base64_data, password)
print("[*] Assembling PDF...")
pdf_file = assemble_pdf(parts)
print("[+] Complete! Opening PDF...")
subprocess.run(['xdg-open', pdf_file])
if __name__ == '__main__':
main()

Key Forensics Techniques

  • PCAP Analysis: Understanding network protocols in packet captures
  • SMTP Protocol: Email structure and MIME encoding
  • Base64 Decoding: Recovering binary data from text encoding
  • ZIP Extraction: Handling encrypted archives with passwords
  • File Reconstruction: Reassembling fragmented data
  • Metadata Analysis: Extracting information from email headers

Key Takeaways

  • PCAP analysis reveals data exfiltration methods
  • SMTP traffic often contains sensitive data in plaintext
  • Base64 encoding is for transport, not security
  • Large files can be split and reassembled
  • Email passwords in subjects indicates weak security practices
  • Following TCP streams simplifies analysis of complex protocols
  • Automated scripts help handle large-scale forensic analysis

Flag: HTB{3x f1ltr4t10n_1s_n0t_w0rk1ng}