php utf8 decode漏洞

来源:80sec

漏洞说明: php是一款被广泛使用的编程语言,可以被嵌套在html里用做web程序开发。但是在php里使用的某些编码函数在处理畸形的utf8序列时会产生不正确的结果,这样在某些情况下可能会引起应用程序的安全漏洞,绕过某些逻辑过滤等等。

漏洞成因:php在处理utf8编码时,对畸形的序列处理不当,如

...
0xc0a7
0xe0c0a7
0xf0c0c0a7
...



均会被错误地解码为一个0×27,这样就导致安全漏洞的产生。譬如utf8_decode函数的源代码如下:

PHPAPI char *xml_utf8_decode(const XML_Char *s, int len, int *newlen, const XML_Char *encoding)
{
int pos = len;
char *newbuf = emalloc(len + 1);
unsigned short c;
char (*decoder)(unsigned short) = NULL;
xml_encoding *enc = xml_get_encoding(encoding);
*newlen = 0;
if (enc) {
decoder = enc->decoding_function;
}
if (decoder == NULL) {
/* If the target encoding was unknown, or no decoder function
* was specified, return the UTF-8-encoded data as-is.
*/
memcpy(newbuf, s, len);
*newlen = len;
newbuf[*newlen] = ‘\0′;
return newbuf;
}
while (pos > 0) {
c = (unsigned char)(*s);
if (c >= 0xf0) { /* four bytes encoded, 21 bits */
c = ((s[0]&7)<<18) | ((s[1]&63)<<12) | ((s[2]&63)<<6) | (s[3]&63);
s += 4;
pos -= 4;
} else if (c >= 0xe0) { /* three bytes encoded, 16 bits */
c = ((s[0]&63)<<12) | ((s[1]&63)<<6) | (s[2]&63);
s += 3;
pos -= 3;
} else if (c >= 0xc0) { /* two bytes encoded, 11 bits */
c = ((s[0]&63)<<6) | (s[1]&63);
s += 2;
pos -= 2;
} else {
s++;
pos–;
}
newbuf[*newlen] = decoder ? decoder(c) : c;
++*newlen;
}
if (*newlen < len) {
newbuf = erealloc(newbuf, *newlen + 1);
}
newbuf[*newlen] = ‘\0′;
return newbuf;
}

xml_utf8_decode函数被广泛用于xml和wddx的编码处理中,在处理utf8编码时并没有严格按照utf8的解码规则来校验数据的正确性,导致出现问题。另外在php的htmlspecialchars等函数中处理utf8编码时也存在类似问题。
漏洞测试:

<?php
$ill=chr(0xf0).chr(0xc0).chr(0xc0).chr(0xa7);
$ill=addslashes($ill);
echo utf8_decode("$ill");
echo htmlspecialchars ($ill,ENT_QUOTES,"utf-8" );
?>

漏洞影响:可能影响所有php版本

漏洞状态:已经通知php官方

相关日志

发表评论