Rust 驱动的革新:探索 LibAFL,高效可定制的跨平台模糊测试框架
前言
模糊测试(Fuzz Testing)作为一种有效的软件测试方法,能够通过自动生成大量随机或半随机的输入数据来检测程序的异常行为,从而帮助开发者发现潜在的漏洞和缺陷。LibAFL,作为一个先进的模糊测试库,以其高效、可定制和跨平台的特性,为软件安全性的提升提供了强有力的支持。
LibAFL 是一个使用 Rust 编写的高级模糊测试库,它允许你将自己的模糊测试工具组合起来,并使用 Rust 扩展它们的特性。
为什么选择 LibAFL?
LibAFL 提供了现成模糊测试工具的许多好处,同时完全可定制化。一些当前的亮点特性包括:
快速
:我们在编译时做尽可能多的事情,保持运行时开销最小。用户在手机上使用所有核心的 frida 模式下达到了每秒 120k 次执行。可扩展性
:简称LLMP
的低级消息传递
,允许 LibAFL 几乎线性地扩展到多个核心,并通过 TCP 扩展到多台机器。适应性
:你可以替换 LibAFL 的每个部分。例如,BytesInput
只是潜在的输入形式之一:请随意添加基于 AST 的输入,用于结构化模糊测试等。多平台
:LibAFL 已确认在Windows、_MacOS_、Linux和Android上运行,在x86_64和aarch64上。LibAFL
可以以no_std
模式构建,以便将 LibAFL 注入到嵌入式设备和虚拟机等不常见的目标中。自带目标
:我们支持二进制模式,如 Frida 模式,以及基于源代码的工具编译多次通过。当然,添加自定义工具后端也很容易。
概览
LibAFL 是一组可重用的模糊测试工具的集合,用 Rust 编写。它快速、多平台兼容、兼容 no_std,并且可以在核心和机器上扩展。
它提供了一个主要的 crate,用于自定义模糊测试的构建块,libafl[1],一个包含可以用于目标工具化的公共代码的库,libafl_targets[2],以及一个提供包装编译器设施的库,libafl_cc[3]。
LibAFL 提供了与流行的工具化框架的集成。目前,支持的后端包括:
在libafl_targets[4]中的 SanitizerCoverage 在libafl_frida[5]中的 Frida 在libafl_qemu[6]中的 QEMU 用户模式和系统模式,包括仿真钩子 由elbiazo[7] 在libafl_tinyinst[8]中的 TinyInst
开始使用
安装依赖项
Rust 开发语言。我们强烈建议不要使用例如 Linux 发行版包,因为这可能已经过时。因此,最好是直接安装 Rust,安装说明可以在这里[9]找到。
LLVM 工具 需要 LLVM 工具(包括 clang, clang++,版本高于 LLVM 15.0.0 到 LLVM 18.1.3) 如果您使用的是 Debian/Ubuntu,我们同样强烈建议您从这里[10]安装包
(在libafl_concolic
中,我们只支持高于 18 版本的 LLVM)
Cargo-make 我们使用 cargo-make 来构建 fuzzers/
目录中的模糊测试工具。您可以使用以下命令安装它:
cargo install cargo-make
使用以下命令克隆 LibAFL 仓库
git clone https://github.com/AFLplusplus/LibAFL
使用以下命令构建库
cargo build --release
使用以下命令构建 API 文档
cargo doc
浏览 LibAFL 书籍(进行中!)(需要mdbook[11])
cd docs && mdbook serve
我们在`./fuzzers`[12]中收集了所有示例模糊测试工具。确保阅读它们的文档(和源代码),这是开始的自然方式!
您可以使用以下命令运行每个示例模糊测试工具
cargo make run
只要模糊测试工具目录有Makefile.toml
文件。
经过最严格测试的模糊测试工具是`./fuzzers/libfuzzer_libpng`[13],这是一个使用 LibAFL 为 libpng harness 的多核 libfuzzer 风格的模糊测试工具。
资源
1. LibAFL 的获取
LibAFL 是一个强大的模糊测试库,可以通过以下步骤轻松获取:
使用 Git 克隆最新版本:
$ git clone https://github.com/AFLplusplus/LibAFL.git
或者,对于类 UNIX 系统,可以下载压缩包并解压:
$ wget https://github.com/AFLplusplus/LibAFL/archive/main.tar.gz
$ tar xvf main.tar.gz
$ rm main.tar.gz
$ ls LibAFL-main # 这是解压后的文件夹
2. Clang 编译器的安装
LibAFL 需要 Clang C/C++编译器,尽管大部分代码使用纯 Rust 编写,但某些功能仍需 C 编译器支持。如果你打算对 C/C++应用程序进行源代码级别的模糊测试,Clang 的插桩选项将非常有用。
在 Linux 上,建议使用 LLVM 的官方仓库[14]获取最新版的 Clang,而不是依赖发行版的包管理器。
Windows 用户可以下载 LLVM 定期生成的安装包[15]。
对于 MacOS,建议通过Homebrew[16]安装 LLVM 和 Clang,使用命令
brew install llvm
,而不是使用苹果自带的版本。或者,可以下载并构建 LLVM 源代码树,包括 Clang,按照这里[17]的步骤进行。
3. Rust 环境的安装
如果你还没有安装 Rust,可以按照这里[18]的说明在任何支持的系统上进行安装。注意,Linux 发行版中附带的 Rust 版本可能过时,LibAFL 总是针对rustup
提供的最新的stable
版本。
建议首先安装 Clang 和 LLVM。
以上步骤将帮助你顺利搭建 LibAFL 的开发和测试环境。在终端中输入命令时,以$
开头的行表示你需要输入的命令,而没有以$
开头的行通常显示前一个命令的输出。对于 PowerShell,特定示例可能使用>
代替$
。
在线 API 文档[19]
LibAFL 书籍(进行中)在线[20] 或在仓库[21]
我们的研究论文[22]
我们的 RC3 演讲[23] 解释了核心概念
我们的 Fuzzcon Europe 演讲[24] 有(有点但不是太过时的)逐步讨论如何构建一些示例模糊测试工具
由epi[25]提供的 Fuzzing101 解决方案[26] & 一系列博客文章[27]
博客文章关于二进制模糊测试库 libaf_qemu,Hacking TMNF - Fuzzing the game server[28],由RickdeJager[29]撰写。
A LibAFL Introductory Workshop[30],由Jordan Whitehead[31]撰写。
引用
如果您在学术工作中使用 LibAFL,请引用以下论文:
@inproceedings{libafl,
author = {Andrea Fioraldi and Dominik Maier and Dongjia Zhang and Davide Balzarotti},
title = {{LibAFL: A Framework to Build Modular and Reusable Fuzzers}},
booktitle = {Proceedings of the 29th ACM conference on Computer and communications security (CCS)},
series = {CCS '22},
year = {2022},
month = {November},
location = {Los Angeles, U.S.A.},
publisher = {ACM},
}
许可证
根据您选择的[Apache License, Version 2.0](LICENSE-APACHE "Apache License, Version 2.0")或[MIT license](LICENSE-MIT "MIT license"),本项目获得许可。除非您明确声明其他方式,否则您有意提交以供此crate包含的任何贡献,如Apache-2.0许可证中定义的,将如上所述获得双重许可,无需任何额外的条款或条件。LibAFL 由以下人员编写和维护:
Andrea Fioraldi[32] andrea@aflplus.plus Dominik Maier[33] dominik@aflplus.plus s1341[34] github@shmarya.net Dongjia Zhang[35] toka@aflplus.plus Addison Crump[36] me@addisoncrump.info Romain Malmain[37] rmalmain@pm.me
附录
https://github.com/AFLplusplus/LibAFL
结语
经过上述步骤的详细设置,你现在应该已经拥有了开始使用 LibAFL 进行模糊测试的所有必要工具和环境。LibAFL 的强大之处在于其模块化的设计,它允许开发者根据自己的需求定制测试流程,无论是在性能上还是在功能上都能达到最优的效果。
libafl: ./libafl
[2]libafl_targets: ./libafl_targets
[3]libafl_cc: ./libafl_cc
[4]libafl_targets: ./libafl_targets
[5]libafl_frida: ./libafl_frida
[6]libafl_qemu: ./libafl_qemu
[7]elbiazo: https://github.com/elbiazo
[8]libafl_tinyinst: ./libafl_tinyinst
[9]这里: https://www.rust-lang.org/tools/install
[10]这里: https://apt.llvm.org/
[11]mdbook: https://rust-lang.github.io/mdBook/index.html
[12]./fuzzers
: ./fuzzers/
./fuzzers/libfuzzer_libpng
: ./fuzzers/libfuzzer_libpng
官方仓库: https://apt.llvm.org/
[15]安装包: https://llvm.org/builds/
[16]Homebrew: https://brew.sh/
[17]这里: https://clang.llvm.org/get_started.html
[18]这里: https://www.rust-lang.org/tools/install
[19]在线 API 文档: https://docs.rs/libafl/
[20]在线: https://aflplus.plus/libafl-book
[21]仓库: ./docs/src/
[22]论文: https://www.s3.eurecom.fr/docs/ccs22_fioraldi.pdf
[23]Fuzzers Like LEGO: http://www.youtube.com/watch?v=3RWkT1Q5IV0
[24]LibAFL: The Advanced Fuzzing Library: https://www.youtube.com/watch?v=PWB8GIhFAaI
[25]epi: https://github.com/epi052
[26]解决方案: https://github.com/epi052/fuzzing-101-solutions
[27]博客文章: https://epi052.gitlab.io/notes-to-self/blog/2021-11-01-fuzzing-101-with-libafl/
[28]Hacking TMNF - Fuzzing the game server: https://blog.bricked.tech/posts/tmnf/part1/
[29]RickdeJager: https://github.com/RickdeJager
[30]A LibAFL Introductory Workshop: https://www.atredis.com/blog/2023/12/4/a-libafl-introductory-workshop
[31]Jordan Whitehead: https://github.com/jordan9001
[32]Andrea Fioraldi: https://twitter.com/andreafioraldi
[33]Dominik Maier: https://twitter.com/domenuk
[34]s1341: https://twitter.com/srubenst1341
[35]Dongjia Zhang: https://github.com/tokatoka
[36]Addison Crump: https://github.com/addisoncrump
[37]Romain Malmain: https://github.com/rmalmain