Back to list
CTFEasy

TryHackMe RootMe Walkthrough: Recon to Root (Beginner Step-by-Step Guide)

ducky
2026-05-21
12 views
5 min read

TryHackMe RootMe Walkthrough: Recon to Root (Beginner Step-by-Step Guide)

RootMe is an Easy, beginner-friendly TryHackMe room that walks you through a complete mini-pentest: enumerate the target, bypass a file-upload filter to get a shell, then escalate to root by abusing a misconfigured SUID binary. It teaches two essential offensive skills — bypassing file-upload restrictions to gain an initial shell, and local privilege escalation by abusing a SUID interpreter.

This guide explains every command and tool so you can follow along even if it's your first room.

Flags are left blank (THM{...}) on purpose — run the steps and capture them yourself. Replace <IP> with your target's IP, and <YOUR_IP> with your TryHackMe VPN IP (tun0).

Tools you'll use: rustscan, nmap, gobuster, a PHP reverse shell, netcat, and GTFOBins.


Task 1 — Deploy the Machine

Start the machine on the room page and wait ~1 minute for it to boot. Connect through the TryHackMe VPN (or use the AttackBox). Grab the target IP shown on the page.


Task 2 — Reconnaissance

Always start by finding out what's running. A handy two-step workflow is to scan ports fast with Rustscan, then hand those open ports to nmap for the slower, detailed enumeration.

Step 1 — Fast port scan with Rustscan

Rustscan races through all 65,535 ports in seconds, then automatically pipes whatever it finds straight into nmap:

  • -a <IP> → the target address
  • everything after -- is passed through to nmap (so -sC -sV runs on just the open ports)

Step 2 — Detailed scan with nmap

If you prefer to run nmap separately (or Rustscan isn't installed), point nmap at the ports Rustscan reported:

  • -sV → identifies service versions
  • -sC → runs nmap's default enumeration scripts
  • -p → only scan the ports we already know are open (much faster)

What you'll find: two open ports — SSH on port 22 and an Apache web server on port 80.

Answers for this task:

  • How many ports are open?2
  • What version of Apache is running?2.4.29
  • What service is running on port 22?ssh

Now find hidden web directories with Gobuster (it brute-forces folder names from a wordlist):

This reveals a few directories. The one of interest is /panel/, which is the hidden directory the room asks for. You'll also see an /uploads/ folder — remember that, it's where uploaded files land.

  • What is the hidden directory?/panel/

Task 3 — Getting a Shell

Visit http://<IP>/panel/ in your browser. It's a page that lets you upload a file. File uploads are a classic weak point, so let's try uploading a PHP reverse shell.

1. Prepare the reverse shell

Use the well-known pentestmonkey PHP reverse shell. On Kali it ships at /usr/share/webshells/php/php-reverse-shell.php, or you can grab it from GitHub: https://github.com/pentestmonkey/php-reverse-shell (the file is php-reverse-shell.php). Open it and edit two lines:

2. Bypass the upload filter

If you try to upload .php, the server rejects it. The fix is to use an alternative extension that the server still hands to the PHP interpreter. For RootMe, renaming the file to .phtml works (.php5 does too).

It's worth knowing the common PHP extensions to try when an upload filter only blocks plain .php — keep a list like this handy:

For this room, rename your shell to .phtml:

Upload shell.phtml through the /panel/ form.

3. Catch the shell

Start a Netcat listener on your machine for the port you set:

  • -l listen, -v verbose, -n no DNS, -p port

Then trigger the shell by browsing to your uploaded file in /uploads/:

Your listener catches a shell as the www-data user. Stabilise it so it behaves like a normal terminal:

4. Find the user flag

The user flag lives under /var/www.


Task 4 — Privilege Escalation

Now go from www-data to root. Look for binaries with the SUID bit set — these run with the file owner's privileges (often root), which can be abused if the binary is one that shouldn't have it.

  • -perm -u=s → files with the SUID bit
  • 2>/dev/null → hide permission-denied noise

What stands out: /usr/bin/python has the SUID bit set, which is unusual.

  • Which SUID file is weird?/usr/bin/python

Check GTFOBins (a reference of binaries that can be abused for privilege escalation). For Python, the trick is to set the UID to 0 and spawn a shell.

Confirm you're root and grab the final flag:

🎉 Box rooted!


Summary: The Attack Path

StageTool / TechniqueResult
ReconnmapFound SSH (22) + Apache (80)
EnumerationgobusterFound /panel/ upload form
Initial access.phtml upload bypass + reverse shellShell as www-data
Privilege escalationSUID python via GTFOBinsRoot

What You Learned (and How to Defend It)

Both of RootMe's vulnerabilities come down to misconfiguration: weak file-upload validation, and a Python binary that shouldn't have the SUID bit set. The defensive lessons:

  • Validate uploads properly — check real content types, use an allow-list of safe extensions, and store uploads outside the web root so they can't be executed.
  • Never set the SUID bit on interpreters like python, bash, or perl — GTFOBins shows exactly why they become instant root.
  • Audit SUID binaries regularly with the same find command an attacker would use.

Handy Reference Commands


For educational use only. TryHackMe is a legal, sandboxed lab. Never use these techniques against systems you don't own or aren't explicitly authorised to test.

Tags

#TryHackMe#RootMe#TryHackMe RootMe#RootMe Walkthrough#RootMe Writeup#CTF#Cybersecurity#Penetration Testing#Web Exploitation#File Upload Bypass#Reverse Shell#Privilege Escalation#SUID#GTFOBins#nmap#Rustscan#Gobuster#Netcat#Linux#Ethical Hacking#InfoSec for Beginners

Keep Reading

Related writeups