• PHP之is_a()函数执行代码之总结


    今天看到云舒在群里贴的漏洞公告,原始的文章在

    http://www.byte.nl/blog/2011/09/23/security-bug-in-is_a-function-in-php-5-3-7-5-3-8/

    后来查了下PHP官方的手册,这个问题是在PHP 5.3.7中更新了is_a()函数的功能。is_a()经常被用于条件判断。

        在此前版本的is_a() 的第一个参数如果不是object,则会返回false,现在变成了如果不是object ,则会去执行 __autoload()函数。PHP为此还开了一个bug,但对此bug仍然有争议,部分开发人员认为这个功能是正常的。

    Aron Budinszky 07-Sep-2011 11:21

    Be careful! Starting in PHP 5.3.7 the behavior of is_a() has changed slightly: when calling is_a() with a first argument that is not an object, __autoload() is triggered!

    In practice, this means that calling is_a('23', 'User'); will trigger __autoload() on "23". Previously, the above statement simply returned 'false'.

    More info can be found here:
    https://bugs.php.net/bug.php?id=55475

    Whether this change is considered a bug and whether it will be reverted or kept in future versions is yet to be determined, but nevertheless it is how it is, for now...

        但是需要注意的是,PHP是否会对这个问题做出修补仍属未知!在昨天发布的PHP 5.4 beta1 中,并未见到修复了此问题。

        这是一个类似于PHP的unserialize()函数可以执行__destruct()/__wakeup()中代码的问题

        漏洞的触发是控制 is_a()函数的第一个参数,该参数会被当做输入传入__autoload()函数,并自动执行__autoload()函数中的代码。能够执行什么功能,取决于__autoload()函数的功能。

        验证此问题如下:

    测试代码:

    <?php

    function __autoload($classname){

      include_once $classname;

    }

    function test($str){

      print "this is a test<br>";

      $object = $str;

      if (!is_a($object, 'SAFE')){

        die("not safe!<br>");

      }

    }

    test($_GET["a"]);

    ?>

    测试结果:

        但是一般来说,__autoload()函数的功能会用于加载一个文件,比如在DEDECMS中的用法:

    //自动加载类库处理

    function __autoload($classname)

    {

        global $cfg_soft_lang;

        $classname = preg_replace("/[^0-9a-z_]/i", '', $classname);

        if( class_exists ( $classname ) )

        {

            return TRUE;

        }

        $classfile = $classname.'.php';

        $libclassfile = $classname.'.class.php';

            if ( is_file ( DEDEINC.'/'.$libclassfile ) )

            {

                require DEDEINC.'/'.$libclassfile;

            }

            else if( is_file ( DEDEMODEL.'/'.$classfile ) ) 

            {

                require DEDEMODEL.'/'.$classfile;

            }

            else

            {

                if (DEBUG_LEVEL === TRUE)

                {

                    echo '<pre>';

    echo $classname.'类找不到';

    echo '</pre>';

    exit ();

                }

                else

                {

                    header ( "location:/404.html" );

                    die ();

                }

            }

    }

        此处在加载文件前判断了文件名只能为/[^0-9a-z_]/i 中的字符,相对较为安全。

        但在另外某知名CMS中,则没有做任何判断:

    function __autoload($class) {

        include_once $class.'.php';

        if(!class_exists($class,false)) exit('系统加载类失败,类'.$class.'不存在!');

    }

        由于这个漏洞是需要is_a()函数配合 __autoload() 才能利用,且对PHP版本有要求,因此实际中能够找到利用的地方相对较少。但若是PHP官方坚持不认为这是个漏洞,在未来可能会成为一个一直可以利用的弱点。在PHP5.4中is_a()可能会支持string类型参数,同时此漏洞应该已经上报给了CVE。

  • 相关阅读:
    改变Prompt默认路径,Change Default Visual Studio Command Prompt Location
    msbuild,Build failed with Error MSB3073 exited with code 1
    the filename directory name or volume label syntax is incorrect
    常用sql语句记录
    EF中多表公共字段,以及设置EntityBase使所有实体类继承自定义类
    一种在MVC3框架里面设置模板页的方法,不使用_ViewStart
    Java内存模型
    Effective Java(1)-创建和销毁对象
    WireShark 查看UDP码流的丢包率
    拖延心理学读后感
  • 原文地址:https://www.cnblogs.com/milantgh/p/3633485.html
Copyright © 2020-2023  润新知