网络安全服务(NSS)是一套用于跨平台开发启用了安全功能的客户端和服务器应用的库,用NSS编译的应用可以支持SSLv2、SSLv3、TLS等安全标准。 Firefox等浏览器所使用的用于匹配证书中公用名的NSS库正则表达式解析器中存在堆溢出。恶意网站可以提供特制的证书触发堆溢出,导致崩溃或以运行浏览器用户的权限执行任意指令。 以下是NSS库中的有漏洞代码段: security/nss/lib/util/portreg.c: 141 static int 142 _handle_union(const char *str, const char *exp, PRBool case_insensitive) 143 { 144 char *e2 = (char *) PORT_Alloc(sizeof(char)*strlen(exp)); 145 register int t,p2,p1 = 1; 146 int cp; 147 148 while(1) { 149 for(cp=1;exp[cp] != \'\')\'\';cp++) 150 if(exp[cp] == \'\'\\\'\') 151 ++cp; 152 for(p2 = 0;(exp[p1] != \'\'|\'\') & & (p1 != cp);p1++,p2++) { 153 if(exp[p1] == \'\'\\\'\') 154 e2[p2++] = exp[p1++]; 155 e2[p2] = exp[p1]; 156 } 157 for (t=cp+1; ((e2[p2] = exp[t]) != 0); ++t,++p2) {} 158 if(_shexp_match(str,e2, case_insensitive) == MATCH) { 159 PORT_Free(e2); 160 return MATCH; 161 } 162 if(p1 == cp) { 163 PORT_Free(e2); 164 return NOMATCH; 165 } 166 else ++p1; 167 } 168 }...
网络安全服务(NSS)是一套用于跨平台开发启用了安全功能的客户端和服务器应用的库,用NSS编译的应用可以支持SSLv2、SSLv3、TLS等安全标准。 Firefox等浏览器所使用的用于匹配证书中公用名的NSS库正则表达式解析器中存在堆溢出。恶意网站可以提供特制的证书触发堆溢出,导致崩溃或以运行浏览器用户的权限执行任意指令。 以下是NSS库中的有漏洞代码段: security/nss/lib/util/portreg.c: 141 static int 142 _handle_union(const char *str, const char *exp, PRBool case_insensitive) 143 { 144 char *e2 = (char *) PORT_Alloc(sizeof(char)*strlen(exp)); 145 register int t,p2,p1 = 1; 146 int cp; 147 148 while(1) { 149 for(cp=1;exp[cp] != \'\')\'\';cp++) 150 if(exp[cp] == \'\'\\\'\') 151 ++cp; 152 for(p2 = 0;(exp[p1] != \'\'|\'\') & & (p1 != cp);p1++,p2++) { 153 if(exp[p1] == \'\'\\\'\') 154 e2[p2++] = exp[p1++]; 155 e2[p2] = exp[p1]; 156 } 157 for (t=cp+1; ((e2[p2] = exp[t]) != 0); ++t,++p2) {} 158 if(_shexp_match(str,e2, case_insensitive) == MATCH) { 159 PORT_Free(e2); 160 return MATCH; 161 } 162 if(p1 == cp) { 163 PORT_Free(e2); 164 return NOMATCH; 165 } 166 else ++p1; 167 } 168 } 基于144行的strlen()执行malloc,但在154行\")\"之前一直进行拷贝。可通过在传送给两级之上父函数的字符串中包含\"~\"来替换这个字符串中的\"\0\"字符: 263 static int 264 port_RegExpMatch(const char *str, const char *xp, PRBool case_insensitive) { 265 register int x; 266 char *exp = 0; 267 268 exp = PORT_Strdup(xp); 269 270 if(!exp) 271 return 1; 272 273 for(x=strlen(exp)-1;x;--x) { 274 if((exp[x] == \'\'~\'\') & & (exp[x-1] != \'\'\\\'\')) { 275 exp[x] = \'\'\0\'\'; 276 if(_shexp_match(str, &exp[++x], case_insensitive) == MATCH) 277 goto punt; 278 break; 279 } 280 } 281 if(_shexp_match(str,exp, case_insensitive) == MATCH) { 282 PORT_Free(exp); 283 return 0; 284 } 285 286 punt: 287 PORT_Free(exp); 288 return 1; 289 } 类似于(foo~bar)的字符串会分配strlen(foo),然后在所分配的内存后覆盖bar个字节。