PHP 代码不开源下的一种漏洞检测思路

 
现在很多的PHP 软件厂商为了一些目的都开始将自己的产品用Zend 加密起来,当客户使用的时候根本不知道程序里面的细节,的确给那些搞安全的人很大的难度,所以一些厂商就开始认为只要是Zend 过的产品都是安全的。但是其实不然,即使在不知道原代码并且不考虑Zend 破解的情况下,我们一样可以利用PHP 本身的一些特性来获取程序的一些商业逻辑以及信息,从而达到探测程序的漏洞。
测试程序的安全性方法一般有三种,第一是完全的不知道源代码,不知道程序内部处理的细节,完全靠输入的参数来猜测程序内部的细节以及可能出现的问题,另外一种就是能得到程序的代码知道代码的处理流程,通过对代码的分析来得到程序的问题。还有另外一种方式就是处于中间的灰盒测试,可以知道程序的一部分细节,这里我们要说的可能就属于这种方式了,因为我们知道Zend所谓的加密其实是将PHP 代码转成了一个中间态的代码,在支持Zend 加密的主机上最终都是跟正常的PHP 文件一样被翻译成底层代码执行的,不过是源代码不可见罢了。但是要注意一点就是,这个加密代码是在我们提供的环境之中运行的,他用的语言环境是我们机器上的PHP,他所选择的数据库等存储系统是我们提供的文件系统或者Mysql 等数据库,这就比单纯的黑盒测试多了很多可以利用的地方,因为我们完全可以控制他的运行环境,甚至大部分的处理结果对我们也是可见的,我们就有空子可钻了。然后说说PHP 代码里的常见漏洞,一般的漏洞包括有SQL 注射、文件包含、代码执行、XSS 注
射、逻辑性错误等等。在知道代码的情况下我们可以比较容易检测出大部分的漏洞,但是由于代码加密变的不可见,只采用一般的黑盒测试方法只能检测一些常见的漏洞,但是对于一些变量没初始化和一些逻辑错误无能为力。下面就说说在应用层如何探测程序的一些安全问题。
首先就是如何“调试”加密的PHP 脚本的问题,这里的调试实际上是指如何让加密的PHP 脚本在我们可以控制的环境下运行,我这里用的方法就是创建一个PHP 文件来include 包含执行需要调试的加密过的PHP 文件,在include 之前我们可以设置调试代码,在include 执行完毕后我们还可以利用后面提到的方法查看脚本的一些信息。譬如我们要调试zend.php 这个被加密的文件,就可以利用下面的方式:
<?php
// 一些运行前的代码
echo "Just a example" ;
include 'zend.php' ;
echo "OK" ;
// 一些运行后的代码
?>
这样zend.php 里的东西就受我们的影响了。然后要做的就是对代码的刺探了,很幸运的是PHP 提供了很多的函数给我们使用,譬如比较有用的有:
get_defined_vars 返回由所有已定义变量所组成的数组(PHP4 >= 4.0.4, PHP 5)
get_declared_classes 返回由已定义类的名字所组成的数组(PHP4,PHP 5)
get_defined_constants 返回由已定义常量的名字所组成的数组
get_defined_functions 返回由已定义的函数
get_included_files 返回已经包含的文件名
......
大家可以去PHP 手册里查下,利用这些函数我们就能做很多事情了,譬如我们知道某个加密的文件zend.php 里面有我们很想要的东西,譬如数据库账户密码,譬如某个加密的Key,譬如......
那么我们就可以将这个文件利用上面的方法include 出来,然后用get_defined_vars 函数看信息,
例子如下:
<?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 的内容就可以知道是不是有变量覆盖的问题了,代码流程如下:
<?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 );
} e
lse
{
php_printf( "%s Unregister Faild/r/n" , function );
}
RETVAL_LONG( 42 );
return ;
}
    再下去呢?再下去就是修改PHP 内核了,就有点超出本文的范围了。文章要说明的是加密不是一切,通过修改程序运行环境以及一些小技巧然后再结合黑盒测试的方法,找出一些加密过的程序的安全漏洞还是可能的,本人就检测过国内一些加密程序,比较大的漏洞还是有的。
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值