实施例1
根据本发明实施例,提供了一种安全漏洞检测方法的实施例,需要说明的是,在附图的流程图示出的步骤可以在诸如一组计算机可执行指令的计算机系统中执行,并且,虽然在流程图中示出了逻辑顺序,但是在某些情况下,可以以不同于此处的顺序执行所示出或描述的步骤。
根据本发明实施例,提供了一种安全漏洞检测方法,如图2所示,该检测方法可以通过如下步骤实现:
步骤S202:记录在待测试程序执行第一测试用例的过程中产生的测试信息,其中,测试信息包括测试指令。
步骤S204:从测试指令中获取待测试程序执行第一测试用例时的执行逻辑。
步骤S206:基于执行逻辑生成第二测试用例。
步骤S208:在待测试程序中执行第二测试用例。
采用本发明实施例,通过记录待测试程序在执行第一测试用例时的测试信息,并从其中的测试指令中确定出待测试程序的执行逻辑,按照该执行逻辑生成新的测试用例(即上述实施例中的测试用例),然后在待测试程序中执行第二测试用例。通过上述的实施例,是通过第一测试用例确定的第二测试用例,第二测试用例是根据待测试程序的执行逻辑生成的,具有很强的针对性,可以在第一测试用例的基础上执行更多的程序逻辑,从而可以有效地覆盖更多的代码路径,有效触及存在漏洞的代码逻辑,解决了现有技术中黑盒挖掘安全漏洞中使用的测试用例无法有效覆盖待测试程序的代码路径,漏掉很多漏洞,漏检率高的问题,实现了有效覆盖更多的待测试程序中的代码路径,减少安全漏洞的漏检率的效果。
其中,本发明实施例中的测试用例指:为某个安全漏洞挖掘目标而编制(如预先设置好)的一组测试输入、执行条件以及预期结果,以便测试待测试产品的代码路径或核实是否满足某个特定需求的字符串或数据包。
上述实施例中的第一测试用例可以为在开始进行自动化漏洞挖掘前,预先设置好的一些固定的基准测试用例,该测试用例可以作为后续第一次执行、监控、特征匹配和约束求解的输入来源。
在一个实施例中,可以循环执行上述的实施例,具体地,在待测试程序执行第二测试用例的过程中,记录待测试程序执行第二测试用例的测试信息,从执行第二测试用例的测试信息中获取新的执行逻辑,然后按照该新的执行逻辑生成第三测试用例,使用待测试程序执行第三测试用例,如此循环往复,直至将待测试程序中的执行逻辑全部获取。
通过对上述实施例的循环执行,可以将一个标准的测试用例进行若干次的变换和还原(即上述实施例中生成新的测试用例的过程),能够得到符合待测试程序执行逻辑的测试用例,通过结合使用符合待测试程序执行逻辑的多个测试用例,可以发现传统的漏洞自动化挖掘系统所无法发现的大量漏洞,大大提高安全漏洞检测的完整率。
本发明的上述实施例可以应用于不同的客户端上,也可以应用于相同的客户端上,即,在使用上述实施例时,可以通过客户端1向客户端2上的待测试程序输入测试用例(如第一测试用例或第二测试用例),也可以在同一客户端1上向待测试程序输入测试用例,以对待测试程序进行安全漏洞测试。
下面以在同一客户端1上向待测试程序输入测试用例,以对待测试程序进行安全漏洞测试为例,详细介绍本发明。
图3中示出了待测试程序(如:QQ应用程序)中存在漏洞的一段代码,在图3示出的代码中程序执行到底20行代码,即确认待测试程序中出现了安全漏洞。
具体地,如图3所示,在输入为“http://a”或“ftp://a”时,将verified(变量)标记为“true(真)”,在verified=true的情况下,调用strcpy(为应用程序编程接口API的名称)拷贝输入的字符串,待测试产品执行“调用strcpy拷贝输入的字符串”,则认为待测试程序出现安全漏洞。可是现有技术中使用的大量测试用例(如“aaaa”)中在代码的第7行就无法执行下去了,因为输入“aaaa”无法满足判断条件“http://”,则使用标准的测试用例“aaaa”无法发现待测试产品中存在“调用strcpy拷贝输入的字符串”的安全漏洞。
通过本发明上述实施例,在向待测试程序(如QQ应用程序)提交第一测试用例(如“aaaa”)之后,待测试程序执行第一测试用例,在执行到如图3所示代码示例中的第7行时,由于输入为“aaaa”则无法再继续执行该步骤之后的逻辑,通过上述实施例,在漏洞挖掘开始后,系统可以在将初始测试用例提交到待测试程序之后,开始通过调用软件调试API监控待测试程序执行第一测试用例的每一个步骤,记录下待测试程序执行第一测试用例的过程中产生的所有的数据(可以为上述实施例中的测试信息),然后从测试信息中提取测试指令,并根据该测试指令确定执行逻辑为:第一个字节input(输入)等于h。在该示例中(第一测试用例为“aaaa”),第一个字节为“a”,获取该执行逻辑“input等于h”,根据该执行逻辑生成第二测试用例,在待测试程序中执行第二测试用例,然后循环执行上述步骤,直至获取到待测试程序中的所有执行逻辑,停止生成新的测试用例。
具体地,从测试指令中获取待测试程序执行第一测试用例时的执行逻辑可以通过如下方法实现:从测试信息中提取处理器11的所有执行指令;在该执行指令为比较第一测试用例的输入与待测试程序中的预定义的常量的指令的情况下,确定该执行指令为比较指令(也即上述实施例中的测试指令),然后从该测试指令中提取用于比较的预定义的常量和比较函数(该比较函数可以为等于、大于或小于等的数学比较函数,也可以是与、非等的逻辑比较函数),确定待测试程序的执行逻辑。
例如,从测试信息中确定与处理器11相关的指令,如果该指令提取了第一测试用例中的第一字节的“a”将其保存在存储器13的第一子存储器中,并从待测试程序的固有逻辑中获取预定义好的常量“h”保存在第二子存储器中,比较两个存储器中的值是否相同(此处的比较函数即为相等的比较函数),则将该指令确定为比较指令,也即确认该指令中包括了执行逻辑,从该指令中提取“第一个字节input等于h”的执行逻辑。
上述实施例中涉及的获取执行逻辑的方法仅作示例说明,执行上述步骤的目的仅为确定待测试程序的执行逻辑,通过执行逻辑生成新的测试用例,按照待测试程序所有的执行逻辑生成的测试用例针对性强,可以覆盖待测试程序的所有代码路径,从而可以发现所有的安全漏洞。
在图4所示的一个可选的实施例中,步骤S203,从测试指令中获取待测试程序执行第一测试用例时的执行逻辑可以包括:从测试指令中提取待测试程序的一个或多个约束表达式,其中,约束表达式用于表示待测试程序中的逻辑运算关系;步骤S206,基于执行逻辑生成第二测试用例包括:生成满足一个或多个约束表达式的第二测试用例。
如图4所示,该实施例可以通过如下步骤实现:
步骤S402:记录在待测试程序执行第一测试用例的过程中产生的测试信息,其中,测试信息包括测试指令。
其中,该步骤S402的实现方法与上述的步骤S202的实现方法一致,在此不再赘述。
步骤S404:从测试指令中提取待测试程序的一个或多个约束表达式,其中,约束表达式用于表示待测试程序中的逻辑运算关系。
具体地,从处理器的测试指令中提取的可以为约束条件(该约束条件可以为上述的处理器11比较第一子存储器与第二子存储器的当前值的一行或一段代码),该约束条件可以使用约束表达式来表示,例如,一段程序逻辑要求输入input<3(即约束条件),可以将这个约束条件转换成数学上的约束表达式。
其中,约束条件是若干个位置量(或变量)之间简单的逻辑关系,每个变量都在给定的论域内取值。例如,如果input为输入且代表一个数字,那么典型的约束如:input<3。
步骤S406:生成满足一个或多个约束表达式的第二测试用例。
步骤S408:在待测试程序中执行第二测试用例。
其中,该步骤S408的实现方法与上述的步骤S208的实现方法一致,在此不再赘述。
表1示出了图3所示代码示例循环执行上述实施例的测试用例变换图。表1中的执行逻辑使用约束表达式表示。
第一测试用例 |
执行逻辑 |
第二测试用例 |
循环执行次数 |
aaaa |
Input[0]=h |
haaa |
0 |
haaa |
Input[1]=t |
htaa |
1 |
htaa |
Input[2]=t |
htta |
2 |
htta |
Input[3]=p |
http |
3 |
http |
Input[0]=f |
ftta |
4 |
ftta |
Input[1]=t |
ftta |
5 |
ftta |
Input[2]=p |
ftpa |
6 |
ftta |
Input[3]=null(空) |
ftp |
7 |
由表1可知,循环执行7次本发明的上述实施例,按照待测试程序的可以将安全漏洞调用strcpy拷贝输入的字符串”检测出来,而在现有技术中通过大量的“aaaa”测试用例无法检测出该安全漏洞。
在表1所示的实施例中,使用每次执行第一测试用例获取一个执行逻辑为示例,在实际的安全漏洞检测的过程中,获取到的执行逻辑可能为一个或多个(也即执行第一测试用例的过程中进行一次或多次if判断,即条件判断),每个执行逻辑生成一个对应的约束表达式。在一个第一测试用例在待测试程序中完整执行完毕后,在每个约束时(在出现每个执行逻辑时)会产生一条约束表达式,从而可以得到一个约束表达式的集合(该集合中可以包括一个或多个约束表达式)。通过这个约束表达式的集合可以确定当前的测试用例已经走到和没有走到的待测试程序中的程序逻辑。
需要进一步说明的是,上述的步骤S406,生成满足一个或多个约束表达式的第二测试用例可以通过如下方法实现:生成取值满足逻辑运算关系的第二测试用例。
具体地,在上述实施例中,获取一个或多个约束表达式的集合之后,可以对约束表达式的集合中的约束表达式进行约束求解得到符合所有约束表达式的解,然后使用该解还原成第二测试用例。
其中,本发明实施例中的代码逻辑也可以理解为约束表达式的集合(或者上述实施例中的约束条件的集合,约束条件的集合或者约束表达式的集合只是约束的表现形式不同,其代表的含义是相同的),由待测试程序中所有约束所组成的一个集合,它代表着待测试程序的逻辑组织结构;约束求解,即运用集合的理论,对一个约束集合中的所有约束(表达式)进行运算,找出满足集合中所有约束条件的解。
例如,存在一个约束集合为{input1>3,input2<10,input1+input2=7},那么对这个约束集合的解为:input1=4,input2=3。
在本发明的上述实施例中,可以采用约束求解引擎Z3对约束集合进行求解。
在一个可选的实施例中,在通过数学手段求得当前约束集合中满足每个约束表达式的所有解后,将这每一个解还原成一个新的测试用例(如上述实施例中的第二测试用例)。然后将这些新的、更有效、能把执行流程带入新的代码路径的测试用例(如第二测试用例)送入待测试程序,进行下一轮的执行逻辑的发现和约束集合的求解,以及更新测试用例的过程中。
在上述实施例中,通过记录的测试信息,确定待测试程序的代码逻辑,通过导出待测试程序的代码逻辑,汇总成一系列的约束表达式的集合,然后通过数学中集合的理论,对这个约束表达式的集合进行约束求解,得到满足待测试程序的每个执行逻辑时约束的解,并将这些约束的解还原成影响待测试程序的代码逻辑的测试用例。通过上述实施例,由于每个生成的测试用例均是针对待测试程序的一种代码逻辑准备,跑完所有生成的测试用例后,即可极大的提升自动化挖掘漏洞时测试用例的覆盖程度,大大的提升发现漏洞的数量,降低安全漏洞的漏检率。
在本发明的一个可选的实施例中,生成满足一个或多个约束表达式的第二测试用例可以包括:检测预设约束数据集合中是否存在一个或多个约束表达式,其中,预设约束数据集合中包括一个或多个预设的约束表达式;在预设约束数据集合中不存在一个或多个约束表达式中任意一个约束表达式的情况下,生成满足不存在于预设约束数据集合中的约束表达式的第二测试用例,并将该约束表达式保存入预设约束数据集合;在预设约束数据集合中存在所有约束表达式的情况下,结束安全漏洞检测流程。
在本发明的实施例中,每得到一个新的执行逻辑(如约束表达式)之后,均将其保存入预设约束数据集合中。具体地,每得到一个约束表达式,检测预设约束数据集合中是否存在该约束表达式,在预设约束数据集合中存在该约束表达式的情况下,确认已经完全找到待测试程序的执行逻辑,测试用例完全覆盖待测试程序的程序逻辑,已经跑完所有生成的测试用例,极大的提升自动化挖掘漏洞时测试用例的覆盖程度,大大的提升发现漏洞的数量。
如图5所示,该实施例可以通过如下步骤实现:
步骤S501:获取第一测试用例。
具体地,在开始进行自动化漏洞挖掘前,可以将固定的基准测试用例,作为后续第一次执行、监控、特征匹配和约束求解的输入来源。在该实施例中,第一次执行测试用例时,可以将预设好的测试用例作为第一测试用例。
步骤S502:在待测试程序中执行第一测试用例。
步骤S503:记录待测试程序在执行第一测试用例的过程中产生的测试信息。
其中,该步骤S503的实现方法与步骤S402和步骤S202的实现方法一致,在此不再赘述。
步骤S504:从测试信息的测试指令中提取待测试程序的一个或多个约束表达式。
其中,该步骤S504的实现方法与步骤S404的实现方法一致,在此不再赘述。
步骤S505:检测预设约束数据集合中是否存在一个或多个约束表达式。
其中,在预设约束数据集合中不存在一个或多个约束表达式中的任意一个约束表达式的情况下,执行步骤S506;在预设约束数据集合中存在一个或多个约束表达式中的全部约束表达式的情况下,执行步骤S507。
具体地,在每一个第一测试用例在待测试程序中完整执行完毕之后,均可以在每个约束时产生一条约束表达式,从而可以得到一个约束表达式的集合。检测该约束表达式的集合中的所有约束表达式是否均存在于预设约束数据集合,如果该约束表达式的集合中的任意一个约束表达式均存在于预设约束数据集合,则确定生成的测试用例已经覆盖待测试程序的所有执行逻辑,不再生成新的测试用例,结束该此安全漏洞检测的流程;如果该约束表达式的集合中的任意一个约束表达式不存在于预设约束数据集合,则确定生成的测试用例没有完全覆盖待测试程序的所有执行逻辑,生成满足不存在于预设约束数据集合的约束表达式的新的测试用例(即第二测试用例),继续执行该第二测试用例,直至得到的约束表达式均存在于预设约束数据集合。
步骤S506:生成满足不存在于预设约束数据集合的约束表达式的第二测试用例。
具体地,在执行步骤S506的同时,可以将该不存在于预设约束数据集合的约束表达式保存入预设约束数据集合。
在生成第二测试用例之后,将该新生成的第二测试用例作为下一次循环的第一测试用例,返回执行步骤S502,直至得到的约束表达式均存在于预设约束数据集合。
其中,第二生成子模块413生成满足不存在于预设约束数据集合中的约束表达式的第二测试用例时可以使用与上述相同的生成方法,即生成取值满足不存在于预设约束数据集合中的约束表达式的逻辑运算关系的第二测试用例。
通过上述实施例,在这个循环不停走下去的过程中,测试用例能够覆盖待测试程序中趋近于100%的代码逻辑,并能够挖掘待测试程序中的所有漏洞。
步骤S507:结束安全漏洞检测流程。
如图6所示的一种可选的上述实施例中,测试信息还可以包括:待测试程序在执行第一测试用例的过程中调用的应用程序编程接口API的信息,如图6所示,该实施例可以包括如下步骤:
步骤S601:记录在待测试程序执行第一测试用例的过程中产生的测试信息。
步骤S602:获取测试信息中待测试程序在执行第一测试用例的过程中调用的应用程序编程接口API的信息。
其中,调用的应用程序编程接口API的信息可以包括API的名称、调用API的时间等信息。
步骤S603:将待测试程序在执行第一测试用例的过程中调用的API与预设的危险API进行匹配处理,其中,预设的危险API为预先获取的用于触发安全漏洞的API。
其中,该实施例中进行匹配处理时,可以通过待测试程序调用的API的名称与预设的危险API的名称进行匹配处理,如果调用的API中有名称与预设的危险API的名称一致的API,则确定匹配到待测试程序调用的API中存在与预设的危险API相匹配的第一API。
具体地,上述实施例中,调用预设的危险API即可触发安全漏洞。
步骤S604:在待测试程序调用的API中存在与预设的危险API相匹配的第一API的情况下,确认待测试程序中存在安全漏洞。
其中,在待测试程序调用的API中不存在与预设的危险API相匹配的第一API的情况下,确认待测试程序中不存在安全漏洞。
步骤S605:获取待测试程序调用第一API的调用信息,生成漏洞报告。
具体地,可以从测试信息中提取与调用该第一API相关的调用信息,使用该调用信息生成漏洞报告。
需要说明的是,本发明上述实施例中确定待测试程序中是否存在安全漏洞的过程与依据执行逻辑生成第二测试用例的过程可以是并行处理的。
下面结合附图7,以在同一客户端实现上述方法的角度详细介绍本发明,如图7所示,可以通过如下步骤实现本发明的上述实施例:
步骤S701:获取当前测试用例。
具体地,在开始进行自动化漏洞挖掘前,可以将固定的基准测试用例,作为后续第一次执行、监控、特征匹配和约束求解的输入来源。
步骤S702:在待测试程序中执行当前测试用例。
步骤S703:记录待测试程序在执行当前测试用例的过程中产生的测试信息。
其中,上述步骤S701至步骤S703的实现方法与步骤S501至步骤S503的实现方法相同,在此不再赘述。
步骤S704:获取测试信息中待测试程序在执行当前测试用例的过程中调用的应用程序编程接口API的信息。
其中,调用的应用程序编程接口API的信息可以包括API的名称、调用API的时间等信息。
步骤S705:将待测试程序在执行当前测试用例的过程中调用的API与预设的危险API进行匹配处理,其中,预设的危险API为预先获取的用于触发安全漏洞的API。
步骤S706:在待测试程序调用的API中存在与预设的危险API相匹配的第一API的情况下,确认待测试程序中存在安全漏洞。
其中,在待测试程序调用的API中不存在与预设的危险API相匹配的第一API的情况下,确认待测试程序中不存在安全漏洞。
步骤S707:获取待测试程序调用第一API的调用信息,生成漏洞报告。
其中,上述步骤S704至步骤S707的实现方法与步骤S602至步骤S605的实现方法相同,在此不再赘述。
步骤S708:从测试信息的测试指令中提取待测试程序的一个或多个约束表达式。
步骤S709:检测预设约束数据集合中是否存在一个或多个约束表达式。
其中,在预设约束数据集合中不存在一个或多个约束表达式中的任意一个约束表达式的情况下,执行步骤S710;在预设约束数据集合中存在一个或多个约束表达式中的全部约束表达式的情况下,执行步骤S711。
步骤S710:生成满足不存在于预设约束数据集合的约束表达式的下一个的测试用例。
具体地,在执行步骤S710的同时,可以将该不存在于预设约束数据集合的约束表达式保存入预设约束数据集合。
在生成第二测试用例之后,将该新生成的下一个的测试用例作为下一次循环的当前测试用例,返回执行步骤S702,直至得到的约束表达式均存在于预设约束数据集合。
通过上述实施例,在这个循环不停走下去的过程中,测试用例能够覆盖待测试程序中趋近于100%的代码逻辑,并能够挖掘待测试程序中的所有漏洞。
步骤S711:结束安全漏洞检测流程。
采用本发明实施例,通过获取待测试产品的代码逻辑,汇总成一系列的约束集合,然后通过数学中集合的理论,对这个集合进行约束求解,得到满足产品每个逻辑时约束的解,并将这些约束的解还原成影响产品代码逻辑的新的测试用例,在实际应用中,代码覆盖率可达100%,较传统黑盒漏洞挖掘模块提升超过9倍,并且发现数量较传统黑盒漏洞挖掘模块提升近3倍,大大提高了安全漏洞的检测量,有效的减少了待测试安全漏洞的数量。
上述的约束求解方法,仅是通过执行逻辑获取新的测试用例的一种可用的实现方法,没有约束求解系统,也通过可以进行自动化的漏洞挖掘,不过合理的约束求解方案效果要好很多。
需要说明的是,对于前述的各方法实施例,为了简单描述,故将其都表述为一系列的动作组合,但是本领域技术人员应该知悉,本发明并不受所描述的动作顺序的限制,因为依据本发明,某些步骤可以采用其他顺序或者同时进行。其次,本领域技术人员也应该知悉,说明书中所描述的实施例均属于优选实施例,所涉及的动作和模块并不一定是本发明所必须的。
通过以上的实施方式的描述,本领域的技术人员可以清楚地了解到根据上述实施例的方法可借助软件加必需的通用硬件平台的方式来实现,当然也可以通过硬件,但很多情况下前者是更佳的实施方式。基于这样的理解,本发明的技术方案本质上或者说对现有技术做出贡献的部分可以以软件产品的形式体现出来,该计算机软件产品存储在一个存储介质(如ROM/RAM、磁碟、光盘)中,包括若干指令用以使得一台终端设备(可以是手机,计算机,服务器,或者网络设备等)执行本发明各个实施例所述的方法。
实施例2
根据本发明实施例,还提供了一种安全漏洞检测装置,该装置可以通过在实施例中涉及的方法来实现,下面对本申请的实施过程进行详细描述。
图8是根据本发明实施例的安全漏洞检测装置的结构示意图。
如图8所示,该装置可以包括:记录模块20、第一获取模块30、测试用例生成模块40以及执行模块50。
其中,记录模块20,用于记录在待测试程序执行第一测试用例的过程中产生的测试信息,其中,测试信息包括测试指令。
第一获取模块30,用于从测试指令中获取待测试程序执行第一测试用例时的执行逻辑。
测试用例生成模块40,用于基于执行逻辑生成第二测试用例。
执行模块50,用于在待测试程序中执行第二测试用例。
采用本发明实施例,通过记录待测试程序在执行第一测试用例时的测试信息,并从其中的测试指令中确定出待测试程序的执行逻辑,按照该执行逻辑生成新的测试用例(即上述实施例中的测试用例),然后在待测试程序中执行第二测试用例。通过上述的实施例,是通过第一测试用例确定的第二测试用例,第二测试用例是根据待测试程序的执行逻辑生成的,具有很强的针对性,可以在第一测试用例的基础上执行更多的程序逻辑,从而可以有效地覆盖更多的代码路径,有效触及存在漏洞的代码逻辑,解决了现有技术中黑盒挖掘安全漏洞中使用的测试用例无法有效覆盖待测试程序的代码路径,漏掉很多漏洞,漏检率高的问题,实现了有效覆盖更多的待测试程序中的代码路径,减少安全漏洞的漏检率的效果。
其中,本发明实施例中的测试用例指:为某个安全漏洞挖掘目标而编制(如预先设置好)的一组测试输入、执行条件以及预期结果,以便测试待测试产品的代码路径或核实是否满足某个特定需求的字符串或数据包。
上述实施例中的第一测试用例可以为在开始进行自动化漏洞挖掘前,预先设置好的一些固定的基准测试用例,该测试用例可以作为后续第一次执行、监控、特征匹配和约束求解的输入来源。
在一个实施例中,可以循环执行上述的实施例,具体地,在待测试程序执行第二测试用例的过程中,记录待测试程序执行第二测试用例的测试信息,从执行第二测试用例的测试信息中获取新的执行逻辑,然后按照该新的执行逻辑生成第三测试用例,使用待测试程序执行第三测试用例,如此循环往复,直至将待测试程序中的执行逻辑全部获取。
通过对上述实施例的循环执行,可以将一个标准的测试用例进行若干次的变换和还原(即上述实施例中生成新的测试用例的过程),能够得到符合待测试程序执行逻辑的测试用例,通过结合使用符合待测试程序执行逻辑的多个测试用例,可以发现传统的漏洞自动化挖掘系统所无法发现的大量漏洞,大大提高安全漏洞检测的完整率。
本发明的上述实施例可以应用于不同的客户端上,也可以应用于相同的客户端上,即,在使用上述实施例时,可以通过客户端1向客户端2上的待测试程序输入测试用例(如第一测试用例或第二测试用例),也可以在同一客户端1上向待测试程序输入测试用例,以对待测试程序进行安全漏洞测试。
下面以在同一客户端1上向待测试程序输入测试用例,以对待测试程序进行安全漏洞测试为例,详细介绍本发明。
图3中示出了待测试程序(如:QQ应用程序)中存在漏洞的一段代码,在图3示出的代码中程序执行到底20行代码,即确认待测试程序中出现了安全漏洞。
具体地,如图3所示,在输入为“http://a”或“ftp://a”时,将verified(变量)标记为“true(真)”,在verified=true的情况下,调用strcpy(为应用程序编程接口API的名称)拷贝输入的字符串,待测试产品执行“调用strcpy拷贝输入的字符串”,则认为待测试程序出现安全漏洞。可是现有技术中使用的大量测试用例(如“aaaa”)中在代码的第7行就无法执行下去了,因为输入“aaaa”无法满足判断条件“http://”,则使用标准的测试用例“aaaa”无法发现待测试产品中存在“调用strcpy拷贝输入的字符串”的安全漏洞。
通过本发明上述实施例,在向待测试程序(如QQ应用程序)提交第一测试用例(如“aaaa”)之后,待测试程序执行第一测试用例,在执行到如图3所示代码示例中的第7行时,由于输入为“aaaa”则无法再继续执行该步骤之后的逻辑,通过上述实施例,在漏洞挖掘开始后,系统可以在将初始测试用例提交到待测试程序之后,开始通过调用软件调试API监控待测试程序执行第一测试用例的每一个步骤,记录下待测试程序执行第一测试用例的过程中产生的所有的数据(可以为上述实施例中的测试信息),然后从测试信息中提取测试指令,并根据该测试指令确定执行逻辑为:第一个字节input(输入)等于h。在该示例中(第一测试用例为“aaaa”),第一个字节为“a”,获取该执行逻辑“input等于h”,根据该执行逻辑生成第二测试用例,在待测试程序中执行第二测试用例,然后循环执行上述步骤,直至获取到待测试程序中的所有执行逻辑,停止生成新的测试用例。
具体地,从测试指令中获取待测试程序执行第一测试用例时的执行逻辑可以通过如下方法实现:从测试信息中提取处理器11的所有执行指令;在该执行指令为比较第一测试用例的输入与待测试程序中的预定义的常量的指令的情况下,确定该执行指令为比较指令(也即上述实施例中的测试指令),然后从该测试指令中提取用于比较的预定义的常量和比较函数(该比较函数可以为等于、大于或小于等的数学比较函数,也可以是与、非等的逻辑比较函数),确定待测试程序的执行逻辑。
例如,从测试信息中确定与处理器11相关的指令,如果该指令提取了第一测试用例中的第一字节的“a”将其保存在存储器13的第一子存储器中,并从待测试程序的固有逻辑中获取预定义好的常量“h”保存在第二子存储器中,比较两个存储器中的值是否相同(此处的比较函数即为相等的比较函数),则将该指令确定为比较指令,也即确认该指令中包括了执行逻辑,从该指令中提取“第一个字节input等于h”的执行逻辑。
通过执行逻辑生成新的测试用例,按照待测试程序所有的执行逻辑生成的测试用例针对性强,可以覆盖待测试程序的所有代码路径,从而可以发现所有的安全漏洞。
在本发明的上述实施例中,第一获取模块30可以包括:提取模块31(如图9所示),用于从测试指令中提取待测试程序的一个或多个约束表达式,其中,约束表达式用于表示待测试程序中的逻辑运算关系;测试用例生成模块40可以包括:第一生成模块41(如图9所示),用于生成满足一个或多个约束表达式的第二测试用例。
具体地,从处理器的测试指令中提取的可以为约束条件(该约束条件可以为上述的处理器11比较第一子存储器与第二子存储器的当前值的一行或一段代码),该约束条件可以使用约束表达式来表示,例如,一段程序逻辑要求输入input<3(即约束条件),可以将这个约束条件转换成数学上的约束表达式。
其中,约束条件是若干个位置量(或变量)之间简单的逻辑关系,每个变量都在给定的论域内取值。例如,如果input为输入且代表一个数字,那么典型的约束如:input<3。
表1示出了图3所示代码示例循环执行上述实施例的测试用例变换图。由表1可知,循环执行7次本发明的上述实施例,按照待测试程序的可以将安全漏洞调用strcpy拷贝输入的字符串”检测出来,而在现有技术中通过大量的“aaaa”测试用例无法检测出该安全漏洞。
需要进一步说明的是,第一生成模块可以包括:第一生成子模块,用于生成取值满足逻辑运算关系的第二测试用例。
具体地,在上述实施例中,获取一个或多个约束表达式的集合之后,可以对约束表达式的集合中的约束表达式进行约束求解得到符合所有约束表达式的解,然后使用该解还原成第二测试用例。
其中,本发明实施例中的代码逻辑也可以理解为约束表达式的集合(或者上述实施例中的约束条件的集合,约束条件的集合或者约束表达式的集合只是约束的表现形式不同,其代表的含义是相同的),由待测试程序中所有约束所组成的一个集合,它代表着待测试程序的逻辑组织结构;约束求解,即运用集合的理论,对一个约束集合中的所有约束(表达式)进行运算,找出满足集合中所有约束条件的解。
在本发明的上述实施例中,可以采用约束求解引擎Z3对约束集合进行求解。
在上述实施例中,通过记录的测试信息,确定待测试程序的代码逻辑,通过导出待测试程序的代码逻辑,汇总成一系列的约束表达式的集合,然后通过数学中集合的理论,对这个约束表达式的集合进行约束求解,得到满足待测试程序的每个执行逻辑时约束的解,并将这些约束的解还原成影响待测试程序的代码逻辑的测试用例。通过上述实施例,由于每个生成的测试用例均是针对待测试程序的一种代码逻辑准备,跑完所有生成的测试用例后,即可极大的提升自动化挖掘漏洞时测试用例的覆盖程度,大大的提升发现漏洞的数量,降低安全漏洞的漏检率。
在本发明的一个可选的实施例中,如图9所示,第一生成模块41可以包括:检测模块411,用于检测预设约束数据集合中是否存在一个或多个约束表达式,其中,预设约束数据集合中包括一个或多个预设的约束表达式;第二生成子模块413,用于在预设约束数据集合中不存在一个或多个约束表达式中任意一个约束表达式的情况下,生成满足不存在于预设约束数据集合中的约束表达式的第二测试用例;保存模块415,用于将约束表达式保存入预设约束数据集合;结束模块417,用于在预设约束数据集合中存在所有约束表达式的情况下,结束安全漏洞检测流程。
其中,第二生成子模块413生成满足不存在于预设约束数据集合中的约束表达式的第二测试用例时可以使用与第一生成子模块相同的生成的方法,即生成取值满足不存在于预设约束数据集合中的约束表达式的逻辑运算关系的第二测试用例。
如图9所示,在执行模块50开始之前,可以通过第二获取模块90获取初始的第一测试用例;并且在图9中示出的执行第一测试用例和执行第二测试用例可以使用相同的执行模块50。
在本发明的实施例中,每得到一个新的执行逻辑(如约束表达式)之后,均将其保存入预设约束数据集合中。具体地,每得到一个约束表达式,检测预设约束数据集合中是否存在该约束表达式,在预设约束数据集合中存在该约束表达式的情况下,确认已经完全找到待测试程序的执行逻辑,测试用例完全覆盖待测试程序的程序逻辑,已经跑完所有生成的测试用例,极大的提升自动化挖掘漏洞时测试用例的覆盖程度,大大的提升发现漏洞的数量。
在一个实施例,测试信息还可以包括:待测试程序在执行第一测试用例的过程中调用的应用程序编程接口API的信息,安全漏洞检测装置还包括:匹配模块60,用于将待测试程序在执行第一测试用例的过程中调用的API与预设的危险API进行匹配处理,其中,预设的危险API为预先获取的用于触发安全漏洞的API;确定模块70,用于在待测试程序调用的API中存在与预设的危险API相匹配的第一API的情况下,确认待测试程序中存在安全漏洞;报告生成模块80,用于获取待测试程序调用第一API的调用信息,生成漏洞报告。
其中,该实施例中进行匹配处理时,可以通过待测试程序调用的API的名称与预设的危险API的名称进行匹配处理,如果调用的API中有名称与预设的危险API的名称一致的API,则确定匹配到待测试程序调用的API中存在与预设的危险API相匹配的第一API。
具体地,上述实施例中,调用预设的危险API即可触发安全漏洞。
在待测试程序调用的API中存在与预设的危险API相匹配的第一API的情况下,确认待测试程序中存在安全漏洞;在待测试程序调用的API中不存在与预设的危险API相匹配的第一API的情况下,确认待测试程序中不存在安全漏洞。
需要说明的是,本发明上述实施例中确定待测试程序中是否存在安全漏洞的过程与依据执行逻辑生成第二测试用例的过程可以是并行处理的。
通过上述实施例,在这个循环不停走下去的过程中,测试用例能够覆盖待测试程序中趋近于100%的代码逻辑,并能够挖掘待测试程序中的所有漏洞。
本实施例中所提供的各个模块的实现方法与上述的方法实施例所提供的使用方法相同、应用场景也可以相同。当然,需要注意的是,上述模块涉及的方案可以不限于上述实施例中的内容和场景,且上述模块可以运行在计算机终端或移动终端,可以通过软件或硬件实现。
上述本发明实施例序号仅仅为了描述,不代表实施例的优劣。
在本发明的上述实施例中,对各个实施例的描述都各有侧重,某个实施例中没有详述的部分,可以参见其他实施例的相关描述。
在本申请所提供的几个实施例中,应该理解到,所揭露的客户端,可通过其它的方式实现。其中,以上所描述的装置实施例仅仅是示意性的,例如所述单元的划分,仅仅为一种逻辑功能划分,实际实现时可以有另外的划分方式,例如多个单元或组件可以结合或者可以集成到另一个系统,或一些特征可以忽略,或不执行。另一点,所显示或讨论的相互之间的耦合或直接耦合或通信连接可以是通过一些接口,单元或模块的间接耦合或通信连接,可以是电性或其它的形式。
所述作为分离部件说明的单元可以是或者也可以不是物理上分开的,作为单元显示的部件可以是或者也可以不是物理单元,即可以位于一个地方,或者也可以分布到多个网络单元上。可以根据实际的需要选择其中的部分或者全部单元来实现本实施例方案的目的。
另外,在本发明各个实施例中的各功能单元可以集成在一个处理单元中,也可以是各个单元单独物理存在,也可以两个或两个以上单元集成在一个单元中。上述集成的单元既可以采用硬件的形式实现,也可以采用软件功能单元的形式实现。
所述集成的单元如果以软件功能单元的形式实现并作为独立的产品销售或使用时,可以存储在一个计算机可读取存储介质中。基于这样的理解,本发明的技术方案本质上或者说对现有技术做出贡献的部分或者该技术方案的全部或部分可以以软件产品的形式体现出来,该计算机软件产品存储在一个存储介质中,包括若干指令用以使得一台计算机设备(可为个人计算机、服务器或者网络设备等)执行本发明各个实施例所述方法的全部或部分步骤。而前述的存储介质包括:U盘、只读存储器(ROM,Read-Only Memory)、随机存取存储器(RAM,Random Access Memory)、移动硬盘、磁碟或者光盘等各种可以存储程序代码的介质。
以上所述仅是本发明的优选实施方式,应当指出,对于本技术领域的普通技术人员来说,在不脱离本发明原理的前提下,还可以做出若干改进和润饰,这些改进和润饰也应视为本发明的保护范围。