APP下载

一种评估漏洞扫描工具效果的测试集生成方法

2018-11-09周鹏倪昀泽

科技视界 2018年18期
关键词:测试用例

周鹏 倪昀泽

【摘 要】随着网络安全技术的快速发展,越来越多的漏洞扫描、源码检测、代码审计相关软件被开发出来。很多工具号称运用符号执行、污点跟踪、机器学习等多种技术提升效率并改善性能。然而,由于缺乏大量已分类的标准化漏洞测试样本,采购人员和研究人员无法准确评估各工具扫描结果的有效性。因此,本文提出了一种基于源码的漏洞测试样本自动化生成技术。通过分析源码代码结构特征,结合已知漏洞类型,自动化将漏洞代码注入到源码中来生成大量含有漏洞的软件测试用例。本文选取了一些开源软件作为测试目标,并成功在源代码中插入多个可利用的漏洞。通过提供标准化、多样化的漏洞程序样本,为漏洞扫描工具提供统一的评判基础。

【關键词】漏洞扫描;评估测试;测试用例

中图分类号: TP309 文献标识码: A 文章编号: 2095-2457(2018)18-0174-003

DOI:10.19694/j.cnki.issn2095-2457.2018.18.078

【Abstract】With the rapid development of network security technology,more and more related softwares such as vulnerability scanning,source code detection and code auditing have been developed.Many tools claim to improve efficiency and performance by using symbolic execution,stain tracking,machine learning and many other technologies. However,due to the lack of a large number of classified standardized test samples,buyers and researchers can not accurately evaluate the effectiveness of the tool scanning results.Therefore,this paper proposes an automatic generation technology of vulnerability test samples based on source code.By analyzing the structure features of the source code and combining the known vulnerability types,the vulnerability code is automatically injected into the source code to generate a large number of software test cases containing vulnerabilities.This article selects some open source software as the test target,and successfully inserts some exploitable vulnerabilities into the source code.By providing standardized and diversified vulnerability program samples,it provides a unified evaluation basis for vulnerability scanning tools.

【Key words】Vulnerability Scanning;Evaluation and Test;Test Samples

0 引言

漏洞检测技术一直以来都是软件安全研究的一个重要领域。随着多年的研究,经过了黑盒测试、白盒测试以及当今主流的灰盒测试三个阶段,引入了符号执行、污点跟踪、代码插桩等智能化技术,也有的研究人员引入了机器学习这一门全新的技术。为了提升性能和速度,研究者不断引入新的技术,产生了大量的不同技术结合的工具框架。然而,对于一款工具框架的性能评估始终缺乏一个统一的标准。就Fuzzing工具而言,从已有的论文来[1][2]看,许多Fuzzing框架采用的测试集通常来自于两个部分:一是历史上存在漏洞的软件,二是网络上公开可供下载的最新软件。此外,不同Fuzzing技术之间的侧重点不一样,例如TaintScope[3]侧重于解决软件的校验问题,AFLFast[4]侧重于加快发现漏洞的过程,因此采用统一的、标准化的测试集有助于分析不同框架的优势和劣势,从而为下一步的研究提供参考。本文旨在通过自动化在源码中注入不同类型及深度的漏洞来生成一个标准化的漏洞测试样例。通过智能分析给定开源软件代码模块,在满足条件的代码点注入漏洞,同时保证漏洞满足:数量多、类型丰富;覆盖整个程序运行周期;尽可能与输入相关;可触发并且有触发样例;不改变程序正常功能;尽可能贴近真实。此外,我们实现了一套原型工具,可以注入常见漏洞,如缓冲区溢出、循环边界溢出,并可以注入到不同的代码深度。最终,可以提供注入漏洞数量、漏洞类型以及对应漏洞的触发样例,用于分析漏洞扫描工具实际运行效果。

1 总览

在本节中,我们将会给出本文的目标,并解释自动化漏洞注入的设计方法及原理。

1.1 目标与范围

总的来说,我们希望能够做到自动化地应用程序中注入能够影响程序安全性的漏洞。如上所述,我们专注于给漏洞挖掘程序制造测试样例。论文中涉及的软件设计方法并不仅限于源代码,也可以面向二进制程序,但在本论文中所涉及的技术将主要面向能够提供源代码的程序。

1.2 路径搜索

这一部分实际上是求解触发一条代码分支需要的输入,我们把这些输入叫做INPUTS。INPUTS将会作为整个程序分析的基础数据,好的INPUTS数据集应当做到尽可能高的覆盖率,因此本小节主要讨论的内容是如何快速有效地生成大量不同的INPUTS,不同意味着能够形成不一样的代码路径。遍历程序所有可能的路径事实上是一件很困难的事情,理论上穷举所有可能的输入才能够达到这个目标的。在本论文中,我们采用符号执行的方法获取初始的INPUTS集。如图所示,在state等于1000的条件下可以触发带漏洞的函数。但是,理论上可以触发漏洞的路径理论上是无穷多的,比如我們可以构造类似1-1+{重复一万次}+1{重复一千次}的表达式。在这一类问题的处理上目前来看没有太好的办法,只能通过大量的测试来确定一个输入是否有效。

1.3 潜在漏洞

这在真实软件中存在各种各样的漏洞,从简单的缓冲区溢出[5]、整数溢出[6],到偶然的错误如条件竞争引起的死锁,或者是在编译时由于存在未定义行为而引入的Bug[7]。本文中讨论的漏洞主要分为缓冲区溢出、整数溢出、数组边界溢出。我们简单介绍一下常见的缓冲区溢出和数组边界溢出的原理及成因。

1.缓冲区溢出:这一类的形成原因通常有几种情况:一、调用了gets,fgets等可以无限制输入的函数。二、调用read、scanf函数的时候没有对读入数据的大小进行校验,当读入长度可控成为一个较大值的时候,就会造成缓冲区溢出。三、调用了strncpy、memcpy等内存拷贝函数时没有对拷贝数据的长度进行有效校验。

2.数组边界溢出:这一类漏洞比较容易出现在循环中,通常会造成数组越界读或越界写。造成这一类漏洞的原因主要可以分为两种情况:1.在计算循环边界时没有对计算出的结果进行校验;2.计算访问数组的下标时出现了溢出等错误使得实际的数组下标超过数组空间实际大小。

产生这些漏洞的原因包括大致可以归为三点:

●没有检查参数或者检查不够严格

●循环边界检查错误或不严

●错误使用API,导致程序存在未定义行为

●基于以上产生漏洞的原因,潜在的漏洞点可以具备以下几个特征:

●调用容易产生漏洞的函数,比如read、memcpy、malloc、free等

●拥有数据校验,比如检查输入的长度是否超过了缓冲区的大小

●循环边界与输入相关,比如基于循环的数据读写操作

以上特征将会作为寻在潜在漏洞注入点的重要依据。

2 实现

在本章节中,我们将详细介绍测试集生成软件的框架结构以及设计细节,以及使用的相关工具和技术。

2.1 系统流程

总本文把整个系统的工作流程分为5个部分,依次为生成遍历样本、标记注入点、搜集运行数据、注入漏洞、POC验证。

首先使用符号执行工具KLEE来生成初始的样本集INPUTS。KLEE是一款基于源码的符号执行分析工具[8],通过KLEE我们可以构造面向特定程序的测试样例。标记注入点的目标主要是寻在潜在漏洞注入点,并插入信息收集函数,最终编译出程序P。接下来是将INPUTS作为输入交给P来解析,由于已经在源码中插入了信息收集函数,所以我们可以在程序运行结束后获取程序运行时信息。根据运行时信息,结合具体的代码特征就可以构造对应的漏洞及POC样本。构造完漏洞之后的一个步骤是测试POC样本能否使得应用程序出现错误,包括程序崩溃及内存越界读写。

2.2 标记注入点

根据小节1.3中对于三种不同漏洞类型产生原因的分析,注入点选取按照如下几个步骤进行。

2.2.1 定位潜在注入点

根据实际分析经验,我们在系统中预置了一个函数集,该函数集包含了常见的可能导致漏洞的函数,例如memcpy、malloc、strcpy等,通过搜索这一类函数在程序中的调用点,我们可以获取第一类注入点。Ⅱ.定位用于判断输入数据是否符合条件的if语句。If语句通常用于对数据进行校验,例如判断需要读入的数据长度是否超过缓冲区大小、是否满足magic校验等,这是第二类注入点。Ⅲ.第三类注入点主要针对循环中进行的数据读写操作。

2.2.2 插入信息收集函数.

主要用来收集程序运行时在所有潜在注入点产生的数据。收集的数据包括函数参数、if条件表达式涉及的变量、循环边界、完整输入数据及相关源代码信息。

2.3 注入漏洞

在收集到程序运行时数据之后,我们需要做到是判断能否将一个潜在注入点转换成漏洞。构造漏洞的方式主要有三种:一、修改malloc、strncpy等函数调用参数,构造缓冲区溢出漏洞;二、删除或弱化if判断条件;三、修改循环边界。在图示代码中,我们通过弱化if判断条件,将输入长度增加到了1000字节,从而在这里构造了一个缓冲区溢出漏洞。当然,我们还可以做一些其他的变化,例如对len进行乘法操作,使其值变为原来的2倍的方式来构造漏洞。

2.4 PoC验证

事实上并不是每一个漏洞都会导致程序崩溃,一部分内存破坏问题并不会影响程序的继续运行,在检测这一类漏洞时需要用到内存破坏检测工具ASAN(AddressSanitizer)。ASAN是广泛在开源软件(如Chrome和Firefox)中广泛使用的内存破坏检测工具。ASAN可以检测的内存破坏漏洞包括缓冲区溢出、由UAF导致的悬挂指针引用等[9]。ASAN编译时会在代码中加入检测代码,通过在程序初始化时申请的一块内存来记录某一块内存所处的状态,ASAN可以实现对每一个字节的访问检测。如果程序在运行过程中出现了崩溃或者ASAN检测到了内存溢出,则说明POC样本为有效样本,当然对应的漏洞也是可触发的。

在上述示例程序中,雖然程序中存在堆溢出漏洞,但是这个漏洞并不会导致程序崩溃,因此检测这种这种问题借助ASAN工具来完成。

3 评估

我们从性能、漏洞质量以及注入漏洞可利用性等方面对原型系统进行评估测试。

本文从GITHUB选取了三个开源项目进行测试。在实验当中,我们在代码中插入了多个漏洞,并且漏洞的数量跟随代码增加而增加。经过评估,插入的漏洞并非全部为可攻击的漏洞,例如我们在C-Crawler中插入了3个漏洞,但只有1个是能够使用POC样本触发的。

3.1 系统配置

实验环境 Ubuntu 16.04, with an Intel Core i7-6500 @ 2.59GHz, 8GB DDR3-RAM @ 1600MHz and a 512GB SSD。

3.2 系统性能

在实验中,我们尝试在三个开源代码中注入漏洞,我们选择了C-interpreter(一个简易版C语言解释器)、linux-coreutils(linux下基本命令的实现代码,从中选取了base64、ls等部分命令进行测试)、C-Crawler(一个自己开发的C语言爬虫项目)。

正如我们在Table 2中能够看到的,由于采用了符号执行的方法来生成测试样例,整个系统在路径搜索阶段花费了大量的时间。需要注意的是,运行所需的时间并不一定和代码量相关。例如,C-interpreter代码量最少,但是由于其中涉及大量重复性的解析工作,所以生成测试样例的时间反而最长。

4 结论

本文提出并设计了一种基于符号执行的漏洞自动注入方案,并且该原型系统在选择的开源工程中成功插入了多个漏洞,其中包含多个可以用漏洞。当然,该原型系统依然存在较大局限性,例如符号执行在路径搜索时普遍面临的路径爆炸问题,并且符号执行本身也需要对特殊运行环境进行适配。

目前,我们仅实现了在源码层面的简单漏洞注入,后续希望能够实现在二进制层面的漏洞注入,同时也希望本文能够促进基于源码的软件漏洞自动化挖掘工具的研究工作。

【参考文献】

[1]Stephens N,Grosen J,Salls C,et al.Driller:Augmenting Fuzzing Through Selective Symbolic Execution[C]//Network and Distributed System Security Symposium.2016.

[2]Rawat S,Jain V,Kumar A,et al.VUzzer:Application-aware Evolutionary Fuzzing[C]// NDSS.2017.

[3]Bhme M,Pham V T,Roychoudhury A.Coverage-based Greybox Fuzzing as Markov Chain[J].IEEE Transactions on Software Engineering,2017,PP(99):1-1.

[4]Wang T,Wei T,Gu G,et al.TaintScope:A Checksum-Aware Directed Fuzzing Tool for Automatic Software Vulnerability Detection[C]// IEEE Symposium on Security and Privacy.IEEE Computer Society,2010:497-512.

[5]Aleph O.Smashing the stack for fun and profit[J].http://www.shmoo.com/phrack/Phrack49/p49-14,1996.

[6]Dietz W,Li P,Regehr J,et al.Understanding integer overflow in C/C++[J].ACM Transactions on Software Engineering and Methodology (TOSEM),2015,25(1):2.

[7]Wang X,Chen H,Cheung A,et al.Undefined behavior:what happened to my code?[C]//Proceedings of the Asia-Pacific Workshop on Systems.ACM,2012:9.

[8]Cadar C,Dunbar D,Engler D.KLEE:unassisted and automatic generation of high-coverage tests for complex systems programs[C]// Usenix Conference on Operating Systems Design and Implementation.USENIX Association,2009:209-224.

[9]Serebryany K,Bruening D,Potapenko A,et al.AddressSanitizer:A Fast Address Sanity Checker[C]//USENIX Annual Technical Conference.2012:309-318.

猜你喜欢

测试用例
基于SmartUnit的安全通信系统单元测试用例自动生成
浅析基于因果图法软件测试用例的设计
基于MBD模型自动生成测试用例的软件测试方法
基于混合遗传算法的回归测试用例集最小化研究
基于需求模型的航天软件测试用例生成方法
基于依赖结构的测试用例优先级技术
电动汽车整车控制软件测试用例设计方法及应用
软件测试用例执行优化研究
浅析软件测试用例管理
软件回归测试用例选取方法研究