会员登陆:
载入中…
我要发布
联系我们
广告合作
推荐:系统管理 信息安全 企业管理 大众消费 多媒体 存储备份 商业智能 系统软件 PK 企业库 软件商城 威客 在线演示 我要发布
病毒防护 | 防火墙 | 入侵检测 | 漏洞扫描 | 入侵防御 | VPN | 身份认证 | 密码保护 | 访问控制 |
安全网关 | 反黄 | 防伪 | 软件加密 | 信息加密 | 防垃圾邮件 | 网络流量分析 | 负载均衡
    ISS  |  金山  |  三星   |  AdventNet   |  其它
您现在的位置: 中华软件网|中国软件导购网 >> 信息安全 >> 漏洞扫描 >> 解决方案 >> 信息安全正文
企业新闻
普通信息安全金山毒霸荣获2006年《数字时
普通信息安全三星漏洞扫描产品绑入冠群金
普通信息安全前沿动力文档安全管理 防止企
普通信息安全微软信息安全公告 ActiveX漏
普通信息安全微软漏洞养活了黑客及安全公
普通信息安全忘记了密码照样能进入Window
普通信息安全暴风影音播放器存在多个缓冲
普通信息安全“假补丁”病毒利用微软漏洞
导购论坛
·常用软件导购
·报表工具软件导购
·数据备份软件导购
·系统管理软件导购
·信息安全软件导购
·数据库软件导购
·基础软件导购
·行业软件导购
产品评测
普通信息安全 内网信息安全/信息防泄漏产品
普通信息安全 榕基RJ-iTop漏洞扫描系统护航
普通信息安全 超半数行业用户担忧自身信息
相关软件下载
相关技术白皮书
在线体验
服务点评
  • 此栏目下没有信息安全
  • 专家点评
    普通信息安全 黑客兵器 如何选择好的漏洞扫
    客户评价
    普通信息安全 三星漏洞扫描获殊荣
    负面报道
  • 此栏目下没有信息安全
  • 解决方案
    普通信息安全 如何快速排除网络故障
    普通信息安全 实用级反主动防御rootkit设计思路
    普通信息安全 覆盖SEH的溢出利用检测思路
    普通信息安全 php代码不开源下的一种漏洞检测思
    普通信息安全 使用漏洞扫描工具有效防范蠕虫病
    推荐信息安全 SecureCentral™ ScanFi 4方
    普通信息安全 三星中小企业网络安全解决方案
    普通信息安全 ISS漏洞扫描解决方案
    Google
    论坛
    php代码不开源下的一种漏洞检测思路
    作者:佚名    信息安全来源:本站原创    点击数:    更新时间:2007-9-20    

      现在很多的php软件厂商为了一些目的都开始将自己的产品用Zend加密起来,当客户使用的时候根本不知道程序里面的细节,的确给那些搞安全的人很大的难度,所以一些厂商就开始认为只要是Zend过的产品都是安全的。但是其实不然,即使在不知道原代码并且不考虑Zend破解的情况下,我们一样可以利用Php本身的一些特性来到达获取程序的一些商业逻辑以及信息以到达探测程序的漏洞等等。

      测试程序的安全性方法一般有三种,第一是完全的不知道源代码,不知道程序内部处理的细节,完全靠输入的参数来猜测程序内部的细节以及可能出现的问题,另外一种就是能得到程序的代码知道代码的处理流程,通过对代码的分析来得到程序的问题。还有另外一种方式就是处于中间的灰盒测试,可以知道程序的一部分细节,这里我们要说的可能就属于这种方式了,因为我们知道Zend所谓的加密其实是将PHP代码转成了一个中间态的代码,在支持Zend加密的主机上最终都是跟正常的PHP文件一样被翻译成底层代码执行的,不过是源代码不可见罢了。但是要注意一点就是,这个加密代码是在我们提供的环境之中运行的,他用的语言环境是我们机器上的PHP,他所选择的数据库等存储系统是我们提供的文件系统或者Mysql等数据库,这就比单纯的黑盒测试多了很多可以利用的地方,因为我们完全可以控制他的运行环境,甚至大部分的处理结果对我们也是可见的,我们就有空子可钻了。

      然后说说PHP代码里的常见漏洞,一般的漏洞包括有Sql注射,文件包含,代码执行,Xss注射,逻辑性错误......等等。在知道代码的情况下我们可以比较容易检测出大部分的漏洞,但是由于代码加密变的不可见,只采用一般的黑盒测试方法只能检测一些常见的漏洞,但是对于一些变量没初始化和一些逻辑错误无能为力。下面就说说在应用层如何探测程序的一些安全问题。

      首先就是如何“调试”加密的PHP脚本的问题,这里的调试实际上是指如何让加密的PHP脚本在我们可以控制的环境下运行,我这里用的方法就是创建一个php文件来include包含执行需要调试的加密过的PHP文件,在include之前我们可以设置调试代码,在include执行完毕后我们还可以利用后面提到的方法查看脚本的一些信息。譬如我们要调试zend.php这个被加密的文件,就可以利用下面的方式:

      eg    <?php
            //一些运行前的代码
            echo "Just a example";
            include 'zend.php';
            echo "OK";
            //一些运行后的代码
            ?>
       
      这样zend.php里的东西就受我们的影响了。

      然后要做的就是对代码的刺探了,很幸运的是PHP提供了很多的函数给我们使用,譬如比较有用的有:

        get_defined_vars 返回由所有已定义变量所组成的数组 (PHP 4 >= 4.0.4, PHP 5)
        get_declared_classes 返回由已定义类的名字所组成的数组 (PHP 4, PHP 5)
        get_defined_constants 返回由已定义常量的名字所组成的数组
        get_defined_functions 返回由已定义的函数
        get_included_files    返回已经包含的文件名
        ......

      大家可以去php手册里查下,利用这些函数我们就能做很多事情了,譬如我们知道某个加密的文件zend.php里面有我们很想要的东西,譬如数据库帐户密码,譬如某个加密的Key,譬如......那么我们就可以将这个文件利用上面的方法include出来,然后用get_defined_vars函数看信息,例子如下:

        eg    <?php
            include 'zend.php';
            print_r(get_defined_vars);
            ?>
       
      怎么样,出来了吧?同样,一些程序员通常把一些函数放到一个php文件里,我们就可以通过同样的方法得到这个php文件里定义了的函数了。
      在一些程序破解里,经常有一个说法叫做Hook,其实我们在进行我们的测试的时候也可以进行简单的Hook。一个站点的SQL查询里经常蕴涵了很多的信息,如果知道了进行某个操作要用的SQL查询对我们的测试是很有用处的。我们有好几个方法,譬如更改php的mysql_query函数,在Mysql方面做手脚,这里我们还是简单点看看应用层能做什么吧!一般的PHP代码都喜欢将Mysql操作封装起来放到一个文件里,我们就可以将这个文件替换掉,自己实现他需要实现的函数,在其中将他运行的SQL语句断下来保存(Thx Saiy),然后我们就可以分析这些SQL查询了,同样的道理,我们完全可以做出假的Function来到达猜测某些函数的功能的目的,在假的函数里用如下func_get_args函数就可以截获传入的参数。当然,这对于函数内部的细节还是不清楚的,但是很多时候已经足够了,起码把黑盒由文件级别降低到函数级别了,呵呵。
       
      而对于程序本身我们能做什么呢?对于一个程序的安全性我们通常关注的有他处理参数的方式,他如何对待危险函数的,他的变量有不有正确的初始化......等等,通过上面的思想我们就大概能做这些事了:)
           
      1、利用PHP自身的设置猜测程序处理参数的方式   
           
      一个PHP程序是要处理参数的,在代码中程序如何处理我们提交的变量是很重要的。譬如一些程序为了兼容所有的PHP环境,都会在开始释放变量以实现在register globals = off的时候程序一样能运行,并且为了在GPC = off 的时候程序不出问题,一般都会做addslashes处理,但是也并不是所有的程序都能正确处理好,所以我们通过更改PHP.ini的设置就可以大致推测出程序是如何处理输入的参数的。譬如,我们将register globals 设置为 off,我们然后include某个文件(譬如index.php),然后在代码的最后print_r($GLOBALS)来查看当前符号表里是不是有我们提交的参数,如果有的话就证明程序是将变量释放的,然后我们提交一些危险的变量如php?_POST=aaaaa然后看看$_POST的内容就可以知道是不是有变量覆盖的问题了,代码流程如下:

        eg    <?php
            include 'index.php';
            print_r($GLOBALS);
            ?>
       
      当然,之前需要设置register global = off

       
      2、利用PHP自身的出错机制

      在PHP运行过程中,可以根据自定义的错误级别捕捉程序中的一些信息,默认情况下对未初始化这些信息并不做判断,但是没有初始化的变量确能给我们有用的信息。一些常见的文件包含漏洞就是都是由变量未初始化造成的。当我们把运行级别错误设置为NOTICE时就可以看到这些信息了,但是也不排除有程序人为地在运行过程中修改运行级别,后面我会说说对付这种的方法。找到未初始化变量之后我们就可以试着提交它,来看程序的反映,结合功能以及变量名猜测程序的写法,通常可以挖掘一些漏洞。

      3、结合php扩展

      这一来就有点向底层靠了,PHP自己是提供了一些查询系统状态的函数如上面提供的get_defined_vars之类,但是这些是远远不够的,但是PHP本身又不像js那样覆盖系统原有的函数就是不允许函数重定义,这就给我们带来了麻烦,譬如我们想跟踪程序有不有调用preg_replace函数,并且想知道里面的参数形式,我们是没有办法的,但是利用PHP扩展就变得可能了,我们可以类似于一种Hook的方法来实现这些。譬如想调查preg_replace的话,我们先将preg_replace这个函数从函数表里Dump成preg_replace_bak一份,然后create_function建立我们自己的函数,我们自己的函数目的很简单,先保存参数然后调用原来的preg_replace_bak函数并返回结果,这样就可以监视脚本里这个函数的调用情况了。我这里有个简单的从函数表里删除函数的代码:

      删除函数的一个php扩展代码


    PHP_FUNCTION(fuck_fun)

    {

            char *function;
            int function_len;
            zval **findfun;


            if (ZEND_NUM_ARGS() != 1 || zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,"s", &function, &function_len) == FAILURE) {
            WRONG_PARAM_COUNT;
            }

            TSRMLS_FETCH();

            if (zend_hash_find(EG(function_table), function, strlen(function)+1,(void**)&findfun)==SUCCESS) {
            php_printf("Find function %s OK\r\n",function);
            }
            else {
            php_printf("Cann't find function %s\r\n",function);
            }

            if (zend_hash_del(EG(function_table), function, strlen(function)+1)==SUCCESS) {
            php_printf("%s Unregister OK\r\n",function);
            }
            else {
            php_printf("%s Unregister Faild\r\n",function);
            }
            RETVAL_LONG(42);
            return;
    }


      4、再下去呢?再下去就是修改PHP内核了,就有点超出本文的范围了。文章要说明的是加密不是一切,通过修改程序运行环境以及一些小技巧然后再结合黑盒测试的方法,找出一些加密过的程序的安全漏洞还是可能的,本人就检测过国内一些加密程序,比较大的漏洞还是有的:)

    Copyright@ 2003-2008 www.soft2008.com.cn All Right Reserved
    京ICP备06062655号
    分类导航