Hack The Box - Admirer
Machine info
Operating System: Linux
Difficulty: Easy
Release date: May 12, 2020
IP Address: 10.10.10.187
# Summary
- Recon
- Port scanning
- Web enumeration: contacts info and credentials
- FTP: web source code backup with known credentials
- Web enumeration (after source code): Adminer application
- Machine Access
- Exploit LFI vulnerability in Adminer
- Log to the server via SSH
- Privilege Escalation
- Enumerate user privileges: user able to run certain scripts as root
- Exploit Python environment to get reverse shell as root
1. Recon
1.1. Port Scan
As usual, I started scanning the open ports in the box doing a fast scan with nmap:
nmap -p- -T5 --min-rate 5000 --open -v -n -Pn -oA nmap/fast-scan 10.10.10.187
It didn't show a lot of services but keeping in mind that this was an easy machine, I went directly to examine the web application after running the nmap custom scripts and version checks on those ports (which results didn't provide that much info either).
1.2. Web Enumeration
First of all, I checked the HTTP Headers with curl but there were no interesting headers, so I just fired up a proxy (just in case) and opened the web on my browser.
Taking a quick glance at the robots.txt file it shown a juicy directory that was worth investigating:
After doing some brute-force URL enumeration with gobuster using a common wordlist I found a couple of files that worth a look.
gobuster dir -u http://10.10.10.187/admin-dir -w /usr/share/seclists/Discovery/Web-Content/common.txt -s '200,301,302,307,403,500' -e
The credentials.txt file (the one I jumped directly into) contained some credentials for FTP, internal mail and Wordpress:
The contacts.txt file only contained some emails from presumably employees of the company behind the web page as well as their current(?) position:
As both files contained valuable information I decided to grab a quick copy of them with wget
before trying to test some of those credentials.
1.3. FTP Enumeration
Testing the gathered FTP credentials from the credentials.txt file (ftpuser
: %n?4Wz}R$tTF7
) I was able to access the FTP server.
There, I was able to retrieve a database dump and the compressed files of the web application.
Checking really quick the database dump file I found it only had information of the web application images / items.
1.4. Web Enumeration (2)
Browsing through the web application files, it had a directory called utility-scripts which contained some admin utilities that might worth poke a little bit.
However, after taking a look at the index.php, I realized that the file contained a syntax error (the database password contains double quotes, breaking its own string format):
As the web application was currently up and running, that indicated that the found files could be probably a backup of the web application.
Going back to the utility scripts, I decided to enumerate further on that directory. This took quite some time, but after using some big wordlists, I was able to find an interesting route. In the meantime, I grabbed a copy and tooked note of any useful information (i.e. the web application folder path).
wfuzz -c -w /usr/share/wordlists/dirb/big.txt --hc=403,404 -u "http://10.10.10.187/utility-scripts/FUZZ.php" -t 100
This new finding was an Adminer instance, a database management application written in a single PHP file.
My first guess here was to use the database credentials from the downloaded index.php to log into the app but that didn't work.
2. Machine Access
2.1 LFI vulnerability
Doing a little bit of research about the application and its version (shown in its login page), I found out that Adminer ver. 4.6.2 presents a Local File Inclusion vulnerability.
This specific version of Adminer allows an attacker to connect to a database on its own machine from the Adminer application. However, as Adminer is running on the victim machine, it is possible to load the content of a file from the victim system instead from the machine where the application is connected to.
This vulnerability and its exploit are further explained in this article by Foregenix as well on this Medium post by @YShahinzadeh.
2.2 Setup local machine
Checking the port where MariaDB was running, I could see that the port was binded only to localhost. Therefore it would reject any connection from the outside.
In order to fix that, it is only necessary to replace the bind-adress of the server in its configuration file from 127.0.0.1 to 0.0.0.0.
sudo lsof -i:3306
sudo vim /etc/mysql/mariadb.conf.d/50-server.cnf
sudo systemctl restart mysql
sudo lsof -i:3306
After restarting the server and checking again, it was ready to accept connections from other machines:
Then I created a random password and logged into my MariaDB server in order to create a user and database to connect to, assigning the proper permissions:
CREATE DATABASE admirertest;
CREATE USER 'kali'@'%' IDENTIFIED BY "thiethae9xiP6ahthieg";
GRANT ALL PRIVILEGES ON *.* TO 'kali'@'%';
FLUSH PRIVILEGES;
Once the database was created, everything was set to exploit the vulnerability.
2.3 Exploit LFI
Using the newly created database credentials I was able to connect to my test database from the Adminer application.
Knowing that the index.php file from the backup had the database credentials, I decided to load that file by taking advantage of the LFI vulnerability. (This is the moment where the info gathered previously from phpinfo comes in handy).
In order to exploit the vulnerability, first I had to create a database table with a text column that I named test. Then, by sending the following SQL commands, each row of the indicated file was loaded in that table:
LOAD DATA LOCAL INFILE '/var/www/html/index.php'
INTO TABLE test
FIELDS TERMINATED BY "\n"
After submitting the code, each row of the indicated file was loaded as a row of the created table. This shown the current database credentials that the web application was using:
Testing the found username (waldo) and password (&<h5b~yK3F#{PaPB&dA}{H>) on SSH I was able to log into the server as waldo!
3. Privilege Escalation
3.1. Enumerate user privileges
Once I was in the target machine as waldo, while doing the usual enumeration tasks (OS version, permissions, etc.) it seemed waldo could run an admin script passing its own environment to it:
Interesting enough, checking the cronjobs configuration, there was a cronjob configured to delete any Python related files on the home folder.
The Bash admin script (/opt/scripts/admin_tasks.sh
) had an option to make a backup of the web directory. In this case, this action was performed invoking an external Python script, instead of performing the backup from the Bash script.
This backup script (/opt/scripts/backup.py
) was a very simple Python script as it is shown in the following image. It imports the shutil
library in order to use its make_archive
function to do the backup of the folder:
Knowing that the current sudo configuration for waldo uses the user environment, it seemed feasible to modify the Python environment with a new one replacing the location where the shutil library was going to get loaded for a malicious one.
3.2. Exploit Python path
In order to perform the exploit, first of all I created a shutil.py file with the function make_archive in it.
I decided to try first with a ping call to my machine as I was getting some trouble getting the PYTHONPATH
environment passed to the root process. I found out that the sudo option -E does not work with PATH nor PYTHONPATH and, if required, those environment variables have to be explicitly passed when calling the command (stackoverflow).
After passing the PYTHONPATH variable as indicated in the following picture, I started getting the output from the ping command.
sudo PYTHONPATH=/home/waldo/scripts /opt/scripts/admin_tasks.sh 6
Finally, I modified the make_archive
function with a reverse shell. As a side note, it is important to remember that the machine had a cronjob configured to remove any Python files in the home folder, therefore I crafted and modified the malicious Python script on my local machine, copying it to the target and executing the admin script before the next cleanup.
Firing again the admin script with sudo, while having a netcat listener on the attacker machine, I got a reverse shell as root!