本文首发自公众号:EnsecTeam

我们专注漏洞检测方向:danenmao、arnoxia、皇天霸、lSHANG、KeyKernel、BugQueen、zyl、隐形人真忙、oxen(不分先后)

作者:隐形人真忙 & KeyKernel

一、什么是灰盒扫描

传统扫描器的原理实际上是构造一些探测串,一般称之为载荷(payload),用这些构造出来的数据进行组包并发送给服务器,当服务器返回数据或者做出的反应符合某种判定规则时,就认为有漏洞。这个过程是一个黑盒探测的过程,并不涉及到服务的具体逻辑,而且受网络通信的制约较大——如进行延时SQL注入扫描时,网络延迟的大小直接影响扫描的准确性。此外,基于黑盒的传统扫描往往需要发送大量的数据包,如布尔型SQL注入漏洞扫描中,需要构造大量的闭合语法扫描payload,可能仅仅检测一条URL就要发送1000个以上的请求。

灰盒漏洞扫描正是为了弥补传统黑盒扫描的不足,通过HOOK需要检测的敏感函数,可以在web应用运行时获取到对应的危险参数,配合Fuzz技术,可以更加高效、准确地发现漏洞

二、灰盒扫描架构设计

本节以PHP语言为例,来讲解如何构建一个适用于PHP的动态灰盒扫描系统。灰盒扫描系统一般分为三部分:

(1)   HOOK部分

主要实现对一些危险函数进行HOOK,确保在运行时环境中能够获取到传入函数的任意参数。

(2)  Fuzz部分

主要生产一些精心构造的污染数据,比如包含一些特殊符号的字符串等。通过扫描发包的方式将脏数据插入到各个待检测的地方。

(3)  规则部分

主要负责对漏洞的识别。通过和Fuzz系统进行配合,检查HOOK到的参数是否符合判别规则,从而判断是否存在漏洞,如果存在则发起上报流程。

这三个模块如下图所示进行整合:

当然,基于fuzz的思路也有缺点,那就是非常依赖于待测web应用的URL输入源的质量。如果URL不够完整,很可能会漏掉某些代码片段,无法做到像静态代码扫描一样的全面检查。事实上,这也是静态分析技术和动态分析技术的区别,即动态分析技术的代码覆盖很难做到非常全面。

三、构建灰盒扫描系统

3.1 构建HOOK层

3.1.1 HOOK原理

3.1.1.1 Zend和PHP

PHP是一个解释型语言,我们编写的PHP脚本文件需要解释器进行解析,生成中间代码然后执行。实现一个解释语言一般需要三个部分:

(1) 解释器部分:分析输入的代码,翻译该代码,然后执行代码。

(2) 功能部分:完成语言的一些特性和功能(如函数、类等等)

(3) 接口部分:提供外部统一交互接口(如与Web通信等)

Zend引擎是PHP实现的核心,它完成了解释器部分的实现,并且部分参与PHP的功能部分实现,如一些PHP语言的实现、扩展机制、内存管理机制等。Zend引擎与PHP的关系图如下:

通常我们都选择使用实现一个扩展的形式来扩展PHP,在PHP扩展中,我们可以调用Zend API做很多定制化的功能,包括实现对PHP内置函数调用的HOOK操作。

3.1.1.2 PHP Opcode

PHP是一种解释型语言,运行一段PHP代码通常包含两个阶段:编译和执行,其中编译部分包含语义分析、语法分析等阶段,这些功能由Zend引擎负责提供。一段PHP脚本文件经过Zend内核的处理,会变为一系列的操作码,称为opcode。这是一种Zend内核可以理解的中间语言,在执行阶段就是去执行这些opcode完成操作。

我们可以使用vld扩展(http://pecl.php.net/package/vld)来查看某段PHP脚本代码的opcode,安装方法如下:

[root@localhost]# wget http://pecl.php.net/get/vld-0.14.0.tgz

[root@localhost]# tar zxvf    vld-0.14.0.tgz

[root@localhost]# cd vld-0.14.0/

[root@localhost]# phpize

[root@localhost]# ./configure -    -with-php-config=[your path of php-config] - -enable-vld

[root@localhost]# make && make    install

安装完成后,编辑一段PHP代码如下:

echo “hello world” ;

?>