TNO 开发了 WuppieFuzz,这是一款基于 LibAFL 构建的覆盖率引导 REST API 模糊测试器,面向广泛的终端用户群体,重点关注易用性、所发现缺陷的可解释性以及模块化。WuppieFuzz 支持全部三种测试模式(黑盒、灰盒和白盒)。
[!NOTE]
如需快速、可跟随操作的指导,请参阅教程!
WuppieFuzz 曾出现在:
如果你想在学术工作中引用 WuppieFuzz,请使用 CITATION.cff 中列出的首选出版物:
Rooijakkers, T., Nijsten, A., Daniele, C., Weitenberg, E., Groenewegen, R., & Melissen, A. (2026). WuppieFuzz: Coverage-Guided, Stateful REST API Fuzzing. In Proceedings of the 12th International Conference on Information Systems Security and Privacy (ICISSP), Volume 2, 221-231. SciTePress. https://doi.org/10.5220/0000217100004061
WuppieFuzz 采用 Apache-2.0 许可证;请参阅 LICENSE。
第三方许可证声明列于 THIRD_PARTY_NOTICES。
如需在常见操作系统(MacOS、Windows、Linux)上快速安装 WuppieFuzz,请参阅 releases,或使用 brew install wuppiefuzz
你可以使用 docker build . -t wuppiefuzz:local 构建 Docker 镜像。要使用它,你必须挂载一个包含你的 openapi 规范的文件夹。在对本地运行的服务(非 Docker 中)进行模糊测试时,你需要指定主机网络:
docker run \
--network host \
-v ./fuzzing-folder:/fuzzing-folder \ # 该文件夹将填充 wuppiefuzz 的输出
-w /fuzzing-folder \
wuppiefuzz:local fuzz --timeout 60 --report openapi.json
要构建该项目,你需要安装以下依赖项和工具:
sudo apt install -y build-essential pkg-config cmake # 通用构建工具
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh # Rust
在运行 WuppieFuzz 之前,你必须启动你的(已插桩的)目标应用程序。
此外,你必须向 WuppieFuzz 提供一个 OpenAPI 规范,以便它知道如何生成和变异其请求。有关命令行参数的帮助,请使用以下命令:
$ cargo run -- --help # 显示所需参数和标志的帮助信息
Usage: wuppiefuzz [OPTIONS] [OPENAPI_SPEC.YAML]
...
例如,要对一个附加了 JaCoCo agent 的 Java 目标运行 WuppieFuzz,你需要指定其 OpenAPI 文件(其中包含目标运行所在的 URL,位于 API 规范中)。此外,你还要指定覆盖率格式为 JaCoCo,并按如下方式给出 classes 目录:
cargo run -- fuzz openapi.yaml --coverage-format jacoco --jacoco-class-dir ../Targets/app/target/classes/
如果你想使用配置文件代替命令行参数,或与命令行参数结合使用,可以使用标志 --config <CONFIG_FILE>。如果你将命令行参数与配置文件结合使用,命令行参数优先。
配置文件应为 yaml 文件,并为你想要指定的每个命令行参数包含一行,例如:
coverage_format: jacoco
output_format: human-readable
source_dir: "/swagger-petstore/src/main/java"
jacoco_class_dir: "/swagger-petstore/target"
timeout: 20
在这种情况下,一个示例运行命令可以是:
$ cargo run -- fuzz --config=config.yaml --report --coverage-host=localhost:6300 --timeout=10 ./openapi.yaml
这一行将合并来自命令行和配置文件的参数。由于标志 --timeout 在两者中都有指定,命令行中指定的超时(10 秒)将优先。
在目录 example_configs/ 中,你将找到两个示例配置文件,分别用于为 Java 代码使用 JaCoCo 生成覆盖率报告,以及为 Python 代码使用 LCOV 生成覆盖率报告。
当你使用 --report 标志运行 WuppieFuzz 时,会在 reports/ 内创建一个以时间戳为名称的子目录。所有受支持的覆盖率报告都会写入该子目录。覆盖率报告有两种类型:
除此之外,还会用一个数据库填充与你的模糊测试活动相关的所有请求信息。该数据库可以通过 Grafana 仪表板进行可视化和探索。
有关其中每一项的更多信息,请参阅这些目录中的 README。
默认情况下,WuppieFuzz 会内置其 C 依赖项(OpenSSL、SQLite、Z3),以便常规的 cargo build 开箱即用。为了在开发期间加快编译速度,你可以禁用所有内置依赖项,改为链接系统安装的库。
[!NOTE]
z3crate 需要 Z3 4.15+,这比大多数 Linux 发行版包管理器提供的版本更新。请通过 Homebrew(brew install z3)安装 Z3 以获得兼容版本。
在你的系统上安装以下库:
Debian/Ubuntu:
sudo apt install libssl-dev libsqlite3-dev
brew install z3 # apt 的 libz3-dev 太旧;请改用 Homebrew
在 Linux 上,Homebrew 会安装到非标准路径。将其库目录添加到你的环境中,以便编译器和运行时链接器能够找到 Z3:
eval "$(brew shellenv)"
export LIBRARY_PATH="$(brew --prefix z3)/lib:$LIBRARY_PATH"
export LD_LIBRARY_PATH="$(brew --prefix z3)/lib:$LD_LIBRARY_PATH"
[!TIP] 将上面的行添加到你的
~/.bashrc或~/.zshrc中,使其永久生效。
Fedora (42+):
sudo dnf install openssl-devel sqlite-devel z3-devel
macOS (Homebrew):
brew install openssl sqlite z3
该仓库在 .cargo/config.toml 中包含 cargo 别名,它们使用 --no-default-features 构建,并链接所有系统库:
cargo dev-build # 不使用内置依赖项进行构建
cargo dev-run -- <args> # 不使用内置依赖项运行
cargo dev-test # 不使用内置依赖项进行测试
使用 cargo doc --no-deps 从源代码中的注释生成文档。文档的主页将是 target/doc/wuppiefuzz/index.html