#上下文无关文法 #模糊测试 #文法 #libafl #变异 #输入 #变异器

bin+lib peacock-fuzz

解析上下文无关文法的库,用于创建基于文法的模糊测试工具

8 个版本

0.2.4 2024年7月19日
0.2.3 2024年6月21日
0.2.2 2024年5月24日
0.2.1 2024年4月13日
0.1.2 2023年12月26日

#3#变异器

Download history 159/week @ 2024-04-13 1/week @ 2024-04-20 101/week @ 2024-05-18 41/week @ 2024-05-25 3/week @ 2024-06-01 69/week @ 2024-06-15 42/week @ 2024-06-22 4/week @ 2024-07-06 67/week @ 2024-07-13 36/week @ 2024-07-20 26/week @ 2024-07-27

每月下载量 133

GPL-3.0-only

97KB
2K SLoC

~~~ 基于文法的变异模糊测试 ~~~

此项目是对 Gramatron 的重写

  • 高性能:比 Gramatron 或 LibAFL 的 Gramatron 实现高出 4 倍的吞吐量
  • 多功能:与 LibAFL、libfuzzer、自定义 AFL++ 变异器或独立使用
  • 易于使用:无需协调不同的脚本来运行模糊测试活动,一切内置
  • 可扩展:peacock 的核心是一个库,您可以根据需要自定义语法模糊测试过程的每个步骤
  • 向后兼容:它与为其他工具编写的文法兼容

如何使用它

克隆仓库并执行

cargo build --release

这将创建 5 个可立即使用的工具

  1. peacock-fuzz:一个覆盖率引导的模糊测试器,可以模糊使用 AFL++ 编译器编译的任何二进制文件或任何使用 AFL forkserver 协议的任何内容
  2. peacock-dump:peacock-fuzz 将崩溃和队列项目以原始的二进制格式保存到磁盘。使用此工具从任何此类文件获取人类可读的输出。所有这些二进制文件都有前缀 peacock-raw-
  3. peacock-compile:将文法编译为 C 代码
  4. peacock-merge:将多个文法文件合并为一个或将文法文件从一种格式转换为另一种格式
  5. peacock-gen:从文法生成单个输入

如果您想进行更细粒度的控制,可以使用 crate peacock_fuzz,它是上述所有工具的骨架。有关如何将 peacock 作为库使用的文档,请参阅 docs.rs

它的工作原理

Peacock 是一个实现所谓的“基于文法变异”的模糊测试器。这意味着它将以这种方式变异其输入,使其始终遵循给定的 文法

变异的工作方式与 Gramatron 相同。将文法转换为 PDA,以便可以将输入表示为通过自动机的遍历。然后,输入的变异简单地是对自动机遍历的修改。我们在随机点切断遍历,并让它在那里找到通过自动机的新随机路径。

虽然 Gramatron 和 LibAFL 将自动机实现为邻接矩阵,但 Peacock 生成将自动机编码在其控制流中的 C 代码。这为我们节省了大量内存访问,并使变异过程更快。

生成的 C 代码暴露了可以由任何应用程序使用的 API,例如 libfuzzer Harness、AFL++ 自定义变异器,甚至是 Rust 代码。

Peacock 还附带了一个可立即使用的 fuzzer,可以模糊任何使用 AFL++ 编译器编译的二进制文件或实现 AFL 风格的 forkserver。

如何编写语法

Peacock 接受其上下文无关语法为 JSON 格式。上下文无关语法的生成规则形式为

A -> X Y Z ...

其中 A 必须 是非终结符,而 XYZ 可以是非终结符或终结符。右侧必须至少包含一个符号。

非终结符用 <> 括起来,所以非终结符 A 将表示为 <A>。终结符用 '' 括起来。

规则集

A -> a B
A -> a
B -> b B
B -> Ɛ

将写成

{
    // Comments are also possible :)
    "<A>": [
        ["'a'", "<B>"],
        ["'a'"]
    ],
    "<B>": [
        ["'b'", "<B>"],
        ["''"] // Ɛ = ''
    ]
}

并对应于正则表达式 a(b*)

Peacock 还支持 Gramatron 格式,它略有不同,不允许有注释。

非终结符 <ENTRYPOINT> 是语法的入口点。

C API 文档

  • void seed_generator(size_tnew_seed)
    为变异器的 RNG 提供种子。

  • size_tunparse_sequence(size_t*seq_buf, size_tseq_capacity,unsignedchar*input, size_tinput_len)
    给定一个符合语法的输入,找到相应的自动机遍历。 此函数可能较慢,请在非热点循环外使用。

    • seq_buf: 自动机遍历将写入此缓冲区
    • seq_capacity: seq_buf 可容纳的最大元素数(不是字节数)
    • input: 符合语法的用户输入
    • input_len: input 的长度

    返回写入 seq_buf 的元素数或 0(如果输入不符合语法)。

  • size_tmutate_sequence(size_t*buf, size_tlen, size_tcapacity)
    给定一个自动机遍历,创建遍历的随机变异体。

    • buf: 指向包含自动机遍历的数组的指针
    • len: buf 中的项目数(不是字节数)
    • capacity: buf 可容纳的最大项目数(不是字节数)

    返回新遍历的长度。

  • size_tserialize_sequence(size_t*seq, size_tseq_len,unsignedchar*out, size_tout_len)
    给定一个自动机遍历,创建相应的输出。

    • seq: 指向自动机遍历的指针
    • seq_len: seq 中的项目数(不是字节数)
    • out: 输出将被写入该缓冲区
    • out_len: out 中的字节数

    返回写入 out 的字节数。

宏定义

  • MAKE_THREAD_SAFE: 定义此宏使变异器完全线程安全
  • MAKE_VISIBLE: 定义此宏显式设置上述函数的可见性为 "default"(默认)
  • STATIC_SEED=<你的种子>:编译时随机数生成器的种子
  • DISABLE_rand:不包含内部 rand 函数,使用具有以下签名的外部函数:size_t rand (void)
  • DISABLE_seed_generator:不包含 seed_generator 函数

依赖项

~13–41MB
~609K SLoC