G.O.S.S.I.P 阅读推荐 2024-04-29 利用Fuzzing降低静态分析的误报

admin 2024年4月29日22:01:15评论6 views字数 3094阅读10分18秒阅读模式

今天来介绍ISSTA 21' [1] 和 ICSE 24' [2] 上面两篇有关利用Fuzzing降低静态分析工具误报的文章。整体思路都是依据static analysis从代码中抽取片段(minimized slice),随后通过harness来进行fuzzing分析,判断漏洞是否可触发。

1. 背景介绍

    静态分析工具在软件开发流程中非常常用,能够在不运行代码的条件下发现软件中的漏洞。然而静态分析工具往往存在整体误报率过高导致使用困难的问题,之前公众号团队做过一些统计,产生误报的原因很复杂,其中主要的原因有例如:

  1. 算力局限,在动态数值处易产生误报

  2. 对于Loop循环次数处理设计缺陷

  3. 无法识别数据过滤函数

1.1 Motivation Example走起

下面给出一个motivation example

G.O.S.S.I.P 阅读推荐 2024-04-29 利用Fuzzing降低静态分析的误报

Listing 1

当运行static analysis工具(如RATS)对这段代码进行检查时,它会将第16行标记为buffer overflow。然而,这显然是一个误报,因为第16行的strcpy操作永远不会超出分配的指针ret的界限。这是因为12行分配给指针p的大小总是等于所有输入字符串的长度+1。

2. Overview & Implementation

学术界为了解决这样的问题,提出了很多方法,包括改进静态分析,函数摘要等等方法。今天介绍的两篇文章是通过对于可能包含漏洞的candidate fuction进行动态fuzzing,来判断是否存在误报。

ISSTA 21‘[1] 开发的工具Helium,ICSE 24’ [2]开发的工具为FuzzSlice[3]

G.O.S.S.I.P 阅读推荐 2024-04-29 利用Fuzzing降低静态分析的误报

workflow

这种类型的工作的challenge主要有以下几点:

CH1:静态分析工具只会报出存在漏洞的代码片段,如何构造可编译、可运行的文件?

CH2:程序中有很多与漏洞无关的代码,如何构建最小的code slice?

CH3:动态测试如何保证覆盖率和准确性?

2.1 Minimal Slice Creation

这一步,两个工具都使用了递归囊括依赖的方式,例如下图,是静态分析工具的一个warning,表示ftpBuildTitleUrl函数存在漏洞。然而这个代码片段语义上不全,1023行的if缺少右括号;依赖上也不全,例如1004行的len没有被定义就被使用。

如何从这个代码片段生成“minimized slice”是本节要解决的问题。

G.O.S.S.I.P 阅读推荐 2024-04-29 利用Fuzzing降低静态分析的误报

针对这种问题,Helium和FuzzSlice提出了不同的解决方法。

2.1.1 FuzzSlice

FuzzSlice 在语义上的解决方法比较粗暴,直接提取整个ftpBuildTitleUrl函数,随后递归地囊括所有依赖,例如发现strcmp需要被包含,就在minimized slice中包含对应的头文件以及环境依赖。

FuzzSlice会多次对minimized slice进行编译,根据每一次编译的log,从源代码中递归地寻找对应的依赖。

例如下图的warning意味着需要加入“OPENSSL_malloc”的依赖,FuzzSlice就会抽取并查询包含源文件语义的XML,找到OPENSSL_malloc的定义处并包含进来。

G.O.S.S.I.P 阅读推荐 2024-04-29 利用Fuzzing降低静态分析的误报

这里用到的工具有:Bear[4] , srcML[5]。Bear能够记录编译时使用的命令行。srcML能够将源代码全部抽取为XML结构,方便使用XPath查询,定位target program依赖所在的位置。

2.1.2 Helium

Helium 在语义上多了一步LCA-Based Synatactic Patching,也就是并不是直接抽取整个ftpBuildTitleUrl函数,而是只抽取这个函数中和漏洞相关的语句并补充。最终的结果如下图:

G.O.S.S.I.P 阅读推荐 2024-04-29 利用Fuzzing降低静态分析的误报

可以看到,Helium仅补充了缺失的len和t两个变量,以及缺失的括号。整体算法十分复杂,详细算法可查询论文内容。

函数补充完成后,Helium也使用Bear进行可编译文件的构建。

2.2 Fuzzing 

2.2.1 Harness

两个工具为了Fuzzing的运行,都会为target program添加一个main函数,作为代码片段的Harness。识别input变量的方法是:如果在代码片段中使用变量𝑣之前没有找到变量𝑣的定义,那么变量𝑣就是一个input变量,应该添加进main函数。

2.2.2 Input

FuzzSlice 使用 libfuzzer 进行fuzz,过程中只改变 “C primitive types” 的值。Helium 则使用了KLEE, Fuzzers and Valgrind 三个工具进行fuzz,所有输入也都是随机生成。

3. Evaluation

两篇文章的作者都使用了公开的Test Suite和 Real-World Dataset进行测试。

FuzzSlice成功检测出了864/864个Juliet Test Suite的False positive,并且对于Real-World Dataset,成功编译了244/265个minimized slice,并在warning中检测出来了143/265个“可能的误报”(下图中PFP), 25/265个确认可被触发的crash(下图中C)。

G.O.S.S.I.P 阅读推荐 2024-04-29 利用Fuzzing降低静态分析的误报

Helium在Real-World Dataset中成功编译了68.5%的minimized slice,找到了205/280个“可能的误报”,48/280个确认可被触发的crash。

Helium编译成功数量表较少主要是由于Helium协助降低代码的片段大小的算法比较复杂,但是最终效果要强于FuzzSlice。

G.O.S.S.I.P 阅读推荐 2024-04-29 利用Fuzzing降低静态分析的误报

4. Discussion

这里由于两者的Target 不同,Evaluation的结果无法直接比较。总而言之,利用Fuzzing进行static analysis的FP elimination确实能达到不错的效果,并且在一定程度上能够辅助生成PoC。

但是实际情况中,这些触发漏洞的PoC不一定有用,因为Fuzz出来的输入很有可能并不会在real-world software中被产生并传入函数,毕竟两个工具的测试目标都是“code slice”以及自定义的main函数构成的程序。

[1] “FuzzSlice: Pruning False Positives in Static Analysis Warnings through Function-Level Fuzzing”: https://www.researchgate.net/publication/374114151_FuzzSlice_Pruning_False_Positives_in_Static_Analysis_Warnings_through_Function-Level_Fuzzing

[2] “Validating Static Warnings via Testing Code Fragments”: 

https://sites.google.com/view/helium-2021

[3] “FuzzSliceICSE,” Sep. 2023, [Online; accessed 11. Sep. 2023]. [Online]. Available: https://github.com/NobleMathews/FuzzSliceICSE

[4] Bear: https://github.com/rizsotto/Bear

[5] srcML: https://github.com/srcML/srcML/tree/master

原文始发于微信公众号(安全研究GoSSIP):G.O.S.S.I.P 阅读推荐 2024-04-29 利用Fuzzing降低静态分析的误报

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年4月29日22:01:15
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   G.O.S.S.I.P 阅读推荐 2024-04-29 利用Fuzzing降低静态分析的误报http://cn-sec.com/archives/2699921.html

发表评论

匿名网友 填写信息