Admirer — Write-up — HackTheBox

0xczar
8 min readJan 15, 2021

Admirer Box is a retired Easy-rated Linux Machine, who deals with exploiting a web database interface, which in fact doesn’t require any creds. For the PrivEsc we used the fact that a non-privilege user can change the path of PYTHONPATH in order to allow us to hijack Python Library.

Recon

nmap -p- -v -sV -sC -oA admirer.htb -Pn -oA nmap_scan
PORT STATE SERVICE VERSION
21/tcp open ftp vsftpd 3.0.3
22/tcp open ssh OpenSSH 7.4p1 Debian 10+deb9u7 (protocol 2.0)
| ssh-hostkey:
| 2048 4a:71:e9:21:63:69:9d:cb:dd:84:02:1a:23:97:e1:b9 (RSA)
| 256 c5:95:b6:21:4d:46:a4:25:55:7a:87:3e:19:a8:e7:02 (ECDSA)
|_ 256 d0:2d:dd:d0:5c:42:f8:7b:31:5a:be:57:c4:a9:a7:56 (ED25519)
80/tcp open http Apache httpd 2.4.25 ((Debian))
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
| http-robots.txt: 1 disallowed entry
|_/admin-dir
|_http-server-header: Apache/2.4.25 (Debian)
|_http-title: Admirer
Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel

Three Ports -

80/tcp open http Apache httpd 2.4.25
22/tcp open ssh OpenSSH 7.4p1
21/tcp open ftp vsftpd 3.0.3

Port 21

When I see a ftp port open, It is always worth checking whether it allows anonymous login — This was not the case. In addition we could also run NSE
to see whether this version has any backdoor.

nmap — script ftp-vsftpd-backdoor -p 21 admirer.htb
Starting Nmap 7.91 ( https://nmap.org ) at 2021–01–15 17:27 GMT
Nmap scan report for admirer.htb (10.10.10.187)
Host is up (1.9s latency).

PORT STATE SERVICE
21/tcp open ftp

Port 80

Seems like some kind of a gallery, each image have a title and a subtitle, nothing unusual there. Before running our main enumeration I thought it might be worth wget all image files and see whether this is more of a CTF type box working with Stenography.
wget -nd -r -P /czar/HTB/admirer/images/ -A jpeg,jpg,bmp,gif,png http://admirer.htb

after downloading all jpg files, let’s check for hidden crypt messages etc. For this part I’ve used stegoveritas which you can find here if you are interested (unlike zsteg, stegoveritas works on jpg files as well).
for i in $(ls); do stegoveritas $i >> output.txt ; done
To make a story short — It seems there’s nothing special we can grab from the files. Moving on.

Gobuster 1st run

Nothing Unusual except for the robots.txt and other generic directories.

Robots + /admin-dir

/admin-dir Sounds like could definitely be worth checking, It also says it contains creds and contacts.

No surprise here. Moving on to Enumeration.

Enumeration

I’ve made a list with all various words for credentials and contacts.
creds
cred
credentials
credential
usernames
username
users
password
pass
hashes
files
contact
contacts
and send it via gobuster -

http://admirer.htb/admin-dir/contacts.txt

http://admirer.htb/admin-dir/credentials.txt

OK, this is much better. We’ve got several users and passwords possible combinations. At this point I thought about using wpscan but I kept it as the last option. Let’s check ftp first.

We see 2 files — a sql dump file and tar.gz file. download them both using mget locally.
tar -xf html.tar.gz
It holds 3 main files — 1 php file and two directories.
index.php, w4ld0s_s3cr3t_d1r/ and utility-scripts/
in the first library — w4ld0s_s3cr3t_d1r we see two files that we encounter before contacts.txt and credentials.txt.
It seems that in credentials.txt we’ve got another missing credentials which we didn’t see on http://admirer.htb/admin-dir/credentials.txt.
[Bank Account]
waldo.11
Ezy]m27}OREc$
OK, Next — index.php ,It is very similar to the main source page HTML but there’s also connection information related to the database:

Writing down these credentials, let’s check utility-scripts/ folder.

info.php is a PHP Info page. admin_tasks.php seems like a script that runs commands , phptest.php basically echo(“Just a test to see if PHP works.”); and db_admin.php contains more credentials, this is also relevant for databases.

Note —At this stage, all the credentials we discovered are not working via SSH.

Adminer

I must admit that I’ve wasted a lot of time trying to figure out what is still missing. By the name of the machine, I thought It should be related to Adminer which is a popular PHP tool to administer MySQL and PostgreSQL databases interface but wasn’t sure at first. But after a lot of enumeration, again, I’v discovered — http://admirer.htb/utility-scripts/adminer.php

At this stage I though all these credentials will finally prove them self, but, as you probably guessed it — They’re not.
A quick search on the Adminer Version (4.6.2) bring me to https://sansec.io/research/adminer-4.6.2-file-disclosure-vulnerability -

Attackers can abuse that to fetch passwords for popular apps such as Magento and Wordpress, and gain control of a site’s database. Exploitation happens in three stages. First, the attacker needs a modified MySQL server, which is altered to send out data import requests to any client that connects

In order for us to try and manipulate Adminer.htb Adminer server to fetch files locally on our machine, we will set the following -
I designed an attack scenario:

  • Setting up local mariaDB/mysql server.
  • Connect via the Adminer Interface to our own local machine.
  • Reading local files by read data local infile command, inserting the results in our own created table.

Unfortunately this all set up burned me an hour or so since I was getting the famous ERROR 2002 (HY000): Can’t connect to local MySQL server through socket ‘/var/run/mysqld/mysqld.sock’ (2). I mange to solve it by purging (=/)
all of my mariadb files and starting over.
From there I -
sudo service mysql start
grep -r 127.0.0.1 /etc/mysql/
>>change bind to 0.0.0.0 >> service mysql restart
Now that mysql is running, let see if we are indeed listening to 3306 -
netstat -antp | grep 3306

OK great, let’s set up our own database and table in order for us to “export” the relevant info from admirer.htb server .
These are the steps -

Now that our DB is ready, let’s try and connect via the creds we just set.

In the above screenshot you can see the various DBs I’ve created during these trials and errors. We select SQL Command and use the read data local infile.

At first I tried to export something like /etc/passwd but encountered an error.
So I tried grabbing /var/www/html/index.php

It seems the original index.php was holding a different password than the one we saw earlier, we got — ‘ ’&<h5b~yK3F#{PaPB&dA}{H>

SSH as waldo

After the last step, we can try and SSH via the password we just received
and grab the user.txt.

Privilege Escalation

sudo -l will relieve the next thing -

It seems waldo has the sudo privilege to run the SETENV command. But wait, what exactly does this command mean ? this page -
https://www.computerhope.com/unix/usetenv.htm
explains it excellent -

If setenv is given no arguments, it displays all environment variables and their values. If only VAR is specified, it sets an environment variable of that name to an empty (null) value. If both VAR and VALUE are specified, it sets the variable named VAR to the value VALUE. setenv is similar to the set command, which also sets an environment variable’s value. However, unlike set, setenv also “exports” this environment variable to any subshells. In this way, it is the equivalent of the bash command export.

So we understand that waldo can change the ENV of any executable. First let’s check what holds the mentioned bash script -
after we overview the script we quickly understand it is the script that handles the admin_task.php we saw earlier. This is the GUI for this script -

Under the Select task, we’ve got 7 task, where 3 tasks can be executed by a non-privileged user (such as waldo), while the remaining 4 task could be executed by a privileged user, and that is exactly what this script is checking.

Among the various tasks, there’s one interesting task, running a backup process (backup.py) in the background — we soon check it ourself. Since the file itself is a python script inside the same directory as our main script (admin_tasks.sh), let’s see what it does -

Basically the idea here is to use the SETENV privilege we got, and manipulate the script in a way that it will triggered a custom command, that we will “plant” inside that specific module (shutil.make_archive). This page explained it best — https://medium.com/analytics-vidhya/python-library-hijacking-on-linux-with-examples-a31e6a9860c8 (the 2nd and 3rd examples).

Now I’ve read a lot of these writeups after finishing the machine and a lot of them deal with complex code that needs to be added to the module itself
using os.system method.
THE following screenshot will explain it best -

Explanation —
1. which python3 to check python location and version path.
2. When importing a module within a script, Python will search that module file through some predefined directories in a specific order of priority, and it will pick the first occurrence .We can find that order using the 2nd command.
(you can see that the first line is empty).
3. The find command will output the location of our shutil module that is being used in the backup.sh script.
4. I’ve scp module itself to my local machine and edit it -

I’ve added 773 and 774 lines.

Explanation -

  1. scp the shutil.py back to /tmp/ (the system clears all new files in /tmp/ every few minutes).
  2. sudo PYTHONPATH=/tmp/ /opt/scripts/admin_tasks.sh
    I’ve changed the PYTHONPATH to /tmp/ so python can grab the first location of the “upgraded” (; shutil.py.
  3. Started nc -nvlp 1337, got connection, spawn a shell and got root.txt.

Thank you.

--

--