FairFuzz理解

简介

AFL在覆盖率方面依然存在局限性,FairFuzz在命中稀有分支(rare branch)方面做出改善,所谓稀有分支就是虽然在不断的变异输入,依然很少能命中的分支。

具体策略为:首先对稀有分支进行识别,然后采用一种名为变异掩码(mutation mask)的算法,控制输入在进行变异时,倾向于命中特定的稀有分支。

这个变异掩码是在fuzzing过程中动态计算的,具体的思路是在已经命中稀有分支的输入中,找到与命中该稀有分支最相关的部分,称为crucial parts;下次变异的时候,为了能继续命中该稀有分支,就要避免对crucial parts部分做变异。如何找到crucial parts呢,通过少量的mutation实验即可。

通过对比,FairFuzz在对嵌套层次较深的程序fuzz时,覆盖率有着明显的提升。

FairFuzz用到的算法

AFL算法

为了作对比,先贴出AFL fuzzing时的算法:

FairFuzz算法

FairFuzz进行fuzzing时的算法,灰色部分表示与AFL算法不同的地方:

要理解这段代码,需要解释上面说的两个概念:变异掩码 和 稀有分支

变异掩码定义

我们从一个一个的基本概念的定义开始。

1. 元组 (c, m) 称为一个mutation,其中m表示此次变异对m个字节的数据施加操作,c表示对input进行变异的种类(categories),包含:

O:覆盖,从位置k开始,新值覆盖旧值,共m个字节;

I:插入,在k位置开始插入m个字节;

D:删除,从k位置开始删除m个字节;

2. mutate(x, µ,i) ,其中,µ = (c,m),i ∈ [0, |x | − m),表示对input x从i位置开始按照元组 (c,m)进行变异的结果;

3. satisfies(x,T),其中x表示输入,T表示测试目标;当satisfies(x,T )值为true时,我们说输入满足测试目标;

4. 

其中函数 

 表示对输入x在测试目标T上计算变异掩码,函数的输入是x中的位置i,输出是{O, I,D}的子集;

如果 satisfies(mutate(x, (c, 1),i),T ) 为true,则,就是说对输入x在位置i进行1字节的c类型的变异后,satisfies返回true,我们说变异c包含在 函数 

 的返回值中。

实际上,变异掩码就是表示:对输入x在位置i进行单字节变异后仍然能够到达测试目标的变异类型的集合。比如,在输入的第3个字节这个位置,分别进行O、I、D三种类型的变异,只有O和I可以达到测试目标,那么第3个字节的变异掩码就是O和I 。

这里,µ = (c,m),OKTOMUTATE用到了上面说的变异掩码,进行本次变异是否合适的判定,其含义是:在对输入x在k位置进行长度为m的c类型变异后,依然可以到达测试目标,这种情况下,我们就说可以进行变异。

我们说FairFuzz进行倾向于稀有分支的变异,在deterministic阶段,这种倾向,就是通过上面的OKTOMUTATE来实现的。代码如下:

 第12行,只有满足变异条件,才会进行实际的变异(14行)。

5.

的定义为: 含义是在所有可以进行变异的位置随机取个位置。在havoc阶段使用,代码如下:

上面说了这么多次测试目标,测试目标到底是什么呢?这需要理解下面的稀有分支概念后,才能有清晰的认识。

稀有分支定义

我们继续先从各个基本概念说起。

6. hits(x,b) 表示输入x命中分支b;

7. numHits[b] = |{x ∈ I : hits(x,b)}| ,这里I表示目前产生的所有的输入,numHits[b]表示命中分支b的输入的个数;就是说numHits[b]是一个分支到命中次数的映射;每次输入被运行的时候,都会对本次命中的分支的命中次数加1,代码如下:

8. 假设Bv = {b ∈ B : numHits[b] > 0}(即Bv表示所有被命中的分支的集合),分支b被判定为稀有分支的条件是分支的命中次数 numHits[b] ≤ rarity_cutoff,其中rarity_cutoff的定义如下:

也是说,所有被命中的分支的命中的次数中,取最小值,然后按照2的i次方向上取整,即为rarity_cutoff。假设所有被命中的分支中,命中次数最小的分支,其命中次数为17,则按照2的i次方向上取整,rarity_cutoff的值为32;那么所有命中次数小于等于32的分支都是稀有分支;

9. 假设branches(x) = {b ∈ B : hits(x,b)}(即branches(x)表示输入x命中的所有分支的集合),输入x所命中的最稀有的分支,定义为:

即,在输入x命中的所有分支中,被命中次数最小的那个分支,称为输入x命中的最稀有的分支;

而FairFuzz只选择这样的输入进行变异:该输入命中的最稀有的分支属于整个变异过程中稀有分支范畴。代码段如下:

到次,稀有分支也说完了。那么前面说的测试目标到底是什么呢,我们说FairFuzz只选择命中稀有分支的输入进行变异,那么测试目标应该应该也是变异后能命中稀有分支才行。具体需要看代码进一步明确。

最后,再看一下fuzzing过程中如何计算变异掩码的。

变异掩码计算

 这个函数好理解,就是逐字节对input进行覆盖、插入或者删除,看看生成的变异是否可以命中指定的分支(函数第三个参数),如果可以就把对该字节进行的操作添加到mask中该字节对应的掩码位,最后返回mask。

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值