【外文翻译-【BlackHat】结构化模糊测试,议题学习】此文章归类为:外文翻译。
BlackHat 2019
标题:
Going Beyond Coverage - Guided Fuzzing with Structured Fuzzing

视频:
d93K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6%4N6Q4x3X3g2T1K9h3I4A6j5X3W2D9K9g2)9J5k6h3y4G2L8g2)9J5c8Y4k6A6k6r3g2G2i4K6u0r3b7W2j5I4k6f1N6K9P5W2W2F1c8f1k6Y4i4K6u0r3
是什么?
模糊测试从最初发展到现在,经历了4个阶段:
- 无覆盖率引导的,非结构化感知的,通过/dev/urandom生成输入,与魔法无异。
- 无覆盖率引导的,结构化感知的,基于生成的方法。
- 覆盖率引导的,非结构化感知的,基于通用变异,虽然无法感知结构,但是由于覆盖率反馈,仍然表现良好。
- 覆盖率引导的,结构化感知的,基于结构变异,是下一代fuzzer方案。

为什么?
fuzz的初心是挖掘漏洞,结构化感知的方案可以挖出更多漏洞。对于下面的 sqlite 堆溢出,非结构化感知的oss-fuzz经过了多年的持续fuzz,输入了数百亿的测试用例,仍然无法发现。然而结构化fuzz很快就找到了。 
结构化fuzzer主要有以下4个方面的优势。
一、大多数bug不在表面
在下图中,非结构化感知的fuzzer获取输入用例,进行任意字节变异。比如对chrome的v8进行fuzz ,javascript代码作为输入,else可能变异成el0se。这会引入语义错误,导致解析失败。这些语义错误的测试用例停留在对解析器的测试(两个圈非重叠部分),无法对v8进行深层次的测试。
如果是结构化感知的fuzzer,可以保证测试用例的语义正确性,专注于后续的代码逻辑分支,进行深层次的测试(重叠部分)。 
这里需要注意2点:
- 理论上非结构化感知的fuzzer也可以发现深层逻辑的bug(重叠部分)。这本质上是概率问题,但是在时间维度上,可能到fuzz到宇宙的尽头。
- 大多数的bug都在语义正确的逻辑代码中,而不是停留在解析层面。
二、死循环和有限循环
为了实现高效的结构化fuzz,不仅要生成语义正确的javascript代码,还需要考虑约束测试用例空间,识别死循环,转而生成有限循环。例如,下图中的代码中存在bug,有限循环就可以找到bug,不必生成死循环,无法覆盖后续分支。 
三、特性fuzz
结构化fuzz的优点之一就是可以针对某一个特性进行fuzz。作者给chrome编写barcode测试代码,比如pdf的barcode特性,实现在cbc_pdfs417i.cpp中。从覆盖率信息可以看到,结构化fuzz可以做到对目标的某一个特性进行fuzz。教导fuzzer进行特性fuzz可以更容易,更低成本的找到bug。 
四、多维度输入
除了上述优点,结构化fuzz可以生成多维输入,覆盖到更多的分支。如下图所示,DoRequest函数有3个参数,那么就可以定制变异,生成多维的参数组合。 
怎么做?
以libfuzzer为例,首先需要写一个定制变异函数,对于javascript进行fuzz,可能需要写AST解析,在AST之上作变异。更简单的方案是使用libprotobuf-mutator写语法文件,将测试用例序列化,在protobuf结构上作变异。 
提问环节
Q:你怎么看AFLSmart?
A:AFLSmart是与libprotobuf-mutator相似的方案,它需要写peach pit语法。但是相比于写peach,每个人都会写C++,而不需要学习新的格式。
Q:未来是否考虑使用AFLSmart来替代?
A:目前项目所有样例都采用的libprotobuf-mutator,而且二者都是相似的方案,不考虑替代。
样例
Appcache fuzzer
Skia fuzzer
SQLite fuzzer
更多【外文翻译-【BlackHat】结构化模糊测试,议题学习】相关视频教程:www.yxfzedu.com