Tenet is a medium rated machine on HackTheBox created by egotisticalSW. For the user part we will find a backup php script and abuse the php unserialze function to reach RCE on the webserver resulting in a reverse shell. Next we find database credentials, with wich we can switch to the user Neil. Finally we will exploit a race condition in a bash script we are able to run as root to write our public ssh key to root’s authorized ssh keys.
User
Nmap
We start our enumeration off with a full port nmap scan, followed by a script and version scan to get a full picture of the attack surface.
Ininital scan all ports
1 |
|
Version and script scan
1 |
|
Backup file
The webpage just shows the default apache page, however gobuster reveals a wordpress installation.
1 |
|
The wordpress installation works with absolute url’s, so we have to add the hostname tenet.htb
to our hosts file.
On the migration blogpost there is a comment mentioning a sator.php file and a possible backup.
Navigating to http://[machine-ip]/sator.php.bak
let’s us retrive the backup of the file
sator.php.bak
1 |
|
Insecure Deserialization
The retrieved code takes user input and passes it to the unserialize function. We want to abuse this with creating our own serialized DatabaseExport instance.
The DatabaseExport class creates a new file with the content of it’s data
attribute on destruction. Controlling both the filename and the data, we can simply write a small webshell to the server with the following code.
1 |
|
1 |
|
We send the serialized object urlencoded to the endpoint with burp repeater and get RCE in the next request.
First we set up out listener to catch the reverse shell.
1 |
|
Then with the next request, we get a bash reverse shell in burp from our webshell, recieve a connection back and upgrade our shell.
1 |
|
Database Credentials
On the machine there are database credentials in the file /var/www/html/wordpress/wp-config.php
which are also reused as the users account credentials, so we can pick up our first flag.
1 |
|
1 |
|
Root
Race condition
We immediatly see that Neil may run a custom bash script as root.
1 |
|
Investigating this script there is a race condition in the mktmp
function. It first creates a temporary file with half of the name being predictable and set’s the umask in a second statement. Generating enough traffic to get our function executed between the tmpName
and the umask
call. We can write our own ssh public key to root’s authorized keys
enableSSH.sh
1 |
|
We do this by running an endless loop twice to have higher chances on winning the race.
1 |
|
While the loops are running we execute the script as root, note here that because of the nature of the race condition you might have to repeat this request. To increase the chance you could e.g. run more of the above loops.
It is furthermore no indication that the script failed if it prints Successfully added root@ubuntu to authorized_keys file!
, because it uses the predefined key to echo to stdout.
1 |
|
Now we can log into the machine with our private key as the root user and grab the root flag.
1 |
|