AFL的介绍

本文档是对AFL(American Fuzzy Lop)的README.txt的解读和总结,主要涵盖了AFL的工作原理和核心概念。它解释了queue/目录中合成的corpus测试用例,crashes/目录下导致程序崩溃的独特案例,以及hangs/目录中使程序超时的测试用例。此外,提到了如何使用afl-cmin工具来减小测试用例的大小。
部署运行你感兴趣的模型镜像

参考了http://blog.youkuaiyun.com/gengzhikui1992/article/details/50829114中对一些语句的理解,对AFL的README.txt进行了总结。。

1. guided fuzzing 的挑战
Fuzzing 是漏洞挖掘领域最有效的方法之一,可以用来发现大量的远程代码执行和提权的漏洞。然而, fuzzing 优势相对肤浅和盲目的。随机变异使得我们很难实现达到测试程序特定的代码路径。这就使得测试的代码覆盖率很低。
有很多人试图去解决这个问题, Tavis Ormandy 曾经提出一种:语料精馏法。这个方法根据代码覆盖率,从大量高质量的输入文件语料中选取一个子集,然后按照传统方法去 fuzz 。这种方法很有效,但前提是需要一个这样的语料。另一方面,代码覆盖率只提供了一个很简单的对程序状态的描述,当 Fuzzing 测试到了一定的程度,代码覆盖率就没什么作用了。
所以,大家都在探索更复杂的技术,比如:程序控制流分析,符号执行或静态分析。这些技术在实验中是很有前途的,但是在实际应用中显得效率低下、缺乏可靠性。
2. AFL 的方案
AFL 是一个暴力方法的 fuzzer ,采用了一个极其简单但是绝对可靠的,插桩代码导向的遗传算法。
它使用 一种自定义的边缘覆盖率 来识别程序控制流的局部变化。
简单来说,整个算法的逻辑如下:
  1) Load user-supplied initial test cases into the queue,

  2) Take next input file from the queue,

  3) Attempt to trim the test case to the smallest size that doesn't alter
     the measured behavior of the program,

  4) Repeatedly mutate the file using a balanced and well-researched variety
     of traditional fuzzing strategies,

  5) If any of the generated mutations resulted in a new state transition
     recorded by the instrumentation, add mutated output as a new entry in the
     queue.

  6) Go to 2.


被选择出来的测试用例会进行周期性的删减,消除那些已经被更新的、更高覆盖率的废弃的测试用例。
整个 fuzzing 过程,会产生一个很有用的 测试 集合的语料库,可以用来对一些浏览器、 office 应用、闭源的软件等进行压力测试。
经测试, AFL 的性能,比那些 blind fuzzing 或者 coverage-only 工具高多了。

3. 使用 AFL 插桩程序(有源码的情况下 instrument
当有源代码时,我们可以在编译期间进行instrument,这种instrument对性能影响很小。
gcc/g++重新编译目标程序的方法是:
CC=/path/to/afl/afl-gcc ./configure
make clean all
对于C++程序,还要设置:
CXX=/path/to/afl/afl-g++.
afl-clang和afl-clang++的使用方法类似。clang用户还可以选择更高效的插桩模式,参考llvm_mode/README.llvm
当测试libraries的时候,我们需要写一个小程序,从stdin中或者一个文件中读取数据,然后传到被测试的libraries中。这种情况下,我们必须把插桩好的库的静态版本与可执行文件链接起来,或者确保运行时加载正确的.so文件。最简单的方法是静态构建,方法如下:
$ CC=/path/to/afl/afl-gcc ./configure –disable-shared
如果设置AFL_HARDEN=1,当调用‘make’时会导致CC自动启动代码hardening选项,使得检测内存bug更简单。Libdislocator,是AFL的一个辅助库(在Libdislocator/README.dislocator中),可以帮助发现heap corruption堆溢出问题。
4.   对无源码二进制 instrument 所以最好还是对有源码,开源的程序进行 fuzz
AFL对没有源代码的程序提供的黑盒二进制instrument支持是实验性的。通过qemu的 用户级(userland) 仿真实现。
QEMU是独立于AFL的工程,但是在AFL中也提供了便于实现该功能的方式:
$ cd qemu_mode
$ ./build_qemu_support.sh
更多的说明和注意事项,在qemu_mode/README.qemu中。
这种模式比编译时instrument慢2到5倍,而且不利于并行处理    
5.   选取初始测试样例
为了正确操作,AFL一开始需要有一个可以被目标程序正确读取的输入样例。选择输入样例的两条基本准则:
-文件尽可能小。低于1kb是理想的,虽然不是必要的。
-选择的样例尽可能在功能上不相同,比如:fuzz照片程序时,没有必要用50个不同的风景照
PS:  
如果有大量数据可用于筛选,可以使用afl-cmin功能来识别在目标程序中执行不同代码路径的功能不同的文件的子集。
afl-cmin用来从大量数据中筛选出合适的子集作为初始test case。
注意:afl-cmin是对一个文件夹中的所有testcase进行删减达到最小化。
6.   开始 Fuzzing
afl-fuzz负责进行fuzzing的过程,需要指定一个初始test cases的输入目录、一个存放findings结构的输出目录和要测试的目标程序的路径。
对那些可以直接从stdin读取输入的目标程序来说,语法如下:
$ ./afl-fuzz -i testcase_dir -o findings_dir /path/to/program […params…]
对从文件读取输入的目标程序来说,要用 @@”,语法如下:
$ ./afl-fuzz -i testcase_dir -o findings_dir /path/to/program @@
也可以用-f选项,把变异数据写到一个指定的文件。
对于没有被instrument的二进制目标程序 ,可以用qemu模式(-Q)进行fuzz,或者直接用传统blind-fuzzer模式(-n)。
使用-t和-m选项,修改fuzz过程的默认timeout和memory limit。
一般afl-fuzz在开始时会执行一系列的确定性fuzzing步骤,这会花费几天的时间,但是会生成更neat的testcase。如果你想要快速运行、马上生成dirty的结果----类似于zzuf和其他传统fuzzer----可以使用-d选项,跳过确定性fuzzing步骤。
7. fuzzing 的输出文件
有关如何解释显示的统计信息和监视进程的运行状况的信息,请参阅status_screen.txt文件。
Fuzzing过程中,会在输出目录中创建3个子目录并实时更新:
  • queue/ - 每个独特执行路径的test case,加上用户给定的初始文件。这就是the synthesized corpus合成语料库可以使用afl-cmin缩小size
  • crashes/ - 导致程序接收fatal信号(e.g., SIGSEGV, SIGILL, SIGABRT)的unique test case。会根据信号的不同进行分组。
  • hangs/ - unique test cases that cause the tested program to time out.
如果相关联的执行路径包含在先前记录的故障中未见到的任何状态转换,则崩溃和挂起被认为是 unique”。
Crashes and hangs are considered "unique" if the associated execution paths involve any state transitions not seen in previously-recorded faults. 
The file names for crashes and hangs are correlated with parent, non-faulting queue entries. This should help with debugging.
   crash和hang的文件名与parent和非故障队列条目有关 。这应该有助于调试。
当您无法重现由afl-fuzz发现的崩溃时,最可能的原因是您没有设置与该工具使用的内存限制相同。尝试:
$ LIMIT_MB=50
$ ( ulimit -Sv $[LIMIT_MB << 10]; /path/to/tested_binary ... )
更改LIMIT_MB以匹配传递给afl-fuzz的-m参数。
任何现有输出目录也可用于恢复已中止的jobs;try:
$ ./afl-fuzz -i- -o existing_output_dir [...etc...]  //-i之后并没有输入目录,而是一个连接符,
如果您安装了gnuplot,您还可以使用afl-plot为任何活动的模糊任务生成一些漂亮的图形。
8 、并行 Fuzzing
afl-fuzz的每个实例都占用大约一个核心。 这意味着在多核系统上,并行化是必须的以充分利用硬件。 有关如何在多个内核或多个网络机器上fuzz一个共同目标的提示,请参阅parallel_fuzzing.txt。
并行Fuzzing模式还提供了一种用于将AFL与其他模糊器,符号执行或者concolic混合符号执行引擎等连接的简单方法;  请参阅parallel_fuzzing.txt的最后一节提示。
9 Fuzzer dictionaries 字典
afl-fuzz变异引擎针对紧凑的数据格式(即,图像,多媒体,压缩数据,正则表达式语法或shell脚本进行了优化。它有点不太适合特别冗长和冗余的语言 - 尤其包括HTML,SQL或JavaScript。
为了避免构建语法感知工具的麻烦,afl-fuzz提供了一种使用语言关键字,magic header或其他与目标数据类型相关联的特殊表示的可选字典为模糊过程提供种子的方法 - 并且使用它来重建底层语法,参考:
要使用这个功能,首先需要创建在dictionaries/README.dictionaries中讨论的两种格式之一的字典;然后在命令行中使用-x选项将fuzzer指向它。(在该目录的子目录下已经提供了几个常用字典)
没有办法提供更多结构化的底层语法的描述,但是fuzzer可能会根据单独的插桩反馈来找出其中的一些。 参考:
PS:
即使当没有给出明确的字典时,afl-fuzz将通过在确定性字节翻转期间非常仔细地观察插桩来尝试提取输入语料库中的现有语法表示(token-表示,记号)。 这适用于一些类型的解析器和语法,但不像 -x模式 那么好。
如果字典真的很难得到,另一个选择是让AFL运行一段时间,然后使用AFL自带的表示捕获库。 有关详细信息,请参阅libtokencap/README.tokencap。
http://volatileminds.net/2015/08/20/advanced-afl-usage-preeny.html 中有关于字典的使用和简单介绍。
10 crash 分类 Crash triage
基于覆盖的崩溃分组通常生成一个小数据集,可以手动或使用非常简单的GDB或Valgrind脚本快速分类。每个崩溃也可追溯到其在queue中的非崩溃的parent测试用例,从而更容易诊断故障。
afl-fuzz的支持一个崩溃探索模式,使用-C标志。 https://lcamtuf.blogspot.com/2014/11/afl-fuzz-crash-exploration-mode.html
在这种模式下,模糊器需要一个或多个崩溃的测试用例作为输入,并使用其反馈驱动的fuzzing策略来快速枚举程序中可以到达的所有代码路径,同时保持其处于崩溃状态。
不导致崩溃的变异被拒绝; 任何不影响执行路径的更改也一样。
  输出是一个小文件库,可以快速检查攻击者对故障地址的控制程度,或者是否有可能通过一个初始的越界读取,以及查看下面的内容 。 
    
afl-tmin工具 适用于crash和non-crash的test case。用于test case 最小化!注意: afl-tmin是对一个文件的无用字节、bit的删减以达到最小化。
$ ./afl-tmin -i test_case -o minimized_result -- /path/to/program [...]
afl-analyze工具。它需要一个输入文件,尝试顺序翻转字节,并观察被测试程序的行为。然后对输入进行颜色编码,基于哪些部分看起来是关键的,哪些部分不是;虽然不是防弹,它通常可以提供对复杂文件格式的快速洞察。
11 Going beyond crashes
     Fuzzing is a wonderful and underutilized technique for discovering non-crashing design and implementation errors, too. Quite a few interesting bugs have been found by modifying the target programs to call abort() when,say:
-Two bignum libraries produce different outputs when given the same fuzzer-generated input,
- An image library produces different outputs when asked to decode the same input image several times in a row,
  - A serialization / deserialization library fails to produce stable outputs when iteratively serializing and deserializing fuzzer-supplied data,
  - A compression library produces an output inconsistent with the input file
    when asked to compress and then decompress a particular blob.

Implementing these or similar sanity checks usually takes very little time;
if you are the maintainer of a particular package, you can make this code
conditional with #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION (a flag also
shared with libfuzzer) or #ifdef __AFL_COMPILER (this one is just for AFL).
12 、常识性的风险 Common-sense risks
与其他计算密集型任务类似,fuzzing可能会给你的硬件或系统带来压力, A good way to monitor disk I/O on Linux is the 'iostat' command:
$ iostat -d 3 -x -k [...optional disk ID...]
13 、已知的限制和改进的领域 Known limitations & areas for improvement
       -AFL 通过检查由于信号( SIGSEGV SIGABRT 等)导致的第一个引起的进程死亡来检测故障。为这些信号安装自定义处理程序的程序可能需要注释掉相关代码。同样,由目标产生的子处理中的错误可能会逃避检测,除非您手动添加一些代码来捕获它。
    -与任何其他强力工具一样,如果使用加密,校验和,加密签名或压缩来完全包装要测试的实际数据格式,则模糊器提供有限的覆盖率。
要解决这个问题,你可以注释掉相关的检查;如果这是不可能的,你也可以写一个后处理器postprocessor,参考experimental/post_library/。
-有一些不幸的折衷对于ASAN和64位二进制。这不是由于afl-fuzz的任何特定故障;请参阅notes_for_asan.txt提示。
-没有直接支持fuzzing网络服务,后台守护进程或需要UI交互工作的交互式应用程序。您可能需要进行简单的代码更改,以使它们以更传统的方式运行。Preeny可以提供一个相对简单的选项,看看:
  https://github.com/zardus/preeny
有关修改基于网络的服务的一些有用的提示还可以在以下网址找到:https://www.fastly.com/blog/how-to-fuzz-server-american-fuzzy-lop
-AFL不输出人类可读的覆盖数据。如果你想监视覆盖,使用afl-cov从Michael Rash: https://github.com/mrash/afl-cov
-偶尔,有意识的机器反对他们的创造者。如果发生这种情况,请参阅http://lcamtuf.coredump.cx/prep/。

您可能感兴趣的与本文相关的镜像

Qwen3-8B

Qwen3-8B

文本生成
Qwen3

Qwen3 是 Qwen 系列中的最新一代大型语言模型,提供了一整套密集型和专家混合(MoE)模型。基于广泛的训练,Qwen3 在推理、指令执行、代理能力和多语言支持方面取得了突破性进展

<think>好的,用户想了解AFL(American Fuzzy Lop)模糊测试工具的相关信息。首先,我需要回忆关于AFL的基本知识,确保信息准确。根据提供的引用,AFL是一个面向安全的模糊测试工具,主要用于发现软件漏洞。接下来,我需要整理这些信息,分点介绍AFL的特点、工作流程和运行模式。 首先,用户可能需要知道AFL是什么,有什么特点。根据引用[2],AFL是一个安全导向的模糊测试工具,支持有源码和无源码的程序测试。需要强调它的覆盖率引导和高效性,比如使用遗传算法和轻量级插桩技术。 然后,工作流程部分可以参考引用[4]和[5],比如初始化语料库、模糊测试循环、结果分类等步骤。要解释清楚每个阶段的作用,比如如何生成测试用例,如何检测异常情况。 运行模式方面,引用[3]和[4]提到有源码和无源码测试的不同方法,比如使用afl-gcc编译或QEMU模式。同时,需要提到fork server机制,如引用[5]中提到的run_target()方法,说明其如何提高效率。 最后,应用场景部分需要结合引用[3]和[4]中的例子,比如测试FFmpeg或现有C程序,展示AFL的实际用途。还要确保引用标识正确,比如提到语料库管理时引用[4],提到安装和运行界面时引用[2]和[3]。 可能用户还需要知道如何安装和使用AFL,但根据问题,主要问的是介绍,所以可能不需要详细步骤,但需要提到相关引用。此外,要检查是否所有技术术语都用中文正确表达,比如“覆盖率引导”等。 生成的相关问题需要涵盖工具的原理、优化、应用和比较,确保用户能进一步探索。例如,如何优化AFL性能,或者与libFuzzer的区别,这些可能都是用户感兴趣的点。 需要确保回答结构清晰,每个部分有明确的标题,使用列表和代码块展示命令示例,符合格式要求。同时,所有数学表达式或代码部分使用正确的LaTeX或代码格式,但根据用户问题,这里可能不需要数学表达式,但代码块要正确。 最后,核对所有引用标记是否正确对应,比如引用[1]是关于性能分析,而引用[4]和[5]是关于语料库和运行机制。确保没有遗漏重要信息,并且内容连贯易懂。</think>### American Fuzzy Lop (AFL) 模糊测试工具介绍 AFL(American Fuzzy Lop)是一款面向安全的**覆盖率引导模糊测试工具**,专注于通过自动化生成测试用例来发现软件中的漏洞。以下是其核心特点和工作原理: --- #### **核心特点** 1. **覆盖率引导** 通过轻量级插桩(instrumentation)实时追踪程序执行路径,优先选择覆盖新代码分支的测试用例,优化模糊测试效率[^4]。 2. **高效性** 使用遗传算法生成输入,并通过并行化(多实例协同)加速测试过程。 3. **兼容性** - **有源码程序**:通过`afl-gcc`、`afl-clang`等编译器插桩[^3]。 - **无源码程序**:借助QEMU模式进行二进制级插桩[^3]。 4. **结果分类** 测试结果分为三类目录:`queue/`(覆盖新路径的输入)、`crashes/`(触发崩溃的输入)、`hangs/`(超时输入)[^4]。 --- #### **工作流程** 1. **初始化语料库** 提供初始测试用例(如简单文本文件),AFL通过插桩分析程序行为。 2. **模糊测试循环** - **变异输入**:对语料库中的文件进行比特翻转、块替换等变异操作。 - **执行监控**:运行目标程序并记录代码覆盖率。 - **反馈优化**:保留触发新路径的输入,更新语料库。 3. **结果检测** 异常输入(如崩溃、超时)会被分类存储以供分析[^4]。 --- #### **运行模式示例** ```bash # 有源码测试(使用插桩编译) CC=afl-gcc ./configure make # 启动模糊测试 afl-fuzz -i input_dir -o output_dir ./target_program @@ # 无源码测试(QEMU模式) afl-fuzz -Q -i input_dir -o output_dir ./target_binary @@ ``` --- #### **应用场景** 1. **漏洞挖掘** 用于测试开源软件(如FFmpeg)或闭源二进制程序[^3]。 2. **代码健壮性验证** 通过大规模输入生成,检测程序边界条件处理能力。 3. **结合其他工具** 如LibFuzzer,扩展测试场景。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值