浅谈模糊测试Fuzzing

浅谈模糊测试Fuzzing

时间:2021-02-19 作者:安帝科技

前言

Fuzzing英文原意“起毛”,在安全测试领域通常翻译为“模糊测试”。Fuzzing技术可以追溯到1950年,当时计算机的数据主要保存在打孔卡片上,计算机程序读取这些卡片的数据进行计算和输出。如果碰到一些垃圾卡片或一些废弃不适配的卡片,对应的计算机程序就可能产生错误和异常甚至崩溃,这样,Bug就产生了。随着计算机的发展,Fuzzing技术也在不断发展,现在Fuzzing技术通过自动化生成并执行大量的随机测试用来发现产品或协议的未知漏洞。相比较以前流行的人工测试和漏洞挖掘,Fuzzing技术是一种自动化技术,程序根据用户的设定自动执行随机测试。因为是程序自动运行,所以效率相较人工远远高出几个数量级。另外,受人类的脑力和想象力限制,没有办法想到所有可能的异常组合,许多异常情况开发人员和测试人员无法预知,自动化的Fuzzing技术通过超大量的测试用例生成,可以在一定程度上解决这些问题。
近年来很多领域都在探索AI的应用,模糊测试领域亦然。主要集中在测试样本生成的训练上,利用已知漏洞的样本或正常样本做训练,然后重新生成测试样本进行测试。可惜从效果上来看,这是一种高投入低产出的事情,有些还不如直接暴力变异来的高效高产。但这也不是说,AI没有价值,只是它在这方面的发展时间较短,很多东西仍亟待探索,还有待时间来证明。

开源的Fuzzing软件

1988年,在威斯康星大学Barton Miller教授的计算机实验课上,首次提出Fuzz生成器(Fuzz Generator)的概念,用于Unix,用随机数据来测试程序直至崩溃。因此,Barton Miller教授也被国外多数人尊称为”模糊测试之父”。2001年,芬兰奥卢大学公布PROTOS测试集项目的研究成果,首次将Fuzzing技术应用在网络协议的安全测试当中,2002年,在BlackHat USA黑客大会上,来自Immunity安全公司的Dave Aite公布了著名的Fuzzer工具SPIKE(现在已过时),它是基于块模板定义的网络协议测试工具。从PROTOS到SPIKE的诞生,代表着学术界与工业界对Fuzzing技术在商业与安全实战领域应用提供了有力证明。近年来,开源社区贡献了许多优秀的Fuzzing开源项目,以下选几个典型介绍一下:
AFL
基于变异的著名Fuzzer。它用大量的输入数据自动去执行程序,从而发现哪些输入能够使程序发生异常,进而分析可能存在的漏洞。
一个典型的Fuzz过程:

Sulley
Sulley是一个成熟的模糊引擎和模糊测试框架,由多个可扩展组件组成。框架的目标是不仅可以简化数据表示,而且也可以简化数据传输。Sulley是以 Monsters Inc.的生物来命名的,整体架构都是用Python写的。
Boofuzz
Boofuzz是Sulley漏洞挖掘模糊测试框架的一个分支和继承者。除了修复了许多错误,还提升了可扩展性和二次开发的便利性。相比Peach和Sulley,Boofuzz目前在GitHub继续保持活跃更新,并获得了更多的关注和使用。相比AFL的白盒插桩特性,Boofuzz更适用于广泛的漏洞挖掘。

案例展示

下面以Sulley测试 WarFTPD为案例,粗略地看一下流程。
现在先要冒充成FTP客户端,向服务器发送变形过的命令数据,尝试获得服务器的权限。它的问题出在USER和PASS命令身上,向它们传递过长的数据,就会引发栈溢出。FTP认证命令的格式如下:
USER
PASS 首先创建FTP协议框架:
from sulley import *s_initialize(“user”)s_static(“USER”)s_delim(” “)s_string(“justin”)s_static(“\r\n”)s_initialize(“pass”)s_static(“PASS”)s_delim(” “)s_string(“justin”)s_static(“\r\n”)s_initialize(“cwd”)s_static(“CWD”)s_delim(” “)s_string(“c: “)s_static(“\r\n”)s_initialize(“dele”)s_static(“DELE”)s_delim(” “)s_string(“c:\\test.txt”)s_static(“\r\n”)s_initialize(“mdtm”)s_static(“MDTM”)s_delim(” “)s_string(“C:\\boot.ini”)s_static(“\r\n”)s_initialize(“mkd”)s_static(“MKD”)s_delim(” “)s_string(“C:\\TESTDIR”)s_static(“\r\n”)
然后定义Sulley会话文件:
from sulley import *from requests import ftp # this is our ftp.py file def receive_ftp_banner(sock): sock.recv(1024) sess = sessions.session(session_filename=”audits/warftpd.session”)target = sessions.target(“192.168.244.133”, 21) target.netmon = pedrpc.client(“192.168.244.133”, 26001) target.procmon = pedrpc.client(“192.168.244.133”, 26002) target.procmon_options = { “proc_name” : “war-ftpd.exe” } # Here we tie in the receive_ftp_banner function which receives # a socket.socket() object from Sulley as its only parameter sess.pre_send = receive_ftp_banner sess.add_target(target) sess.connect(s_get(“user”)) sess.connect(s_get(“user”), s_get(“pass”)) sess.connect(s_get(“pass”), s_get(“cwd”)) sess.connect(s_get(“pass”), s_get(“dele”)) sess.connect(s_get(“pass”), s_get(“mdtm”)) sess.connect(s_get(“pass”), s_get(“mkd”)) sess.fuzz()
现在定义好了会话,下面去设置网络和监控脚本。在Sulley的主目录下可以找到 process_monitor.py和network_monitor.py两个脚本,它们分别负责网络监控和进程监控。启动进程监控:

python process_monitor.py -c C:\warftpd.crash -p war-ftpd.exe
启动网络监控:

python network_monitor.py -d 1 -f “src or dst port 21” -P C:\pcaps\
现在启动Sulley,并使用内置的Web界面观察整个fuzz过程。

如果输出是这样,说明一切正常。Sulley正在繁忙地工作。现在看看Sulley的web界面,它会提供更多信息。 用浏览器打开http://127.0.0.1:26000,将看到类似下图的结果。

不断的刷新浏览器就能看到当前fuzzing的进程,以及正在使用的请求和测试用例导致的崩溃信息。点击test case的数字,就会看到详细的崩溃信息,崩溃报告打开如下。

Sulley捕捉到了所有相关的崩溃信息,可看到两个测试用例的错误信息都是:当试图从0x021af000读取时,0042d063从线程6008的rep movsd导致访问冲突。当程序尝试访问它们没有权限访问页面的时候或者以一种不合法的方式访问内存的时候,就会产生访问违例。导致违例错误的范围很广,从内存溢出到不恰当的处理空指针都有可能。从安全角度考虑,每一个访问违例都应该仔细的审查,因为它们有可能被利用。当调试器处理访问违例的时候,需要搜集所有和违例相关的信息,栈框架,寄存器,以及引起违例的指令。接着就能够用这些信息写一个二进制的补丁文件进行修复软件。

总结

开源的模糊测试工具还有很多,各自都有不同特点。模糊测试技术不断发展,功能也越来越强大。相信在不久的将来,模糊测试技术在安全领域,尤其是漏洞挖掘方向一定会有更大的可能性和延展性。