My two questions about AFL.

prologue

afl-2.52b 之前对fuzz的理解仅限于它可以产生各种输入去’撞’程序,然后就有可能包含一些非法输入,这样程序就会崩溃然后fuzzer会保存这些输入,然后挖洞的就可以一一去人工尝试这些非法输入看看能不能找到存在脆弱性的地方. 一开始对这种方法不以为意感觉就是会打字的猴子能’撞’到哈姆雷特的概率是极低的,第一次听说真正利用起来是在winesap的社课上讲的一题PlaidCTF2015-Plaiddb这题winesap讲的时候说他们队伍比赛的时候是用afl发现漏洞的,虽然那题的洞我做的时候感觉比较常见(可能近几年被玩坏了),但是感觉fuzz的有用性还是不错的.

Q

首先我明确一下我想要探究的感兴趣的问题

  1. AFL的mutate是如何进行的,有多少种变化每种变化是怎么样子的.
  2. AFL的mutate是何时进行的.也就是说什么时候认为是找到了新的状态.

其他关于AFL比较细节的部分先不去了解.

How

首先根据[相关的文章]定位相关的函数–fuzz_one in afl-fuzz.c一个1600多行的大函数…时间紧迫这次不能硬刚了…理解mutate相关操作为目的. 上下拖动源码你就会发现有类似于

  /*********************************************
   * SIMPLE BITFLIP (+dictionary construction) *
   *********************************************/

于是乎我就用着搜索功能搜索/*********找到了和mutate相关的操作 主要有一下几种模式.SIMPLE BITFLIPARITHMETIC INC/DECINTERESTING VALUESDICTIONARY STUFFRANDOM HAVOCSPLICING一共6种这几个名字让我想起了跑AFL时queue文件夹内的那些文件的名字:

id:000009,src:000000,op:flip1,pos:6
id:000020,src:000000,op:flip2,pos:6
id:000024,src:000000,op:arith8,pos:8,val:+12
id:000034,src:000000,op:havoc,rep:64
...

于是乎偷懒不看源码的方法就出现了,通过对比产生的测试样例和原来的seed结合文件的名字来推断mutate相关操作,可以用于理解相关内容.

首先是猜测一下起名规则'id:{},src:{},op:{}'.format(id,source,option)前面的3个区域比较好理解就是自己本身的id(每次都会加1),src表示source就是本测试样例是有id为xxxx的source演变的,然后option就对应了上述的6种模式中的一种.接下去的例如pos,rep…. 正当我发现我这种方法其实不是特别准确的时候(因为queue里面放的并不是所有的)接着我发现了有人已经分析过的文章…真香… 一位硬核的博主@Chen_zju,看完了他的分析后发现源码分析能得到的东西真多,我这里由于时间有限就不多分析仅将他的成果摘录.

bitflip

比特反转.有许多种反转方式,反转后进行测试会通过返回结果判断为token或者是可能会有影响程序流程的位置从而生成effector map. 具体的分析还需看上面链接中的文章,非常细致通透易懂.

arithmetic

byte,word,dword进行加减运算.

interest

修改原值为一些interesting的值例如一些边界值0,128之类的.

dictionary

尝试 插入/替换为 一些token可以用-x设置词典文件.

havoc

引入一些随机值的大巨变(富人靠科技,穷人靠变异).一定的变异率可以挖掘到奇妙的洞.

splice

找两个seed 然后切掉后链接后havoc具体可以表示为 A1|A2 + B1|B2 =(splice)=> A1|B2 …=(havoc)=>new seed

感谢Chen_zju!至此我已经大致了解了AFL是如何对mutate的,之前玄幻的fuzz现在没有那么摸不着了,伴着Chen_zju的文章我也读了一些相关的代码不得不说AFL的mutate机制比我当初想象的要灵活以及有效,的确可能会名中许多漏洞.接下来我来解决我的另一个疑惑: AFL何时认为自己的确发现了一个可能有用的输入.

When

于是乎我又去找资料了,@0saber0非常完整的过程.我对着源码搞了半天终于大概弄懂怎么回事了。。。看了人家完整的分析反正我是不敢写下来我的一知半解的。 关于何时发生mutate的答案应该是在将列表中的所有文件都测试过了完成了一个cycle就会开始进行. 主要的设及的函数有fuzz_one.里面包括了一些重要的函数例如 calibrate_case,calculate_score.

summary

又看着大师傅们的博客看了一天,虽然读了大半天源码但是感觉对AFL的了解非常有限,看了师傅们的分析不明不白的我现在实在不敢自己写分析.

mutate一共有6中模式对seed进行变化并不是随便的而是根据运行结果发生变化,在一些‘有趣’的结果上会在一个cycle结束后继续变化.

reference

(推荐阅读

  1. https://blog.csdn.net/Chen_zju/article/details/80791268
  2. https://bbs.pediy.com/thread-254705.htm