HackTheBox TENET
Tenet is a Medium difficulty machine that features an Apache web server with Wordpress.
TL;DR
This machine had an easy initial enumeration. Only ports 22 and 80 were open and the web app was a Wordpress, which was discovered through folder bruteforcing with gobuster and the wordlist big.txt. After that, navigating the site was enough to see the next step: one user left a comment with sensitive information, which led to the discovery of a backup file. This file used a dangerous function (unserialize) to execute code from user input without sanitizing it. From that it was possible to write a PHP file on the server to achieve Remote Code Execution (RCE). With www-data permissions, it wasn’t possible to get the user flag, but it was possible to get root without needing to perform lateral movement. This was done by analysing a shell script that writes a public key to the root’s authorized_keys file. The vulnerable point was the fact that this script was run by www-data with sudo (root) permissions, but it creates a temporary file to write the public key and this file had unsafe permissions that allowed the writing of an additional public key inside it. Then the keys were all written to the authorized_keys file of the user root.
Lessons Learned
- Stop to think about every new piece of information;
- Read the documentation on things you don’t know;
RECON
NMAP SCAN
SERVICE RECON
Apache port 80
Directory bruteforcing
The root of the webserver using the wordlist big.txt led to the discovery of a folder called wordpress.
EXPLOITATION
INITIAL ACCESS
Navigating to the Migration post on the blog, it’s possible to see a comment that leaks sensitive information:
This backup file was stored on the root of the webserver:
The original file is stored on the same place:
After getting the backup file from the web server, analyzing it revealed a vulnerable use of the function unserialize:
The exploitation process includes abusing the unsafe use of the function unserialize in order to activate the class method destructor, which writes data to a file.
The exploit crafts a similar class that fills the variables $user_file
and $data
with malicious content:
The above is the execution of the exploit file, which creates a serialized PHP object that contains the malicious data:
This payload is then sent to the webserver via arepo GET parameter using the original sator.php file:
Notice that the HTTP response body includes two entries of [] Database updated, which means that the method destructor was called twice: one on the object $app
, on the original code, and the other on the malicious object $databaseupdate
:
Now we should have a file called rev.php on the webserver:
LATERAL MOVEMENT (USER ACCESS)
It was not possible to get the user flag with www-data permissions, but there was no need for lateral movement. Root access could be achieved directly from www-data.
PRIVILEGE ESCALATION (ADMIN/ROOT ACCESS)
After some basic initial enumeration commands, it was discovered that the user www-data has sudo access and that it can execute the script /usr/local/bin/enableSSH.sh
with root permissions:
After analyzing the script, it was possible to see that it writes a public key string on the file /root/.ssh/authorized_keys
:
The function addKey() is the one responsible for creating a temporary file, writing the key in it and then writing the contents of this temporary file into /root/.ssh/authorized_keys
.
The vulnerable point is the mask used for the creation of the temporary file:
The file is created with writing permissions for every user. Because of this, it’s possible to write another public key into the file, so both keys are written into /root/.ssh/authorized_keys
. For this to happen, a while loop was written to monitor the creation of a temporary file. When it is created, the malicious public key is written:
When the script enableSSH.sh is executed, the malicious public key is written into the temporary file and also in the root’s authorized_keys file:
TOOLS USED
- nmap
- burp suite
- gobuster
CUSTOM STUFF (scripts, commands, exploits, etc)
- Wait for file creation and write on it:
while :; do file=$(ls /tmp/ssh-*) && echo 'text to be written' >> $file; done