-
-
[翻译]写一个简单的fuzzer-part 2
-
发表于: 2020-5-8 23:50 8288
-
在本系列的上一篇(英文版)中,我们实现了一个非常简单的fuzzer,因为我们使用的是随机的变异策略且没有任何反馈信息来证明我们对原始文件所做的变异是有效的(之后我们会对此进行优化),所以这个fuzzer很难胜任对复杂目标的fuzz。另外就是上一篇中编写的代码并不完整(主要是只有功能代码,并没有调用代码的过程),在这一篇中我们依然只有功能代码,但是为了能帮助新手理解整个工程,我已将所以的代码放到GitHub上供大家学习。
随着目标越来越复杂,我们早期的fuzzer代码显然是不够用的,所以我将在不改变原有代码功能的情况下对代码的三个部分进行优化。第一个就是支持全局配置文件和运行时的部分信息提示:
我们不必将过多的硬编码、路径、名称和值也打印出来。
第二就是让fuzzer能访问单个文件或文件目录:
这项优化能使fuzzer直接使用整个文件库,能帮助我们实现之后的对覆盖率的优化(这项优化现在是没用的)
第三就是对ptrace事件的一些优化:
上述这三种优化并没有直接改变fuzzer的功能;接下来我们将对fuzzer本身的功能进行优化
我们的fuzzer的变异策略是依靠随机化来完成的,但是我们对随机化的了解并不多,假如我想复现之前的fuzz的运行结果,如何实现呢? 接下来简单介绍一下Python-random的随机策略。
如果仔细阅读关于random库的文档,不难发现它是基于伪随机数生成器(Pseudo Random Number Generator, PRNG)实现的,如果使用这种生成器生成加密密钥的话,是很不安全的;而且如果我们想获取或者设置生成器的状态的话,就必须将其反序列化后生成的文件放在磁盘上,并且每次加载文件的时候就必须再次反序列化(贼麻烦)。
然而,针对PRNG的特性(对于相同的种子,生成的初始状态也是相同的),有一个更简单的方法
当fuzzer启动时就会随机获取24个字节并将其作为种子,这么做的好处就是如果想要恢复状态只需要传递运行时的种子值,此方法的缺点是fuzzer一旦开始就无法暂停(只能等运行结束或者中途kill),但是如果循环时能有反馈信息的话,这个缺点也就不重要了
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!