基于目标点任务划分的并行化模糊测试方法及系统

文档序号:29622053发布日期:2022-04-13 13:33阅读:293来源:国知局
基于目标点任务划分的并行化模糊测试方法及系统

1.本发明属于软件自动化安全检测技术领域,基于目标点任务划分的并行化模糊测试方法及系统。


背景技术:

2.软件安全测试对于软件质量的保证具有重要意义。为了提升软件安全测试的效率,可以采用并行化的模糊测试方法,但是这种技术方法会存在任务冲突的问题,任务冲突主要由两部分的原因:1.由于各个实例的种子选择策略是相似的,所以会针对软件中相似的代码部分进行测试,导致测试局限于软件某一部分。2.多个实例采用相同的种子变异策略对相似的种子队列中的种子进行变异,会产生很多的重复的测试用例,造成测试资源的浪费。
3.为了解决并行化模糊测试中存在的任务冲突问题,现有的解决方法主要分为种子选择策略多样化和种子变异策略多样化等两类方法。
4.1.通过种子选择策略多样化来解决任务冲突。pafl框架的核心思想是将位图进行静态均等划分,分配给各个模糊测试实例,各实例依据其所负责的位图部分来测试软件中对应部分的程序,通过种子选择策略的差异来解决并行化模糊测试过程中的任务冲突问题。这种方法针对性的解决了aflfast、fairfuzz模糊测试框架在并行化过程中存在的任务冲突问题。但是,位图均等划分方法可能会导致任务分配的不均衡。cn113590281a提出了基于动态集中式调度的分布式并行模糊测试方法及系统,在该方法中,通过对各个模糊测试实例产生的种子进行集中式的管理,构建一个全局种子队列,依据种子的深度、模糊测试轮次数和变异次数来对种子进行优先级排序(具体实现参考afl的calculate_score()函数)。然后,主节点会采用请求-分配的方式,为每一个请求种子的模糊测试实例,从全局种子队列中取出优先级最高的种子进行分配,从而使得各个模糊测试实例能变异测试不同的种子,实现种子选择策略的多样性。该方法能较好的解决并行化模糊测试过程中的任务冲突问题,且具有较好的普适性,但是,该方法需要消耗额外的计算资源进行种子的评估和管理,且主节点和模糊测试实例频繁的信息交互会影响整体的测试效率。
5.2.通过种子变异策略多样化来解决任务冲突。cn110147310a提出了一种基于变异策略的并行模糊测试调度方法及装置。在该方法中,对模糊测试器afl中的变异策略集合进行静态分配(变异策略集合具体参见afl的fuzz_one()函数),为并行的不同测试实例分配不同的变异策略,以使得各实例间种子变异策略的多样化,从而减少重复测试用例的产生,达到部分解决任务冲突的问题。虽然该方法通过种子变异策略的多样化减少了大量重复测试用例的产生,但是,由于各实例种子选择策略的相似性,仍然会存在软件测试的局部性问题。
6.综上,对于并行化模糊测试过程中存在的任务冲突问题,本发明以定向模糊测试框架aflgo为基础,提出了基于目标点任务划分的并行化模糊测试方法,依据种子在测试过程中所能覆盖的基本块信息来决定其归属的目标点,为不同的模糊测试实例生成不同的种
子队列来实现任务的划分,使得各实例可以测试软件中的不同部分,解决任务冲突问题,从而提升整体的软件漏洞检测效率。


技术实现要素:

7.本发明的一个目的是针对上述问题,提出了一种基于目标点任务划分的并行化模糊测试方法。本发明中模糊测试器基于aflgo框架开发,在aflgo的并行化模型之上增加了基于目标点的任务划分方法,用以解决原先并行化过程中会存在的任务冲突问题。
8.首先通过静态分析程序,获取软件中可能存在的漏洞点,将其作为目标点集合插装入软件,编译后获取软件的函数调用关系图和控制流程图;将任意一行代码表示为基本块,计算出软件中的所有基本块代码到各个目标点的距离,然后将基本块依据其距离信息进行归类,每一个基本块归属于一个目标点。
9.并行化模糊测试启动前,每个模糊测试实例都会被分配一个子目标点集合,然后在测试过程中,依据种子在测试时所能覆盖的基本块信息来决定该种子归属于哪一个目标点,即由该目标点对应的模糊测试实例对其进行变异。如果发现了漏洞,就由主节点依据漏洞对应的错误栈信息进行分析,判断该漏洞是否由某个目标点处的代码引起,若是,则将该目标点标记为已完成,将相应的计算资源转为对其他未完成的目标点的测试。
10.上述方法主要包括四个阶段:静态代码分析阶段、插桩编译阶段、并行化模糊测试阶段、目标点漏洞判断阶段。
11.所述的静态代码分析阶段具体为:通过代码缺陷静态检查工具cppcheck,对软件进行静态分析检测出存在内存泄漏、错配的内存分配和释放、缓冲区溢出问题的代码块,构建目标点集合。
12.所述的插桩编译阶段具体包括以下步骤:
13.2-1.插装编译构建函数调用关系图cg图和控制流程图cfgs图;借助aflgo原有的插桩编译脚本,将静态分析阶段获取的目标点集合信息在编译的过程中通过插桩的方式注入程序;生成cg图和cfgs图,用于下一步基本块的归属及其距离的计算;
14.2-2.计算基本块归属及其距离:依据cg图和cfgs图,计算软件中每一个基本块到各个目标点的距离,如果基本块到目标点a的距离小于到其他目标点的距离,则该基本块就归属于目标点a;然后,将每一个基本块的名称、归属目标点信息和基本块距离信息写入distance.cfg.txt文件中;
15.2-3.插装编译生成可执行文件:读取distance.cfg.txt文件中的信息,将该信息在软件重新编译时插入,生成可执行文件,使得在软件运行触发基本块时能获取其归属的目标点信息。
16.所述的并行化模糊测试阶段具体包括以下步骤:
17.3-1.读取本目标点任务集合:各个模糊测试实例读取指定目录下的与其实例名对应的目标点文件,其中记录着各实例所需负责测试的目标点信息;当某个模糊测试实例对应的目标点文件为空时,则结束测试;模糊测试实例是指模糊测试器启动后的模糊测试进程;
18.3-2.种子选择:模糊测试实例在进行种子选择时,会依据种子测试运行过程中所覆盖的一些基本块信息来判断该种子是否归属于自己所负责的目标点,若是,则将其加入
种子队列中,用以进行变异测试,否则,便不加入;
19.3-3.变异测试:每一个模糊测试实例都会对各自的种子队列中的种子依次进行变异测试,当一轮测试完成后,若在测试过程中发现漏洞,则转至步骤3-4,否则转至步骤3-1;
20.3-4.漏洞存储:如果在测试过程中发现漏洞,就将其存储在crashs目录下,以漏洞文件形式保存,由主节点自行完成目标点漏洞判断;返回至步骤3-1。
21.所述的目标点漏洞判断阶段具体包括如下步骤:
22.4-1.漏洞搜集:主节点会定期检查各个模糊测试的crashs目录,若发现存在新的漏洞文件,则转至步骤4-2,否则,休眠sl秒,sl为设定值,再次进行漏洞搜集;
23.4-2.漏洞信息生成:主节点会依据搜集到的漏洞文件进行漏洞复现,借助asan框架,产生漏洞所对应的错误栈信息;
24.4-3.漏洞与目标点信息比对:比对漏洞的错误栈信息和每一个目标点的位置信息,判断漏洞是否存在于某一个目标点处的代码中,若是,则转至步骤4-4,否则返回步骤4-1;
25.4-4.更新目标点集合,进行节点资源调度;将确认已经发现漏洞的目标点从整个目标点集合中移除,如果整个目标点集合为空,则测试结束;否则,重新分配目标点给各个实例,更新各个模糊测试实例所对应的目标点文件,返回至步骤4-1。
26.进一步的,所述的步骤2-2具体过程如下:
27.1)依据cfgs图,计算任意基本块bb到本函数中各函数调用点的基本块间距离,用dis_block[i]表示,其中i指代函数调用点,i=1,2...n,n为函数调用点的总个数;
[0028]
2)依据cg图,计算各函数调用点到各个目标点函数的函数间距离,用dis_func[i][j]表示,其中j指代目标点函数,j=1,2...m,m为目标点函数的总个数,然后依据dis_func[i][j],求解出各函数调用点的最短函数间距离,用dis_min_func[i]表示,而对应的目标点信息则用block_to_target[i]表示;
[0029]
3)依据基本块间距离和最短函数间距离,可以计算出bb的基本块距离dis,计算公式为:dis=min(dis_block[i]+α*dis_min_func[i]);而bb的归属目标点记为target,target=block_to_target[ii],其中ii为求解出dis的函数调用点;
[0030]
4)将每一个计算好的基本块的基础信息bbinfo写入distance.cfg.txt文件中,基础信息bbinfo包括基本块的名称、归属目标点信息、基本块距离信息。
[0031]
进一步的,所述步骤3-2过程具体如下:
[0032]
1)首先遍历basicinfoall中的基本块基础信息,读取其中的target和dis,在targetnum队列的target位置处加1,表示当前基本块归属于target,targetnum队列中记录着各个目标点所拥有的基本块的数量;将基本块的dis值加到targetdis队列的target位置处,targetdis队列用于记录各个目标点所拥有的基本块的总的距离之和;
[0033]
2)从targetnum队列中选择拥有最多基本块归属的目标点,若存在多个目标点所拥有的基本块数量一致,则从targetnum队列中,选择归属基本块的距离之和最小的那个目标点,该目标点即为种子归属的目标点,记为seedtarget;
[0034]
3)若seedtarget在本实例所负责的子目标点集合tc中,则将其加入本实例的种子队列中,用以进行变异测试,否则,便不加入。
[0035]
进一步的,所述步骤4-3具体过程为:获取错误栈信息中指明漏洞存在的那行代码
的位置信息,将其与目标点集合中每一个目标点的位置信息进行比对,若信息比对成功,则可证明某一目标点处存在漏洞。
[0036]
进一步的,所述步骤4-4具体过程为:主节点将确认已经发现漏洞的目标点从整个目标点集合t中移除,如果整个目标点集合t为空,则测试结束;否则,基于任务负载均衡原则,重新将t中的目标点分配给各个实例,然后通过save()更新各个模糊测试实例所对应的目标点文件。
[0037]
本发明的另一个目的是提供基于目标点任务划分的并行化模糊测试系统,包括静态分析模块、插桩编译模块、并行化模糊测试模块和目标点漏洞判断模块;
[0038]
静态分析模块,借助开源的cppcheck静态检查工具,对软件进行静态分析,找出软件中所有可能存在漏洞的位置,依据潜在漏洞的位置生成目标点集合;
[0039]
插桩编译模块,用于对待测软件进行插装编译。基于aflgo的编译脚本进行改进,通过插桩编译生成cg图和cfgs图,然后计算软件中每一个基本块到各个目标点的距离,选取距离最近的目标点作为基本块的归属目标点,将该信息记录至distance.cfg.txt文件中;
[0040]
并行化模糊测试模块,用于对待测软件进行并行化模糊测试。各个模糊测试实例会从其对应的目标点文件中读取目标点信息,然后对种子进行选择,只对那些归属于本实例所负责的目标点的种子进行变异测试,从而解决各个模糊测试实例之间的任务冲突问题;
[0041]
目标点漏洞判断模块,用于判断漏洞是否存在于目标点代码处。借助asan框架生成漏洞对应的错误栈信息,然后比对漏洞的错误栈信息和每一个目标点的位置信息,判断漏洞是否存在于某一个目标点代码中,若是,则可以将目标点标记为已完成,调集计算资源测试软件的其他目标点。
[0042]
本发明采用了基于目标点任务划分的并行化模糊测试方法,将种子依据其归属的目标点进行自动划分,使得各个模糊测试实例拥有不同的种子队列,解决了并行化模糊测试过程中的任务冲突问题,可以有效的提升整体的测试效率。
[0043]
相对于已有工具pafl并行化模糊测试框架,本发明提出的基于目标点任务划分的并行化模糊测试方法,专门针对aflgo并行化模型,进行了更细粒度的任务划分,使得各个模糊测试实例的任务分配更细致、更加均衡,可以更好的解决其运行过程中所存在的任务冲突问题。另外,本发明提出的目标点漏洞判断机制,解决了aflgo原来就存在的发现漏洞之后无法判断该漏洞是否位于目标点代码处的问题,从而导致即使完成了对目标点的探索也无法停止的情况。现在,通过目标点漏洞判断机制,可以释放已经探索完成的目标点区域对应的计算节点资源,使其探索其他目标点区域,从而提高了系统的灵活性和计算资源的使用效率。因此,本发明可以提升aflgo并行化模型的整体测试效率。
[0044]
使用本发明方法,可以提升软件漏洞的检测效率,在相同的测试时间内,能更全面的探索软件中的代码,发现更多的软件漏洞。
附图说明
[0045]
图1为本发明的整体流程图;
[0046]
图2为图1中插装编译阶段流程图。
[0047]
图3为图2中基本块归属及其距离计算流程图。
[0048]
图4为图1中并行化模糊测试阶段流程图。
[0049]
图5为图1中目标点漏洞判断阶段流程图。
具体实施方式
[0050]
下面将结合本发明实施例中的附图,对本发明中的技术方案进行完整描述。
[0051]
如图1所示,基于目标点任务划分的并行化模糊测试方法,整体步骤分为四个阶段,静态代码分析阶段、插桩编译阶段、并行化模糊测试阶段、目标点漏洞判断阶段。
[0052]
静态代码分析阶段具体为:通过代码缺陷静态检查工具cppcheck,对软件进行静态分析检测出可能存在内存泄漏、错配的内存分配和释放、缓冲区溢出等问题的代码块,构建目标点集合。所述目标点集合(可能存在上述问题的代码行的集合),其中单个目标点(任意一行代码)表示为基本块(文件名,代码行号)。
[0053]
插桩编译阶段,如图2所示,包括以下步骤:
[0054]
2-1.插装编译构建函数调用关系图和控制流程图:借助aflgo原有的插桩编译脚本,将静态代码分析阶段获取的目标点集合信息在编译的过程中通过插桩的方式注入程序。生成函数调用关系图cg图和控制流程图cfgs图,分别描述软件中各个函数之间的调用关系和各个函数内部的基本块之间的关系,用于下一步基本块的归属及其距离的计算。
[0055]
2-2.计算基本块归属及其距离:
[0056]
以软件中的某个基本块bb来描述基本块的归属及其距离的计算方法:首先,依据cfgs图,计算基本块bb到本函数中各函数调用点的基本块间距离,用dis_block[i]表示,其中i指代函数调用点,i=1,2...n(n为函数调用点的总个数)。其次,依据cg图,计算各函数调用点到各个目标点函数的函数间距离,用dis_func[i][j]表示,其中j指代目标点函数,j=1,2...m(m为目标点函数的总个数),然后依据dis_func[i][j],求解出各函数调用点的最短函数间距离,用dis_min_func[i]表示,而对应的目标点信息则用block_to_target[i]表示。最后,依据基本块间距离和最短函数间距离,计算出基本块bb的基本块距离dis,计算公式为:dis=min(dis_block[i]+α*dis_min_func[i])。而bb的归属目标点记为target,target=block_to_target[ii],其中ii为求解出dis的函数调用点。
[0057]
当每一个基本块的归属目标点信息及其距离都计算好后,将这些基本块的基础信息bbinfo(bb、target、dis)写入distance.cfg.txt文件中。
[0058]
目标点函数是指目标点所在的函数。
[0059]
基本块归属及其距离计算的伪代码如下:
[0060][0061][0062]
如图3所示,本实施例中,以软件中的某个基本块basica来描述基本块的归属及其距离的计算方法:首先,依据cfgs图,计算基本块basica到本函数mian中各函数调用点的基本块间距离。basica到函数调用点f1()的基本块间距离为1(计算方式为行号相减),而到函数调用点f2()的基本块间距离为3。其次,依据cg图,计算各函数调用点到各个目标点函数的最短函数间距离,如图1所示,函数调用点f1()到目标点函数1之间间隔为1,因此函数间距离为1,而不存在到目标点函数2的路径,因此函数间距离为无穷大,所以,函数调用点f1()的最短函数间距离为1,对应的函数为目标点函数1,以此方式可计算函数调用点f2()的最短函数间距离。最后,依据基本块间距离和最短函数间距离,计算出基本块距离,计算公式为:min(基本块间距离i+α*最短函数间距离i),(i=1,2...n,n为函数调用点的个数)。所以,basica的基本块距离为11,归属于目标点1。
[0063]
2-3插装编译生成可执行文件:对软件进行重新插装编译时,会读取distance.cfg.txt文件中的信息,将该信息插桩入软件中,生成可执行文件,使得在软件运行触发基本块时能获取其归属的目标点信息target和距离信息dis。
[0064]
并行化模糊测试阶段,如图4所示,具体包括以下步骤:
[0065]
假定并行化模糊测试的并行度为n,一共有n个并行模糊测试实例,命名为sk(k=
1,2...n)。假定目标点集合为t,t中的目标点平均分成n份,记各子目标点集合为tc(c=1,2...n)。
[0066]
3-1.读取本目标点任务集合:目标点集合t中的目标点会依据平均分配的原则被划分成n个子目标点集合,分配给各个模糊测试实例,并将子目标点集合信息tc存储到/tasks/xxx目录下相应的子目标点文件中,子目标点文件名等于模糊测试实例名,即sk(k=1,2...n)。
[0067]
在每一轮模糊测试开始前,各个模糊测试实例sk均会读取/tasks/xxx目录下与其实例名对应的目标点文件,其中记录着各实例所需负责测试的子目标点集合tc信息。当某个模糊测试实例对应的目标点文件为空时,则其结束测试。
[0068]
所述模糊测试实例是指模糊测试器启动后的模糊测试进程。
[0069]
3-2.种子选择:模糊测试实例在进行种子选择时,会依据种子测试运行过程中所覆盖的基本块的基础信息集合basicinfoall来判断该种子是否归属于本实例所负责的目标点,其判断方法是:依据种子所覆盖的所有基本块的基础信息,选择拥有最多基本块归属的目标点,若存在多个目标点所拥有的基本块数量一致,则选择归属基本块的距离之和最小的那个目标点。确定种子归属于哪一个目标点。若种子归属的目标点在本实例sk所负责的子目标点集合tc中,则将其加入本实例的种子队列中,用以进行变异测试,否则,便不加入。
[0070]
本实施例中首先遍历basicinfoall中的基本块基础信息,读取其中的target和dis,在targetnum队列的target位置处加1,表示当前基本块归属于target,targetnum队列中记录着各个目标点所拥有的基本块的数量;将基本块的dis值加到targetdis队列的target位置处,targetdis队列用于记录各个目标点所拥有的基本块的总的距离之和。其次,从targetnum队列中选择拥有最多基本块归属的目标点,若存在多个目标点所拥有的基本块数量一致,则从targetnum队列中,选择归属基本块的距离之和最小的那个目标点,该目标点即为种子归属的目标点,记为seedtarget。若seedtarget在本实例所负责的子目标点集合tc中,则将其加入本实例的种子队列中,用以进行变异测试,否则,便不加入。种子选择过程的伪代码如下:
[0071][0072]
3-3.变异测试:每一个模糊测试实例都会对各自种子队列中的种子依次进行变异测试,而种子变异过程中的能量分配,取决于种子所覆盖的基本块中,和种子归属于同一个目标点的基本块的数量以及这些基本块的距离之和。当一轮测试完成后,若在测试过程中发现漏洞,则转至步骤3-4,否则转至步骤3-1。
[0073]
3-4.漏洞存储:如果在测试过程中发现漏洞,就将其存储在本实例的crashs目录下,以漏洞文件形式保存,由主节点自行完成目标点漏洞判断。之后,返回至步骤3-1。
[0074]
目标点漏洞判断阶段,如图5所示,具体包括以下步骤:
[0075]
4-1.漏洞搜集:主节点会定期检查各个模糊测试实例的crashs目录,若发现存在新的漏洞文件,则转至步骤4-2,否则,休眠sl秒(sl为经验值,默认取60),再次进行漏洞搜集。
[0076]
4-2.漏洞信息生成:主节点会依据搜集到的漏洞文件进行漏洞复现,借助asan框架,可以产生漏洞所对应的错误栈信息。
[0077]
4-3.漏洞与目标点信息比对:获取错误栈信息中指明漏洞存在的那行代码的位置,将其与目标点集合tc中每一个目标点的位置信息进行比对,若信息比对成功,则可证明
某一目标点处存在漏洞,将目标点存入已完成探索目标点集合completetargetlist中,转至步骤4-4,否则返回步骤4-1。
[0078]
4-4.更新目标点集合,进行节点资源调度:主节点将确认已经发现漏洞的目标点从整个目标点集合t中移除,如果整个目标点集合t为空,则测试结束;否则,基于任务负载均衡原则,重新将t中的目标点分配给各个实例,然后通过save()更新各个模糊测试实例所对应的目标点文件,返回至步骤4-1。该过程的伪代码如下:
[0079][0080]
综上所述,本发明基于目标点任务划分的并行化模糊测试方法,依据种子所覆盖的基本块信息来决定种子的归属,使得不同模糊测试实例拥有不同的种子队列,负责测试程序中不同区域的代码,解决了aflgo并行化模糊测试过程中所存在的任务冲突问题。并且结合目标点漏洞判断机制,提高了aflgo并行模糊测试系统的灵活性和计算资源的使用效率。因此,本发明可以提升aflgo并行化模型的整体测试效率。
[0081]
为了验证本发明方法的有效性,进行了实验验证,其中两组对照组分别为:未经优化的aflgo原生框架(aflgo-old)和基于pafl方法改进后的aflgo框架(aflgo-pafl),而实验组则在原生aflgo框架的基础上使用了本发明方法进行优化(aflgo-new),对照组和实验组的并行度均为4。实验测试集分别采用lava-m、unifuzz平台中集成的2款测试软件以及一款开源软件libxml2,并且为了保证实验数据的准确性,每次实验都会重复三次,结果取平均值,最终的实验数据结果如下表所示:
[0082]
[0083]
/*提升率(1:3)指的是aflgo-new相较于aflgo-old的效果提升,提升率(2:3)指的是aflgo-new相较于aflgo-pafl的效果提升*/
[0084][0085][0086]
从实验数据中可以看出,虽然由于各个测试软件的特点而存在的部分效果差异,但是总体而言,使用了本发明方法后,相较于原生的aflgo框架和基于pafl方法改进的aflgo框架,在整体效果上有所提升。因此,本发明方法可以有效的解决aflgo在并行模式下任务冲突问题,提高软件漏洞检测的效率。
[0087]
上面结合附图对本发明的实施方式做了详细说明,凡依本发明申请发明范围所作的均等变化与修饰,都属于本发明保护的范围。
当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1