This is a post about the Blog room on TryHackMe. It is a medium difficulty room. The target is a web server running a WordPress blog site.
Link to the room: https://tryhackme.com/room/blog
As mentioned in the room introduction we need to add blog.thm to the /etc/hosts file. After that we can start enumerating the machine.
From the result of the scan we can answer 2 questions: Billy is using WordPress CMS and the version of the CMS is 5.0.
There are 4 open ports. The server is running SSH, HTTP and SMB services. We can also see that there is a disallowed entry in robots.txt: /wp-admin/.
First I enumerated SMB shares with smbmap. There is a share named BillySMB with read and write permissions. I was able to access the share with smbclient without providing any credentials.
I found 3 files on the share and downloaded them with the get command. Once I had the files on my local machine I checked them looking for some useful information. First I did not find anything meaningful, then I found that the JPEG file has a text file hidden in it with steganography (no password was required).
narancs@kali:~/THM/blog$ steghide extract -sf Alice-White-Rabbit.jpg
wrote extracted data to "rabbit_hole.txt".
narancs@kali:~/THM/blog$ cat rabbit_hole.txt
You've found yourself in a rabbit hole, friend.
It was clearly a waste of time and I was on the wrong track.
A continued with enumerating the WordPress website.
While looking around on the website I was able to collect 2 possible usernames. There are 2 posts on the blog: 1 by Karen Wheeler and 1 by Billy Joel. If we hover over their name we can see their username in the URL: kwheel and bjoel.
If we visit /wp-admin/ that we found in robots.txt we will be redirected to the login page of WordPress. Since I had 2 usernames I tried to brute-force the password with hydra.
We need to provide the follow parameters:
- username or several usernames from file
- password or several passwords from file
- the target (DNS or IP address)
- the service to crack
- path of the login page
- the request data to be sent (
^PASS^will be the placeholders for the username and password values)
- message on the website after a successful/failed login, so hydra can identify the successful login attempts.
The path of the login page is
/wp-login.php. To get the request data to be sent I captured a login attempt via Burp Suite.
The information we will need to hydra:
^PASS^ placeholders in the command. Then I tried to login with one of the existing usernames, and received the following message after the failed attempt:
This can be used for the last parameter for the http-post-form service in hydra. If I tried to login with a non-existing username, then the error is different which would not be useful for us. Hydra would give false results.
First I used the original rockyou.txt that is stored in /usr/share/wordlists on Kali by default. However it contained empty line(s), which caused hydra to return incorrect results. So I created a copy of the file removing those empty lines.
grep -v '^$' /usr/share/wordlists/rockyou.txt > rockyou.txt
The final command:
hydra -l kwheel -P rockyou.txt blog.thm http-post-form "/wp-login.php:log=^USER^&pwd=^PASS^&wp-submit=Log+In&redirect_to=http%3A%2F%2Fblog.thm%2Fwp-admin%2F&testcookie=1:F=The password you entered for the username"
The brute-force worked properly, and I was able to get the password for the user kwheel.
Now I was able to login to WordPress. The user did not have full administrative rights, but it had access to create posts, upload files and moderate comments.
Exploiting WordPress to get a shell
I was looking for available exploits for this particular version of WordPress and I found some on Exploit DB. Then I tested a few of them, and what finally ended up working for me is the following: https://www.exploit-db.com/exploits/46662
I was able to get a shell on the target with this exploit. Then I spawned a proper bash shell with Python:
python3 -c 'import pty;pty.spawn("/bin/bash")'
There was only 1 user directory in /home for bjoel user. It contained a user.txt file, but the file did not include the user flag:
You won't find what you're looking for here.
I was not able to find the user flag with www-data user. Then I tried to escalate privileges to bjoel. I found the database credentials in /var/www/wordpress/wp-config.php, then I was able to get the password hash of bjoel WordPress user out of the database, but I could not crack it.
Since I did not find anything, I started to check for privilege escalation. I checked SUID binaries and there was an unfamiliar file in the output:
/usr/sbin/checker. I executed the file:
Not an Admin
The program checks something, and determines that I am not an administrator so it stops executing. In order to check the program logic and see why it is exiting with a message “Not an Admin”, I transferred the file to my local machine via Python HTTP server and opened it in Ghidra. This is the decompiled C code of the main function:
So the program reads the value of the environment variable “admin”. If the variable does not exist getenv returns a null pointer. If this is the case, the program will output “Not an Admin” and exit.
However, if the environment variable “admin” is set to any value, then the else clause will be executed. The program sets the user id to 0 (root) and spawns a bash shell.
With root access I used the find command to look for the user.txt file.
root@blog:/var/www/wordpress# find / -name user.txt 2> /dev/null
The user flag was in /media/usb/user.txt.
Since I already had root access it was easy to get the root flag. It was simply stored in /root/root.txt as usual.