Love
Un SSRF en un escáner de ficheros llega a un panel interno en el puerto 5000 que filtra las credenciales de admin del Voting System; desde su panel, una subida de ficheros sin validar da RCE, y un AlwaysInstallElevated a 0x1 remata con SYSTEM vía MSI.
Love
| Máquina | SO | Dificultad | IP |
|---|---|---|---|
| Love | Windows | Easy | 10.129.48.103 |
A tener en cuenta...
Resumen
Love es una máquina de puro camino web, de esas que hacen pensar. No hay un CVE que lances y ya: hay que encadenar varias piezas, y cada una te obliga a entender cómo funciona la anterior.
Todo arranca en un escáner de ficheros en un subdominio de staging que, en vez de analizar archivos locales, se descarga una URL que tú le das. Eso es un SSRF de manual, y apuntándolo contra la propia máquina aparece un panel interno en el puerto 5000 que, sin pudor alguno, muestra las credenciales de administrador del Voting System que corre en el 80.
Con esas credenciales, el panel permite subir una foto de votante… que en realidad es un .php, porque no valida nada. De ahí sale la ejecución de código y, con un nc.exe, una shell como phoebe. El último empujón es un clásico de Windows mal configurado: AlwaysInstallElevated, que deja instalar un .msi como SYSTEM.
Una caja divertidísima y muy completa para quien prepara el eWPT: enumeración, SSRF, bypass de protecciones de login, file upload y escalada por registro, todo en una.
Vulnerabilidad
Tres fallos encadenados, cada uno aprovechando lo que el anterior deja al descubierto.
01 · SSRF en el «Free File Scanner» de staging
El subdominio staging.love.htb ofrece un escáner que recibe la URL de un fichero y lo descarga desde el servidor para analizarlo. Como no restringe el destino, se le puede pedir que acceda a http://127.0.0.1 y a sus puertos internos. Es un Server-Side Request Forgery: el servidor hace la petición por ti, saltándose el filtrado de red. Apuntándolo al puerto 5000 — que desde fuera devuelve 403 Forbidden — se accede a un panel interno que filtra las credenciales de administrador.
02 · Subida de ficheros sin validar en el Voting System (RCE)
El Voting System de SourceCodeSter que corre en el puerto 80 permite, desde su panel, crear un votante con una foto. No comprueba ni la extensión ni el tipo del fichero, así que en lugar de una imagen se sube un .php. El fichero queda accesible en /images/ y, al pedirlo, el servidor lo ejecuta: ejecución remota de código como love\phoebe.
03 · AlwaysInstallElevated — escalada a SYSTEM
La clave de registro AlwaysInstallElevated está puesta a 0x1. Esa política hace que cualquier paquete .msi se instale con privilegios de SYSTEM, sin importar quién lo lance. Generando un instalador malicioso con msfvenom y ejecutándolo con msiexec, la escalada es inmediata.
Reconocimiento
Caja negra: barrido completo de puertos contra la víctima, pidiendo de paso que adivine el sistema operativo
| Puerto | Servicio |
| 80 | http |
| 135 | msrpc |
| 139 | netbios-ssn |
| 443 | https |
| 445 | microsoft-ds |
| 3306 | mysql |
| 5000 | http |
Bastantes puertos abiertos para un Windows: web en el 80, SMB/RPC (135, 139, 445), un 443 con HTTPS, 3306 de MariaDB y un curioso 5000 que también habla HTTP. El SO lo sitúa en un Windows 10.

Enumeración
Afino versión y lanzo los scripts por defecto sobre los puertos interesantes


Dos cosas saltan a la vista. Primera, el stack es un XAMPP viejo: Apache 2.4.46 con PHP 7.3.27, todo desactualizado. Segunda, y más jugosa, el certificado TLS del puerto 443 delata un subdominio: commonName=staging.love.htb

Añado love.htb y staging.love.htb al /etc/hosts y empiezo por la web del 80. whatweb confirma el Voting System using PHP sobre Bootstrap y jQuery

La portada es un panel de login del Voting System; Wappalyzer añade DataTables, iCheck y la versión de Bootstrap

Un dirsearch descubre el panel /admin/, un /images/ con listing y los habituales de un proyecto PHP

y un nikto corrobora el directory indexing en /images/ y /icons/

Ahora toca repetir el mismo trabajo sobre el subdominio. staging.love.htb es un Free File Scanner de ValentineCorp, con una pestaña Demo que promete escanear ficheros

whatweb sobre el subdominio




Nada clamoroso en los fuzzings, pero esa pestaña Demo del escáner huele raro. Es por ahí por donde hay que tirar.
Explotación
Antes de meterme con el escáner, reviso el login del Voting System. Resulta que enumera usuarios: con uno que no existe responde «Cannot find account with the username»…

…pero con admin cambia a «Incorrect password», confirmando que esa cuenta existe

La tentación es una fuerza bruta, pero el login esconde una trampa. Al fallar, /admin/login.php no devuelve un mensaje en la misma página: hace un 302 que redirige a index.php

Lo confirmo con curl: con credenciales falsas, la cabecera Location apunta a index.php

Esto es importante porque hydra, por defecto, busca una palabra en la respuesta (F=Incorrect) y aquí la respuesta es una redirección, así que da falsos positivos en cascada

El truco es cambiar la condición de fallo: en vez de buscar una palabra, decirle a hydra que considere erróneo cuando la respuesta redirige a index.php. Aun así, la contraseña de admin no está en los diccionarios habituales — el camino de verdad es otro.
El escáner de ficheros — SSRF
Vuelvo a staging.love.htb y entro en la pestaña Demo: pide la URL de un fichero para escanearlo


Para entender cómo se comporta, levanto un servidor y le paso la URL de un .txt mío. El escáner se lo descarga desde la víctima y me muestra su contenido

Que además lo interprete abre la puerta a un XSS. Lo confirmo con un .html que lleva un <script>

Pruebo a subir la apuesta a RCE con .php en varias extensiones, pero no hay suerte: solo interpreta código de navegador, no PHP del lado del servidor

Lo verdaderamente potente es otra cosa: si el escáner se descarga cualquier URL, puedo apuntarlo contra la propia máquina. Es un SSRF. Le pido http://127.0.0.1:80 y me devuelve el login del Voting System — estoy haciendo peticiones desde dentro

Probando puertos, el 443 interno se queja de que le hablo en HTTP plano

y aquí está el premio: el puerto 5000, que desde fuera daba 403 Forbidden…

…visto desde dentro con el SSRF es un Password Dashboard que suelta las credenciales de administrador en bandeja: admin:@LoveIsInTheAir!!!!

Dentro del panel — File Upload a RCE
Con esas credenciales entro en /admin/ del Voting System y llego al dashboard

En Voters puedo crear un votante con una foto. El formulario no comprueba el tipo de archivo, así que preparo una webshell en PHP y la subo como si fuera la imagen



Las fotos se guardan en /images/. Abro mi fichero y le paso un comando por la URL: ?cmd=whoami devuelve love\phoebe, y la ruta del error revela que estoy en C:\xampp\htdocs\omrs\images

Ya tengo ejecución de código, pero quiero una shell interactiva. Intento con la clásica php-reverse-shell, cambiándole la IP, el puerto y el $shell a cmd.exe

pero se queda colgada: cmd.exe solo suelta su salida cuando cree que habla con una consola de Windows real, y un socket — que no es más que un canal de bytes en bruto entre dos máquinas, sin nada de «terminal» — no se lo hace creer

El plan B es subir un nc.exe y lanzarlo desde la ejecución de comandos que ya tengo. Primero confirmo que el formulario también acepta .exe

Localizo la ruta exacta con ?cmd=cd, que confirma C:\xampp\htdocs\omrs\images

así que el binario quedará en C:\xampp\htdocs\omrs\images\nc.exe. Subo el nc.exe, me pongo en escucha, y lo ejecuto desde la webshell — hay que URL-encodear el comando para que llegue entero

Al otro lado, el listener recibe la shell como phoebe

Con shell estable, leo la primera bandera en el escritorio de phoebe

Escalada de privilegios
Con la shell de phoebe, busco configuraciones típicas de Windows mal puestas. Reviso las registry keys de política del instalador y ahí está la joya: AlwaysInstallElevated a 0x1

Esa política hace que cualquier paquete .msi se instale con privilegios de SYSTEM. Así que me genero un instalador malicioso con msfvenom que, al ejecutarse, me devuelve una shell

Lo subo a la víctima por la misma vía del file upload del panel

Hay un detalle molesto: si dejo el fichero directamente en C:\Windows\Temp, el antivirus lo borra. La solución es crear una subcarpeta propia y moverlo ahí

Con un listener esperando, ejecuto el instalador de forma silenciosa
NT AUTHORITY\SYSTEM. Control total de la máquina. Leo la última bandera en el escritorio de Administrator

Flags
La de usuario, en el escritorio de phoebe
Y la de root, en el de Administrator
Cómo se arregla
La máquina encadena un fallo de diseño tras otro; cada capa tiene su remedio:
- Validar el destino del escáner: el Free File Scanner nunca debería poder pedir URLs internas. Una lista blanca de dominios permitidos y el bloqueo de 127.0.0.1, rangos privados y metadata endpoints cierran el SSRF.
- No exponer secretos en servicios internos: un panel que muestra la contraseña de admin en texto plano es un regalo. Las credenciales no se publican ni en el 5000 ni en ningún sitio; y confiar en que el 5000 sea «interno» no basta cuando hay un SSRF.
- Validar las subidas de ficheros: el Voting System debe comprobar extensión y MIME type, renombrar los ficheros, guardarlos fuera del webroot y servirlos sin permitir su ejecución. Eso corta el RCE de raíz.
- Actualizar el stack: XAMPP con Apache 2.4.46 y PHP 7.3.27 está muy desfasado. Mantenerlo al día reduce la superficie de ataque.
- Desactivar AlwaysInstallElevated: poner la clave a 0 en HKLM y HKCU elimina la escalada por MSI. Es una política que casi nunca debería estar activa.
- Contraseñas robustas y login sin fugas: evitar que el formulario distinga «usuario no existe» de «contraseña incorrecta» frena la enumeración de usuarios.
Conclusiones
Máquina 10/10, perfecta para eWPT, full web y muy divertida, te hace pensar nuevas maneras de explotarla, muy recomendable