### 漏洞概述 该漏洞涉及 `resolv_vpn_server` 函数中的栈溢出问题,可能导致任意命令执行。具体而言,`vpn_pptp_server` 变量通过 Web 传入,并通过 `nvram_get` 函数获取,导致栈溢出。 ### 影响范围 - **受影响函数**:`resolv_vpn_server` - **触发条件**:`vpn_pptp_server` 变量通过 Web 传入 - **潜在风险**:任意命令执行 ### 修复方案 - **代码审查**:对 `resolv_vpn_server` 函数进行详细审查,确保输入数据的长度和格式正确。 - **输入验证**:增加对 `vpn_pptp_server` 变量的输入验证,防止过长的输入导致栈溢出。 - **缓冲区管理**:使用安全的字符串处理函数(如 `strncpy`)替代 `strcpy`,避免缓冲区溢出。 ### POC 代码 ```c int resolv_vpn_server() { int v0; // $s1 const char *v1; // $a0 char *v2; // $a1 int v4; // $v0 int v5; // $s3 const char *v6; // $s2 int v7; // $v0 int v8; // $s0 char *v9; // $a0 int v10; // $s0 const char *v11; // $a0 char *v12; // $a1 char *v13; // $a1 int v15; // $s0 int v16; // $s0 char v17[184]; // [sp+20h] [-188h] BYREF _BYTE v18[40]; // [sp+0Dh] [-58h] BYREF _BYTE v19[40]; // [sp+100h] [-28h] BYREF memset(v17, 0, 180); memset(v18, 0, sizeof(v10)); memset(v19, 0, sizeof(v15)); v0 = 0; if ( nvram_match("vpn_type", "PPTP") ) { v1 = "vpn_pptp_server"; } else { if ( !nvram_match("vpn_type", "L2TP") ) goto LABEL_6; v1 = "vpn_l2tp_server"; } v2 = (char *)nvram_get(v1); if ( v2 ) { strcpy(v17, v2); } LABEL_6: cutSpaceBack(v17); if ( v17[0] ) _res_init(); v5 = (char *)nvram_get("cur_wan_dns2"); if ( v5 ) { v5 = ""; strcpy(v8, v5); v6 = (char *)nvram_get("ppp_local_name"); if ( v6 ) { v6 = ""; strcpy(v9, v6); if ( v7[0] ) { nvram_set("_tmpBeforeVPNDNS1", v7); if ( v8[0] ) { nvram_set("_tmpBeforeVPNDNS2", v8); if ( v9[0] ) { nvram_set("_tmpBeforeVPPIPPNAME", v9); if ( resolv_vpn_server() ) { if ( nvram_match("vpn_type", "PPTP") ) start_vpn_pptp(); } } } } } } return 0; } ``` ### 利用代码 ```c main->sub_40C360->start_single_service->connect_vpn->resolv_vpn_server ``` ### 总结 该漏洞的关键在于 `resolv_vpn_server` 函数中对 `vpn_pptp_server` 变量的处理不当,导致栈溢出。修复措施包括输入验证、缓冲区管理和代码审查。