第 24 章 使用 afl-fuzz 进行模糊测试

1 概述

American fuzzy lop(“afl-fuzz”)是一种模糊测试器,它通过提供随机生成的输入来测试软件,搜索导致程序崩溃的输入。

与大多数模糊测试器不同,afl-fuzz 会观察被测试程序的内部行为,并调整生成的测试用例以触发未探索的执行路径。因此,由 afl-fuzz 生成的测试用例涵盖了被测试程序的更多可能行为,而不是其他模糊测试器。

这要求被测试的程序要进行工具,以便与 afl-fuzz 进行通信。原生代码编译器“ocamlopt”可以生成这种工具,允许 afl-fuzz 用于针对用 OCaml 编写的程序进行测试。

有关 afl-fuzz 的更多信息,请访问其网站:http://lcamtuf.coredump.cx/afl/.

2 生成工具

afl-fuzz 所需的工具默认情况下不会生成,必须显式启用,方法是将 -afl-instrument 选项传递给 ocamlopt

为了对大型系统进行模糊测试而无需修改构建工具,OCaml 的 configure 脚本也接受 afl-instrument 选项。如果 OCaml 在配置时使用了 afl-instrument,那么由 ocamlopt 编译的所有程序都将被工具。

2.1 高级选项

在极少数情况下,控制生成的工具数量是有用的。通过将 -afl-inst-ratio N 参数传递给 ocamlopt,其中 N 小于 100,可以仅针对 N% 的分支生成工具。(有关此参数的精确影响,请参阅 afl-fuzz 文档中的 AFL_INST_RATIO 参数。)

3 示例

例如,我们对以下程序 readline.ml 进行模糊测试

let _ =
  let s = read_line () in
  match Array.to_list (Array.init (String.length s) (String.get s)) with
    ['s'; 'e'; 'c'; 'r'; 'e'; 't'; ' '; 'c'; 'o'; 'd'; 'e'] -> failwith "uh oh"
  | _ -> ()

有一个唯一的输入(字符串“secret code”)会导致此程序崩溃,但通过盲目随机搜索找到它是不可能的。

相反,我们使用启用了 afl-fuzz 工具的编译器进行编译

ocamlopt -afl-instrument readline.ml -o readline

接下来,我们在 afl-fuzz 下运行该程序

mkdir input
echo asdf > input/testcase
mkdir output
afl-fuzz -m none -i input -o output ./readline

通过检查工具输出,模糊测试器可以快速找到导致崩溃的输入。

注意:要使用 afl-fuzz 对 OCaml 程序进行模糊测试,需要传递 -m none 选项来禁用 afl-fuzz 的默认 50MB 虚拟内存限制。