本文首发自公众号: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” ;?> |