其他分享
首页 > 其他分享> > 【论文分享】 Regression Greybox Fuzzing

【论文分享】 Regression Greybox Fuzzing

作者:互联网

CCS 2021 的一篇关于模糊测试的文章,主要是利用git commit 的日志来去指导模糊测试,去测试最近变化过和变换频繁的代码区域。

简介

What you change is what you fuzz !在OSSFuzz里生成的报告里,大约77%的漏洞报告都是回归型的。对于一个新加进来的项目,每天可能会有2-3个漏洞报告。在刚开始这段漏洞爆发期过去后,后续每周有漏洞的频率大概是一周会有3-4个bug。这种常数的增长速率只能用回归率来解释。作者画了个漏洞是回归的概率与漏洞数目的图,从图上可以看出,后期产生的bug,有非常大的概率是回归的。漏洞是回归的意思就是漏洞是由最近的修改导致的。

image-20220120202319728

文章基于这个发现提出了一种回归灰盒测试。能够针对最近变化频繁的代码进行测试。然而,对于任意的软件,是不可能对于每个commit进行单独测试。因此,回归灰盒测试能够同时fuzz 所有的commits,但是最近提出的commit具有更高的优先级。作者观察到大部分的代码都不会变化,而且相当的老。所以,实现了一种方法去加强感兴趣代码的fuzz力度。同样也修改了能量调度算法,并且引入了蚁群算法来分配更多的能量到那些会生成更多有趣输入的种子上去。

背景

现有的工具可以对单个commit进行fuzz,但是如果只对单个commit进行fuzz,可能会丢失掉没有测试的commit、跨越多个commit引起的漏洞。例如,早期的commit引入了一个漏洞,后期的commit用了这个数组,导致了漏洞,这种情况只对一个commit进行fuzz的AFLGo就没有办法解决。

而且对所有commit一次次地去fuzz,也是非常耗时的。

方法

改了三个部分:

Code History-based Instrumentation

理论上,要计算一个输入执行的代码有多老或者有多经常被修改,我们需要在执行的时候进行计算。计算的具体实现就是对代码进行插桩。插桩的算法如下:

image-20220121111231089

对于每个基本块BB,计算基本块的age和churn,然后使用AMPLIFY函数进行放大。修正全局变量阿尔法和count的值。

第三行的LASTCHANGED,计算基本块的age,age表示这个基本块最近被修改的时间。具体来说,是使用git blame去识别给定行L的commit C,然后提取C的日期,计算从commit C到当前commit经过了多少时间。基本块的age就是基本块里所有行的平均age。

第四行的NUMBEROFCHANGES,对于所有的基本块,RGF会去计算churn值。churn值指的是基本块被修改的频率。简单来说,就是计算commit C’ 的次数。C‘ 指的是连续两个版本R和R’的语法不同。

第五行的AMPLIFY,是放大age和churn的函数。作者观察到有很大一部分的基础基本块是不会被修改的。如果我们只计算基本块的均值,就会导致一些有趣的基本块的值特别小。最近的修改或者频繁地修改都会被忽略掉。作者做了几个实验来确定amplify函数,认为下面的amplify函数是最有效的。

a g e ′ = 1 a g e age' = \frac{1}{age} age′=age1​

c h u r n ′ = l o g ( c h u r n ) churn' = log(churn) churn′=log(churn)

对于6-8行的inject,对于所有的基本块BB,插桩pass会在基本块的末端插入新的指令。主要是用来累加放大后的age和churn,以及计算执行的基本块的数目。

Simulated Annealing-based Power Schedule

回归灰盒测试(RGF)是一个优化问题,需要平衡exploration和exploitation。如果RGF只做探索,而不使用age和churn值,就和普通的灰盒测试没什么区别了。如果RGF只关心最优化的种子,就会失去探索其他漏洞的机会。全局优化技术就是用来处理这个trade-off的。

这篇文章处理这个全局优化问题,采用的是模拟退火算法。开始于探索阶段,然后迅速地切换到利用阶段。在灰盒测试中,,我们可以使用能量调度来调整这些搜索参数。能量调度对所有的种子赋予能量,一个种子的能量决定了用这个种子fuzzing的时间。

下面的种子调度算法,实现了:给定插桩的程序,种子库和输入,计算输入的能量。

image-20220122140823785

第1行是前面插桩计算的阿尔法值,然后第2行对他求每个基本块的平均。第3行做归一化,将阿尔法值归到0-1之间。

第4行的ω是来处理探索(exploration)和利用(exploitation)的平衡的。其中 T e x p = 0.0 5 t . s e l e c t d T_{exp} = 0.05^{t.selectd} Texp​=0.05t.selectd是温度函数。在探索阶段,过低和过高的fitness的种子所获取的权重是一样的。比如,当一个种子没有被选择过,ω等于0.5,而当种子被选择了很多次之后,ω会接近归一化后的阿尔法值。

第5行是能量调度算法。基于前面的ω值来计算种子t的能量。其中 p a f l p_{afl} pafl​指的是这个种子之前赋予过的能量。r是用来确定能量p的范围在 [ 2 − r , 2 r ] [2^{-r},2^{r}] [2−r,2r]之间。

Ant Colony Optimisation (ACO)-based Byte-Level Power Schedule

污点分析经常用于分析哪些输入字节能够影响给定的代码位置,比如angora,vulscope等等fuzzer都用到了这种方法。然而,在这个场景里,不适合用污点分析。一是,污点分析的性能开销比较大。二是,这篇文章没有给出具体的位置给污点分析用来分析。

本文采用的是迭代式学习输入字节的分布,看哪部分的输入字节会让程序执行到有趣的地方。简单来说,就是计算每个字节的得分,分数越高越有可能到达感兴趣的地方。

image-20220122151209957

要学习输入字节的分布的难点在于后续fuzzing迭代的字节选择依赖于前期fuzzing迭代时的字节选择。比如,在早期的迭代过程中,我们选了前面三个字节,并且成功了,就会导致前三个字节的得分变高,并且不断重复,就会导致前三个字节的权重变得很高。

为了解决这个问题,文中提出了一种蚁群优化算法。蚂蚁在他们的路径上留下信息素,使得其他的蚂蚁会沿着这条路径一块走。成功的路径会有更多的蚂蚁走,并且留下更多的信息素。然而,随着时间的过去,信息素会逐渐挥发,然后就给了新的机会去发现更好的路径。这里也类似,RGF基于输入的fitness,给输入的某个字节一个分数。然后,每个时间间隔过去后,所有字节的分数都会乘以0.9来模拟逐渐挥发。

具体的步骤可以分为以下四步:

  1. 当一个新的输入t加入到种子语料库中
    • 计算种子t的fitness分数(归一化的阿尔法值)
    • 将种子t的所有字节的分数置为0
  2. 通过fuzzing种子t生成了一个新的输入t‘
    • 计算输入t’的fitness分数
    • 找到t与t‘不同的字节
    • 如果t’的fitness分数高于t,就累加一定的分数到这些不同的字节上
  3. 当种子t被选为fuzzing时,以概率来fuzz每个字节,字节的分数越大,变异的概率越大。
  4. 在固定的时间间隔,RGF对所有的字节乘以小于1的数,来降低所有旧字节的分数。

结果

文章的假设是去fuzz最近变化的代码和变化频繁的代码,能够提高挖到回归漏洞的效率。因此,实验也是去验证这一点。所以,文章提出了三个研究问题。

RQ1:这种指导方式能不能提高灰盒测试工具的效率。(与AFL做对比实验)

RQ2:哪种启发式的指导的贡献更大?

RQ3:crash的位置到底和最近变化、频繁变化这两个因素有没有关系?

RQ1的结果:1部分是AFL和AFLChurn在第一个cycle就找到了漏洞。而aflchurn需要跑完第1个cycle的指导作用才有用。3部分是两个都没跑出来crash。所以能看的是第2部分。看第2部分的结果,可以看到aflchurn是要优于第AFL的。

image-20220122153805252

RQ2的结果:从表格上看,没有说哪方赢了很多。从某些特例来看,其中一者具有更好的效果。所以才需要将这两种启发式方法结合起来。

image-20220122154302853

RQ3:给了很多图表,这里就简单说下结论:栈轨迹里的许多元素要比其他地方的代码变化得更多。在很多情况下,有一两个栈元素在代码中基本没有什么变化。大部分的元素都变化了相当多次。并且regressions和non-regressions之间并没有太大的区别。

总结

看了这篇文章,基本上理解了模糊测试的文章需要改哪些部分可以应用到别的一个场景。(插桩、能量调度、fuzz哪些输入字节)

总体来说,是一篇原理不是很难,但是思路很清奇的文章。而且文章开源了代码和实验框架可供学习,太赞了!

标签:字节,age,漏洞,基本块,Greybox,输入,commit,Regression,Fuzzing
来源: https://blog.csdn.net/u013648063/article/details/122638786