Category: Forensics
Level: Medium
File: click-here-for-free-bricks.zip
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.
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.pcapngOpen the capture file in Wireshark:
┌──(kali㉿kali)-[~/Desktop/uma/uma2]
└─$ wireshark thedamage.pcapngApply an HTTP display filter to narrow down the traffic:

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

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.jpegFive files were downloaded: three JPEG images (likely decoys), a Python script, and a binary.

Looking at the full picture in Wireshark, here is what happened in the capture:
10.0.0.10) downloaded several
files from 156.234.52.16 over plain HTTP:
fungame.jpg, cooldog.jpeg,
literallyme.jpeg — decoy imagesinstaller.py — the malware dropper
(Python script)launcher — an encrypted binary
payload76.54.32.144 appears — this is the C2 callback triggered by
installer.pyinstaller.pyReading the script reveals exactly what it does:
┌──(kali㉿kali)-[~/Desktop/uma/http output]
└─$ cat installer.pyimport 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:
Derives an AES key by SHA256-hashing a hardcoded seed string
Uses nacl.secret.SecretBox (NaCl symmetric
encryption) to decrypt the launcher binary
in-place
Executes a ping to 76.54.32.144 — the C2
(Command & Control) callback
installer.py and launcherSearching 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.
launcher BinaryWe 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: ba61a153eada267fcd3378aa20bb468e4be4e90a584c69669e52b1c4189f1758Alternatively, 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_decryptedThe decrypted launcher is a FreeBSD i386 executable — the actual malware payload.
SHA256 of decrypted launcher:
e7a09064fc40dd4e5dd2e14aa8dad89b328ef1b1fdb3288e4ef04b0bd497ccae
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