diff --git a/2000/01/01/hello-world/index.html b/2000/01/01/hello-world/index.html index 22d00ecd..eca5c539 100644 --- a/2000/01/01/hello-world/index.html +++ b/2000/01/01/hello-world/index.html @@ -580,7 +580,7 @@
- 31 + 33 标签
diff --git a/2018/11/16/BIBA访问控制模型实现(python)/index.html b/2018/11/16/BIBA访问控制模型实现(python)/index.html index e8c2b707..bf496337 100644 --- a/2018/11/16/BIBA访问控制模型实现(python)/index.html +++ b/2018/11/16/BIBA访问控制模型实现(python)/index.html @@ -752,7 +752,7 @@
- 31 + 33 标签
@@ -807,7 +807,7 @@ -
+
diff --git a/2018/12/15/miio-control/index.html b/2018/12/15/miio-control/index.html index 33aa6878..43c8b89c 100644 --- a/2018/12/15/miio-control/index.html +++ b/2018/12/15/miio-control/index.html @@ -654,7 +654,7 @@
- 31 + 33 标签
@@ -709,7 +709,7 @@ -
+
diff --git a/2018/12/23/基于规则引擎发现IOT设备/index.html b/2018/12/23/基于规则引擎发现IOT设备/index.html index 77ba925f..b6fbe3a0 100644 --- a/2018/12/23/基于规则引擎发现IOT设备/index.html +++ b/2018/12/23/基于规则引擎发现IOT设备/index.html @@ -654,7 +654,7 @@
- 31 + 33 标签
@@ -709,7 +709,7 @@ -
+
diff --git a/2018/12/25/TCPDUMP拒绝服务攻击漏洞/index.html b/2018/12/25/TCPDUMP拒绝服务攻击漏洞/index.html index 499e312e..5ccea283 100644 --- a/2018/12/25/TCPDUMP拒绝服务攻击漏洞/index.html +++ b/2018/12/25/TCPDUMP拒绝服务攻击漏洞/index.html @@ -659,7 +659,7 @@
- 31 + 33 标签
@@ -714,7 +714,7 @@ -
+
diff --git a/2019/01/16/wifi半双工侧信道攻击学习笔记/index.html b/2019/01/16/wifi半双工侧信道攻击学习笔记/index.html index 044e1623..b54ce6e4 100644 --- a/2019/01/16/wifi半双工侧信道攻击学习笔记/index.html +++ b/2019/01/16/wifi半双工侧信道攻击学习笔记/index.html @@ -782,7 +782,7 @@ Server -------wire----------|
- 31 + 33 标签
@@ -837,7 +837,7 @@ Server -------wire----------| -
+
diff --git a/2019/02/22/qq数据库的加密解密/index.html b/2019/02/22/qq数据库的加密解密/index.html index 8d362bb4..3dcd1c3d 100644 --- a/2019/02/22/qq数据库的加密解密/index.html +++ b/2019/02/22/qq数据库的加密解密/index.html @@ -631,7 +631,7 @@
- 31 + 33 标签
@@ -686,7 +686,7 @@ -
+
diff --git a/2019/03/16/小米固件工具mkxqimage/index.html b/2019/03/16/小米固件工具mkxqimage/index.html index cb278a67..16dda3b2 100644 --- a/2019/03/16/小米固件工具mkxqimage/index.html +++ b/2019/03/16/小米固件工具mkxqimage/index.html @@ -638,7 +638,7 @@
- 31 + 33 标签
@@ -693,7 +693,7 @@ -
+
diff --git a/2019/03/23/auto-send-WX/index.html b/2019/03/23/auto-send-WX/index.html index 02c41077..c30cf483 100644 --- a/2019/03/23/auto-send-WX/index.html +++ b/2019/03/23/auto-send-WX/index.html @@ -648,7 +648,7 @@
- 31 + 33 标签
@@ -703,7 +703,7 @@ -
+
diff --git a/2019/03/25/Samba-CVE/index.html b/2019/03/25/Samba-CVE/index.html index 3c0408f9..ccef016f 100644 --- a/2019/03/25/Samba-CVE/index.html +++ b/2019/03/25/Samba-CVE/index.html @@ -673,7 +673,7 @@
- 31 + 33 标签
@@ -728,7 +728,7 @@ -
+
diff --git a/2019/03/28/逆向工程实验/index.html b/2019/03/28/逆向工程实验/index.html index be000b10..165f5604 100644 --- a/2019/03/28/逆向工程实验/index.html +++ b/2019/03/28/逆向工程实验/index.html @@ -776,7 +776,7 @@
- 31 + 33 标签
@@ -831,7 +831,7 @@ -
+
diff --git a/2019/04/15/Caving-db-storage/index.html b/2019/04/15/Caving-db-storage/index.html index e7eb6f7e..bbe6d7b2 100644 --- a/2019/04/15/Caving-db-storage/index.html +++ b/2019/04/15/Caving-db-storage/index.html @@ -697,7 +697,7 @@
- 31 + 33 标签
@@ -752,7 +752,7 @@ -
+
diff --git a/2019/04/21/XIAOMI-UPnP/index.html b/2019/04/21/XIAOMI-UPnP/index.html index ecfcd64c..73455dbd 100644 --- a/2019/04/21/XIAOMI-UPnP/index.html +++ b/2019/04/21/XIAOMI-UPnP/index.html @@ -820,7 +820,7 @@
- 31 + 33 标签
@@ -875,7 +875,7 @@ -
+
diff --git a/2019/05/13/PE-file/index.html b/2019/05/13/PE-file/index.html index 55984e1a..5dd8b3cb 100644 --- a/2019/05/13/PE-file/index.html +++ b/2019/05/13/PE-file/index.html @@ -740,7 +740,7 @@
- 31 + 33 标签
@@ -795,7 +795,7 @@ -
+
diff --git a/2019/05/14/pack-and-unpack/index.html b/2019/05/14/pack-and-unpack/index.html index 28eb3761..b289b521 100644 --- a/2019/05/14/pack-and-unpack/index.html +++ b/2019/05/14/pack-and-unpack/index.html @@ -662,7 +662,7 @@
- 31 + 33 标签
@@ -717,7 +717,7 @@ -
+
diff --git a/2019/07/01/AFL-first-learn/index.html b/2019/07/01/AFL-first-learn/index.html index 004e277b..81817706 100644 --- a/2019/07/01/AFL-first-learn/index.html +++ b/2019/07/01/AFL-first-learn/index.html @@ -68,7 +68,7 @@ - + @@ -79,19 +79,20 @@ - + + - + - + - + @@ -445,29 +446,34 @@

接触这个词语已经有一年了,但还没有学习过更没有上手实践过,正好趁这个机会好好弄弄AFL。提起模糊测试,我们总会联想起这样或那样的专业术语——测试用例、代码覆盖率、执行路径等等,你可能和我一样一头雾水,这次我们就来看个明白

+

0x01 模糊测试

首先,模糊测试(Fuzzing)是一种测试手段,它把系统看成一个摸不清内部结构的黑盒,只是向其输入接口随机地发送合法测试用例,这些用例并不是开发者所预期的输入,所以极有可能会造成系统的崩溃,通过分析崩溃信息,测试人员(黑客)就可以评估系统是否存在可利用的漏洞。
模糊测试的过程,就好像是一个不断探测系统可以承受的输入极限的过程,让我想起学电子的时候对一个滤波器进行带宽的评估,如果我们知道内部电路原理,那么这个器件对于我们就是白盒了,可以直接通过公式计算理论带宽,现在系统对于我们而言是一个黑盒,我们通过在足够大频率范围内对其不断输入信号,就能测试出其实际带宽。

模糊测试方法一览


























基于变种的Fuzzer 基于模板的Fuzzer 基于反馈演进的Fuzzer
基于追踪路径覆盖率 基于分支覆盖率
在已知合法的输入的基础上,对该输入进行随机变种或者依据某种经验性的变种,从而产生不可预期的测试输入。 此类Fuzzer工具的输入数据,依赖于安全人员结合自己的知识,给出输入数据的模板,构造丰富的输入测试数据。 此类Fuzzer会实时的记录当前对于目标程序测试的覆盖程度,从而调整自己的fuzzing输入。
PAP:路径编码的算法;后面会产生路径爆炸的问题 漏洞的爆发往往由于触发了非预期的分支
Taof, GPF, ProxyFuzz, Peach Fuzzer SPIKE, Sulley, Mu‐4000, Codenomicon AFL
+

0x02 AFL快速入门

1)用make编译AFL。如果构建失败,请参阅docs / INSTALL以获取提示。
2)查找或编写一个相当快速和简单的程序,该程序从文件或标准输入中获取数据,以一种有价值的方式处理它,然后干净地退出。如果测试网络服务,请将其修改为在前台运行并从stdin读取。在对使用校验和的格式进行模糊测试时,也要注释掉校验和验证码。
遇到故障时,程序必须正常崩溃。注意自定义SIGSEGV或SIGABRT处理程序和后台进程。有关检测非崩溃缺陷的提示,请参阅docs/README中的第11节。
3)使用afl-gcc编译要模糊的程序/库。一种常见的方法是:

1
CC = / path / to / afl-gcc CXX = / path / to / afl-g ++ ./configure --disable shared make clean all

-

如果程序构建失败,请联系 afl-users@googlegroups.com
4)获取一个对程序有意义的小而有效的输入文件。在模糊详细语法(SQL,HTTP等)时,也要创建字典,如dictionaries/README.dictionaries中所述。
5)如果程序从stdin读取,则运行’afl-fuzz’,如下所示:
./afl-fuzz -i testcase_dir -o findings_dir -- \ /path/to/tested/program [... program's cmdline ...]
如果程序从文件中获取输入,则可以在程序的命令行中输入@@; AFL会为您放置一个自动生成的文件名。

+

如果程序构建失败,请联系 afl-users@googlegroups.com
4)获取一个对程序有意义的小而有效的输入文件。在模糊详细语法(SQL,HTTP等)时,也要创建字典,如dictionaries/README.dictionaries中所述。
5)如果程序从stdin读取,则运行’afl-fuzz’,如下所示:
./afl-fuzz -i testcase_dir -o findings_dir -- \ /path/to/tested/program [... program's cmdline ...]
如果程序从文件中获取输入,则可以在程序的命令行中输入@@; AFL会为您放置一个自动生成的文件名。

+

一些参考文档

docs/README - AFL的一般介绍,
docs/perf_tips.txt - 关于如何快速模糊的简单提示,
docs/status_screen.txt - UI中显示的花絮的解释,
docs/parallel_fuzzing.txt - 关于在多个核上运行AFL的建议
Generated test cases for common image formats - 生成图像文件测试用例的demo
Technical “whitepaper” for afl-fuzz - 技术白皮书

-

该工具已确认适用于32位和64位的x86 Linux,OpenBSD,FreeBSD和NetBSD。 它也适用于MacOS X和Solaris,但有一些限制。 它支持用C,C ++或Objective C编写的程序,使用gcc或clang编译。 在Linux上,可选的QEMU模式也允许对黑盒二进制文件进行模糊测试。

+

适用环境
该工具已确认适用于32位和64位的x86 Linux,OpenBSD,FreeBSD和NetBSD。 它也适用于MacOS X和Solaris,但有一些限制。 它支持用C,C ++或Objective C编写的程序,使用gcc或clang编译。 在Linux上,可选的QEMU模式也允许对黑盒二进制文件进行模糊测试。

AFL的变体和衍生物允许您模糊Python,Go,Rust,OCaml,GCJ Java,内核系统调用,甚至整个虚拟机。 还有一个密切启发的进程模糊器,它在LLVM中运行,并且是一个在Windows上运行的分支。 最后,AFL是OSS-Fuzz背后的模糊引擎之一。

哦 - 如果你安装了gnuplot,你可以使用afl-plot来获得漂亮的进度图。

+

0x03 AFL

  1. 非常复杂。它是一种插桩器(instrumentation)引导的遗传模糊器,能够在各种非平凡的目标中合成复杂的文件语义,减少了对专用的语法识别工具的需求。它还带有一个独特的崩溃浏览器,一个测试用例最小化器,一个故障触发分配器和一个语法分析器 - 使评估崩溃错误的影响变得简单。
  2. 智能。它围绕一系列经过精心研究,高增益的测试用例预处理和模糊测试策略而构建,在其他模糊测试框架中很少采用与之相当的严格性。结果,它发现了真正的漏洞
  3. 它很快。由于其低级编译时间或仅二进制检测和其他优化,该工具提供了针对常见现实世界目标的近原生或优于原生的模糊测试速度。新增的持久模式允许在最少的代码修改的帮助下,对许多程序进行异常快速的模糊测试。
  4. 可以链接到其他工具。模糊器可以生成优质,紧凑的测试语料库,可以作为更专业,更慢或劳动密集型流程和测试框架的种子。它还能够与任何其他软件进行即时语料库同步。
+

0x04 AFL README

-

Written and maintained by Michal Zalewski lcamtuf@google.com

+

Written and maintained by Michal Zalewski lcamtuf@google.com

Copyright 2013, 2014, 2015, 2016 Google Inc. All rights reserved.
Released under terms and conditions of Apache License, Version 2.0.

For new versions and additional information, check out:
http://lcamtuf.coredump.cx/afl/

-

To compare notes with other users or get notified about major new features,
send a mail to afl-users+subscribe@googlegroups.com.

+

To compare notes with other users or get notified about major new features,
send a mail to afl-users+subscribe@googlegroups.com.

See QuickStartGuide.txt if you don’t have time to read this file.

1)具有导向性的模糊测试的挑战

Fuzzing是用于识别真实软件中的安全问题的最强大且经过验证的策略之一;它负责安全关键软件中迄今为止发现的绝大多数远程代码执行和权限提升漏洞。
不幸的是,模糊测试也不够有力。盲目的、随机的变异使得它不太可能在测试代码中达到某些代码路径,从而使一些漏洞超出了这种技术的范围。
已经有许多尝试来解决这个问题。早期方法之一 - 由Tavis Ormandy开创 - 是一种语义库蒸馏(corpus distillation)。网上找到的一些大型语料库中往往包含大量的文件,这时就需要对其精简,该方法依赖于覆盖信号从大量高质量的候选文件语料库中选择有趣种子的子集,然后通过传统方式对其进行模糊处理。该方法非常有效,但需要这样的语料库随时可用。正因为如此,代码覆盖率也只是衡量程序执行状态的一个简单化的度量,这种方式并不适合后续引导fuzzing测试的。
其他更复杂的研究集中在诸如程序流分析(“concoic execution”),符号执行或静态分析等技术上。所有这些方法在实验环境中都非常有前景,但在实际应用中往往会遇到可靠性和性能问题 - 部分高价值的程序都有非常复杂的内部状态和执行路径,在这一方面符号执行和concolic技术往往会显得不够健壮(如路径爆炸问题),所以仍然稍逊于传统的fuzzing技术。

@@ -535,6 +541,7 @@
  • AFL不输出人类可读的覆盖数据。如果你想监控覆盖,请使用Michael Rash的afl-cov:https://github.com/mrash/afl-cov
  • 偶尔,敏感的机器会对抗他们的创造者。如果您遇到这种情况,请访问http://lcamt​​uf.coredump.cx/prep/。除此之外,请参阅安装以获取特定于平台的提示。
  • +

    0x05 afl-fuzz白皮书

    本文档提供了American Fuzzy Lop的简单的概述。想了解一般的使用说明,请参见README 。想了解AFL背后的动机和设计目标,请参见historical_notes.txt

    0)设计说明(Design statement)

    American Fuzzy Lop 不关注任何单一的操作规则(singular principle of
    operation),也不是一个针对任何特定理论的概念验证(proof of concept)。这个工具可以被认为是一系列在实践中测试过的hacks行为,我们发现这个工具惊人的有效。我们用目前最simple且最robust的方法实现了这个工具。
    唯一的设计宗旨在于速度、可靠性和易用性。

    1)覆盖率计算(Coverage measurements)

    在编译过的程序中插桩能够捕获分支(边缘)的覆盖率,并且还能检测到粗略的分支执行命中次数(branch-taken hit counts)。在分支点注入的代码大致如下:

    @@ -707,18 +714,18 @@

    “favored” entries产生的语料,会比初始的数据集小5到10倍。没有被选择的也没有被扔掉,而是在遇到下列对队列时,以一定概率略过:

    1
    2
    3
    4
    5
    6
    7
    8
    - If there are new, yet-to-be-fuzzed favorites present in the queue,
    99% of non-favored entries will be skipped to get to the favored ones.

    - If there are no new favorites:

    - If the current non-favored entry was fuzzed before, it will be skipped 95% of the time.

    - If it hasn't gone through any fuzzing rounds yet, the odds of skipping drop down to 75%.

    基于以往的实验经验,这种方法能够在队列周期速度(queue cycling speed)和测试用例多样性(test case diversity)之间达到一个合理的平衡。
    使用afl-cmin工具能够对输入或输出的语料库进行稍微复杂但慢得多的的处理。这一工具将永久丢弃冗余entries,产生适用于afl-fuzz或者外部工具的更小的语料库。

    5)输入文件修剪(Trimming input files)

    文件的大小对fuzzing的性能有着重大影响(dramatic impact)。因为大文件会让目标二进制文件运行变慢;大文件还会减少变异触及重要格式控制结构(format control structures)的可能性(我们希望的是变异要触及冗余代码块(redundant data blocks))。这个问题将在perf_tips.txt细说。
    用户可能提供低质量初始语料(starting corpus),某些类型的变异会迭代地增加生成文件的大小。所以要抑制这种趋势(counter this trend)。
    幸运的是,插桩反馈(instrumentation feedback)提供了一种简单的方式自动削减(trim down)输入文件,并确保这些改变能使得文件对执行路径没有影响。
    afl-fuzz内置的修剪器(trimmer)使用变化的长度和步距(variable length and stepover)来连续地(sequentially)删除数据块;任何不影响trace map的校验和(checksum)的删除块将被提交到disk。
    这个修剪器的设计并不算特别地周密(thorough),相反地,它试着在精确度(precision)和进程调用execve()的次数之间选取一个平衡,找到一个合适的block size和stepover。平均每个文件将增大约5-20%。
    独立的afl-tmin工具使用更完整(exhaustive)、迭代次数更多(iteractive)的算法,并尝试对被修剪的文件采用字母标准化的方式处理。

    -

    6)模糊测试策略(Fuzzing strategies)

    插桩提供的反馈(feedback)使得我们更容易理解各种不同fuzzing策略的价值,从而优化(optimize)他们的参数。使得他们对不同的文件类型都能同等地进行工作。afl-fuzz用的策略通常是与格式无关(format-agnostic),详细说明在下边的连接中:
    binary-fuzzing-strategies-what-works
    值得注意的一点是,afl-fuzz大部分的(尤其是前期的)工作都是高度确定的(highly deterministic),随机性修改和测试用例拼接(random stacked modifications和test case splicing)只在后期的部分进行。确定性的策略包括:

    1
    2
    3
    4
    5
    - Sequential bit flips with varying lengths and stepovers,使用变化的长度和步距来连续进行位反转

    - Sequential addition and subtraction of small integers,对小的整型数来连续进行加法和减法

    - Sequential insertion of known interesting integers (0, 1, INT_MAX, etc),对已知的感兴趣的整型数连续地插入

    +

    6) 模糊测试策略(Fuzzing strategies)

    插桩提供的反馈(feedback)使得我们更容易理解各种不同fuzzing策略的价值,从而优化(optimize)他们的参数。使得他们对不同的文件类型都能同等地进行工作。afl-fuzz用的策略通常是与格式无关(format-agnostic),详细说明在下边的连接中:
    binary-fuzzing-strategies-what-works
    值得注意的一点是,afl-fuzz大部分的(尤其是前期的)工作都是高度确定的(highly deterministic),随机性修改和测试用例拼接(random stacked modifications和test case splicing)只在后期的部分进行。确定性的策略包括:

    1
    2
    3
    4
    5
    - Sequential bit flips with varying lengths and stepovers,使用变化的长度和步距来连续进行位反转

    - Sequential addition and subtraction of small integers,对小的整型数来连续进行加法和减法

    - Sequential insertion of known interesting integers (0, 1, INT_MAX, etc),对已知的感兴趣的整型数连续地插入

    使用这些确定步骤的目的在于,生成紧凑的(compact)测试用例,以及在产生non-crashing的输入和产生crashing的输入之间,有很小的差异(small diffs)。
    非确定性(non-deterministic)策略的步骤包括:stacked bit flips、插入(insertions)、删除(deletions)、算数(arithmetics)和不同测试用例之间的拼接(splicing)。

    由于在historical_notes.txt 中提到的原因(性能、简易性、可靠性),AFL通常不试图去推断某个特定的变异(specific mutations)和程序状态(program states)的关系。

    fuzzing的步骤名义上来说是盲目的(nominally blind),只被输入队列的进化方式的设计所影响(见第三部分)。

    这意味着,这条规则有一个例外:
    当一个新的队列条目,经过初始的确定性fuzzing步骤集合时,并且文件的部分区域被观测到对执行路径的校验和没有影响,这些队列条目在接下来的确定性fuzzing阶段可能会被排除。
    尤其是对那些冗长的数据格式,这可以在保持覆盖率不变的情况下,减少10-40%的执行次数。在一些极端情况下,比如一些block-aligned的tar文件,这个数字可以达到90%。

    -

    7)字典(Dictionaries)

    插桩提供的反馈能够让它自动地识别出一些输入文件中的语法(syntax)符号(tokens),并且能够为测试器(tested parser)检测到一些组合,这些组合是由预定义(predefined)的或自动检测到的(auto-detected)字典项(dictionary terms)构成的合法语法(valid grammar)。
    关于这些特点在afl-fuzz是如何实现的,可以看一下这个链接:
    afl-fuzz-making-up-grammar-with
    大体上,当基本的(basic, typically easily-obtained)句法(syntax)符号(tokens)以纯粹随机的方式组合在一起时,插桩队列进化这两种方法共同提供了一种反馈机制,这种反馈机制能够区分无意义的变异和在插桩代码中触发新行为的变异。这样能增量地构建更复杂的句法(syntax)。
    这样构建的字典能够让fuzzer快速地重构非常详细(highly verbose)且复杂的(complex)语法,比如JavaScript, SQL,XML。一些生成SQL语句的例子已经在之前提到的博客中给出了。
    有趣的是,AFL的插桩也允许fuzzer自动地隔离(isolate)已经在输入文件中出现过的句法(syntax)符号(tokens)。

    -

    8)崩溃去重(De-duping crashes)

    崩溃去重是fuzzing工具里很重要的问题之一。很多naive的解决方式都会有这样的问题:如果这个错误发生在一个普通的库函数中(如say, strcmp, strcpy),只关注出错地址(faulting address)的话,那么可能导致一些完全不相关的问题被分在一类(clustered together)。如果错误发生在一些不同的、可能递归的代码路径中,那么校验和(checksumming)调用栈回溯(call stack backtraces)时可能导致crash count inflation(通胀)。

    +

    7) 字典(Dictionaries)

    插桩提供的反馈能够让它自动地识别出一些输入文件中的语法(syntax)符号(tokens),并且能够为测试器(tested parser)检测到一些组合,这些组合是由预定义(predefined)的或自动检测到的(auto-detected)字典项(dictionary terms)构成的合法语法(valid grammar)。
    关于这些特点在afl-fuzz是如何实现的,可以看一下这个链接:
    afl-fuzz-making-up-grammar-with
    大体上,当基本的(basic, typically easily-obtained)句法(syntax)符号(tokens)以纯粹随机的方式组合在一起时,插桩队列进化这两种方法共同提供了一种反馈机制,这种反馈机制能够区分无意义的变异和在插桩代码中触发新行为的变异。这样能增量地构建更复杂的句法(syntax)。
    这样构建的字典能够让fuzzer快速地重构非常详细(highly verbose)且复杂的(complex)语法,比如JavaScript, SQL,XML。一些生成SQL语句的例子已经在之前提到的博客中给出了。
    有趣的是,AFL的插桩也允许fuzzer自动地隔离(isolate)已经在输入文件中出现过的句法(syntax)符号(tokens)。

    +

    8) 崩溃去重(De-duping crashes)

    崩溃去重是fuzzing工具里很重要的问题之一。很多naive的解决方式都会有这样的问题:如果这个错误发生在一个普通的库函数中(如say, strcmp, strcpy),只关注出错地址(faulting address)的话,那么可能导致一些完全不相关的问题被分在一类(clustered together)。如果错误发生在一些不同的、可能递归的代码路径中,那么校验和(checksumming)调用栈回溯(call stack backtraces)时可能导致crash count inflation(通胀)。

    afl-fuzz的解决方案认为满足一下两个条件,那么这个crash就是唯一的(unique):

    1
    2
    - The crash trace includes a tuple not seen in any of the previous crashes,这个crash的路径包括一个之前crash从未见到过的tuple。
    - The crash trace is missing a tuple that was always present in earlier faults.这个crash的路径不包含一个总在之前crash中出现的tuple。

    这种方式一开始容易受到count inflation的影响,但实验表明其有很强的自我限制效果。和执行路径分析一样,这种崩溃去重的方式是afl-fuzz的基石(cornerstone)。

    -

    9)崩溃调查(Investigating crashes)

    不同的crash的可用性(exploitability)是不同的。afl-fuzz提供一个crash的探索模式(exploration mode)来解决这个问题。
    对一个已知的出错测试用例,它被fuzz的方式和正常fuzz的操作没什么不同,但是有一个限制能让任何non-crashing 的变异(mutations)会被丢弃(thrown away)。
    这种方法的意义在以下链接中会进一步讨论:
    afl-fuzz-crash-exploration-mode
    这种方法利用instrumentation的反馈,探索crash程序的状态,从而进一步通过歧义性的失败条件,找到了最新发现的input。
    对于crashes来说,值得注意的是和正常的队列条目对比,导致crash的input没有被去掉,为了和它们的父条目(队列中没有导致crash的条目)对比,它们被保存下来,
    这就是说afl-tmin可以被用来随意缩减它们。

    -

    10)The fork server

    为了提升性能,afl-fuzz使用了一个”fork server”,fuzz的进程只进行一次execve(), 连接(linking), 库初始化(libc initialization)。fuzz进程通过copy-on-write(写时拷贝技术)从已停止的fuzz进程中clone下来。实现细节在以下链接中:
    afl-fuzz-crash-exploration-mode
    fork server被集成在了instrumentation的程序下,在第一个instrument函数执行时,fork server就停止并等待afl-fuzz的命令。
    对于需要快速发包的测试,fork server可以提升1.5到2倍的性能。

    -

    11)并行机制

    实现并行的机制是,定期检查不同cpu core或不同机器产生的队列,然后有选择性的把队列中的条目放到test cases中。
    详见: parallel_fuzzing.txt.

    +

    9) 崩溃调查(Investigating crashes)

    不同的crash的可用性(exploitability)是不同的。afl-fuzz提供一个crash的探索模式(exploration mode)来解决这个问题。
    对一个已知的出错测试用例,它被fuzz的方式和正常fuzz的操作没什么不同,但是有一个限制能让任何non-crashing 的变异(mutations)会被丢弃(thrown away)。
    这种方法的意义在以下链接中会进一步讨论:
    afl-fuzz-crash-exploration-mode
    这种方法利用instrumentation的反馈,探索crash程序的状态,从而进一步通过歧义性的失败条件,找到了最新发现的input。
    对于crashes来说,值得注意的是和正常的队列条目对比,导致crash的input没有被去掉,为了和它们的父条目(队列中没有导致crash的条目)对比,它们被保存下来,
    这就是说afl-tmin可以被用来随意缩减它们。

    +

    10) The fork server

    为了提升性能,afl-fuzz使用了一个”fork server”,fuzz的进程只进行一次execve(), 连接(linking), 库初始化(libc initialization)。fuzz进程通过copy-on-write(写时拷贝技术)从已停止的fuzz进程中clone下来。实现细节在以下链接中:
    afl-fuzz-crash-exploration-mode
    fork server被集成在了instrumentation的程序下,在第一个instrument函数执行时,fork server就停止并等待afl-fuzz的命令。
    对于需要快速发包的测试,fork server可以提升1.5到2倍的性能。

    +

    11) 并行机制

    实现并行的机制是,定期检查不同cpu core或不同机器产生的队列,然后有选择性的把队列中的条目放到test cases中。
    详见: parallel_fuzzing.txt.

    12)二进制instrumentation

    AFL-Fuzz对二进制黑盒目标程序的instrumentation是通过QEMU的“user emulation”模式实现的。
    这样我们就可以允许跨架构的运行,比如ARM binaries运行在X86的架构上。
    QEMU使用basic blocks作为翻译单元,利用QEMU做instrumentation,再使用一个和编译期instrumentation类似的guided fuzz的模型。

    1
    2
    3
    4
    5
    6
    7
    if (block_address > elf_text_start && block_address < elf_text_end) {

    cur_location = (block_address >> 4) ^ (block_address << 8);
    shared_mem[cur_location ^ prev_location]++;
    prev_location = cur_location >> 1;

    }

    像QEMU, DynamoRIO, and PIN这样的二进制翻译器,启动是很慢的。QEMU mode同样使用了一个fork server,和编译期一样,通过把一个已经初始化好的进程镜像,直接拷贝到新的进程中。
    当然第一次翻译一个新的basic block还是有必要的延迟,为了解决这个问题AFL fork server在emulator和父进程之间提供了一个频道。这个频道用来通知父进程新添加的blocks的地址,之后吧这些blocks放到一个缓存中,以便直接复制到将来的子进程中。这样优化之后,QEMU模式对目标程序造成2-5倍的减速,相比之下,PIN造成100倍以上的减速。

    13)afl-analyze工具

    文件格式分析器是最小化算法的简单扩展
    前面讨论过; 该工具执行一系列步行字节翻转,然后在输入文件中注释字节运行,而不是尝试删除无操作块。

    @@ -766,6 +773,14 @@