OSS-Fuzz 模糊测试使用指南

文章目录

  • [1. 简介](#1. 简介)
  • [2. 环境部署](#2. 环境部署)
    • [2.1 系统前置准备](#2.1 系统前置准备)
    • [2.2 Docker 安装与配置](#2.2 Docker 安装与配置)
      • [2.2.1 安装 Docker](#2.2.1 安装 Docker)
      • [2.2.2 配置 Docker 加速(可选,根据网络情况)](#2.2.2 配置 Docker 加速(可选,根据网络情况))
      • [2.2.3 配置 Docker 权限](#2.2.3 配置 Docker 权限)
    • [2.3 克隆 OSS-Fuzz 仓库并验证基础工具](#2.3 克隆 OSS-Fuzz 仓库并验证基础工具)
      • [2.3.1 克隆官方仓库](#2.3.1 克隆官方仓库)
      • [2.3.2 验证 OSS-Fuzz 核心辅助脚本](#2.3.2 验证 OSS-Fuzz 核心辅助脚本)
    • [2.4 配置代理(国内必配)](#2.4 配置代理(国内必配))
    • [2.5 拉取 OSS-Fuzz 基础镜像](#2.5 拉取 OSS-Fuzz 基础镜像)
    • [2.6 环境完整校验](#2.6 环境完整校验)
  • [3. 项目示例](#3. 项目示例)
    • [3.1 示例项目准备](#3.1 示例项目准备)
    • [3.2 项目配置文件编写](#3.2 项目配置文件编写)
      • [3.2.1 Dockerfile 编写与参数解释](#3.2.1 Dockerfile 编写与参数解释)
      • [3.2.2 project.yaml 编写与参数解释](#3.2.2 project.yaml 编写与参数解释)
    • [3.3 编译脚本 build.sh 编写与参数解释](#3.3 编译脚本 build.sh 编写与参数解释)
    • [3.4 模糊测试代码编写与规范说明](#3.4 模糊测试代码编写与规范说明)
      • [3.4.1 libFuzzer 固定格式](#3.4.1 libFuzzer 固定格式)
      • [3.4.2 fuzzer 编写重点](#3.4.2 fuzzer 编写重点)
    • [3.5 测试步骤与参数解释](#3.5 测试步骤与参数解释)
      • [3.5.1 构建项目镜像](#3.5.1 构建项目镜像)
      • [3.5.2 构建模糊测试用例](#3.5.2 构建模糊测试用例)
      • [3.5.3 验证构建结果](#3.5.3 验证构建结果)
      • [3.5.4 运行模糊测试](#3.5.4 运行模糊测试)
    • [3.6 模糊测试日志解读](#3.6 模糊测试日志解读)
  • [4. 总结](#4. 总结)

⚠️本博文所涉安全渗透测试技术、方法及案例,仅用于网络安全技术研究与合规性交流,旨在提升读者的安全防护意识与技术能力。任何个人或组织在使用相关内容前,必须获得目标网络 / 系统所有者的明确且书面授权,严禁用于未经授权的网络探测、漏洞利用、数据获取等非法行为。

1. 简介

OSS-Fuzz 是由 Google 主导打造的开源模糊测试(Fuzz Testing)平台,核心目标是为全球开源软件提供标准化、自动化、可持续的漏洞检测能力,从根源上提升开源生态的安全性。

该平台基于 Docker 容器实现环境隔离,集成了 libFuzzer、HongFuzz、AFL++ 等主流模糊测试引擎,并配套了崩溃分析、覆盖率统计、测试用例精简等全链路工具链,让开发者无需关注环境适配、引擎运维等底层细节,只需聚焦于业务逻辑的模糊测试适配。

2. 环境部署

2.1 系统前置准备

OSS-Fuzz 对操作系统有明确要求,本文基于 Ubuntu 24.04.3 LTS 完成部署。

首先需更新系统并安装核心依赖工具(OSS-Fuzz 的辅助脚本基于 Python3 开发,Git 用于克隆仓库):

bash 复制代码
sudo apt update && sudo apt upgrade -y
sudo apt install -y git python3 python3-pip curl wget build-essential

git --version
python3 --version

2.2 Docker 安装与配置

OSS-Fuzz 完全基于 Docker 运行(核心优势是环境隔离),需安装官方稳定版 Docker 并完成权限、加速配置。

2.2.1 安装 Docker

bash 复制代码
# 安装证书、GPG 密钥相关依赖,确保软件源验证合法
sudo apt install -y ca-certificates curl gnupg lsb-release

# 创建 Docker 软件源密钥目录并设置权限
sudo install -m 0755 -d /etc/apt/keyrings
# 下载阿里云 Docker 源的 GPG 密钥并写入密钥文件
curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

# 赋予密钥文件全局可读权限,确保 apt 能读取验证
sudo chmod a+r /etc/apt/keyrings/docker.gpg

# 添加阿里云 Docker 软件源到系统源列表(适配当前系统架构和版本)
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# 安装 Docker 全套组件
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

2.2.2 配置 Docker 加速(可选,根据网络情况)

国内访问 Docker 官方镜像源速度较慢,可配置国内镜像加速:

shell 复制代码
sudo mkdir -p /etc/docker
sudo apt-get install vim -y
sudo vim /etc/docker/daemon.json

# 写入国内镜像加速地址(DaoCloud 镜像,国内可用性高)
{
  "registry-mirrors": [
    "https://docker.m.daocloud.io"
  ]
}

# 重新加载系统服务配置并重启 Docker 服务,使加速配置生效
sudo systemctl daemon-reload && sudo systemctl restart docker
sudo systemctl status docker

2.2.3 配置 Docker 权限

默认情况下 Docker 命令需 sudo 执行,配置普通用户权限可简化后续操作:

bash 复制代码
sudo groupadd -f docker
sudo usermod -aG docker $USER
newgrp docker

2.3 克隆 OSS-Fuzz 仓库并验证基础工具

2.3.1 克隆官方仓库

OSS-Fuzz 的核心脚本和配置都在官方仓库中,需先克隆到本地(国内慢可导入 Gitee 后克隆):

bash 复制代码
git clone https://github.com/google/oss-fuzz.git
cd oss-fuzz

2.3.2 验证 OSS-Fuzz 核心辅助脚本

infra/helper.py 是 OSS-Fuzz 最核心的辅助脚本,负责镜像构建、模糊测试编译/运行等全流程,需验证其可用性:

bash 复制代码
python3 infra/helper.py --help

2.4 配置代理(国内必配)

国内直接拉取 OSS-Fuzz 的海外 Docker 镜像(gcr.io 源)会超时,仅靠镜像加速无法解决,需配置代理:

shell 复制代码
# 创建 Docker 服务的代理配置目录
sudo mkdir -p /etc/systemd/system/docker.service.d
# 编辑 HTTP/HTTPS 代理配置文件
sudo vim /etc/systemd/system/docker.service.d/http-proxy.conf

# 配置代理环境变量(需替换为自身代理的 IP 和端口)
[Service]
Environment="HTTP_PROXY=http://192.168.10.3:7897"  # HTTP 代理地址
Environment="HTTPS_PROXY=http://192.168.10.3:7897"  # HTTPS 代理地址
Environment="NO_PROXY=localhost,127.0.0.1"  # 无需代理的本地地址

# 重新加载服务配置并重启 Docker,使代理生效
sudo systemctl daemon-reload
sudo systemctl restart docker

2.5 拉取 OSS-Fuzz 基础镜像

OSS-Fuzz 为不同编程语言提供了预构建的基础镜像,首次拉取较慢,建议提前拉取:

bash 复制代码
# 拉取 C/C++ 项目基础构建镜像
docker pull gcr.io/oss-fuzz-base/base-builder

# 拉取 Java/Go 项目基础构建镜像(按需选择)
docker pull gcr.io/oss-fuzz-base/base-builder-jvm
docker pull gcr.io/oss-fuzz-base/base-builder-go

2.6 环境完整校验

运行以下命令验证整个环境是否满足 OSS-Fuzz 运行要求:

bash 复制代码
# 验证 Docker 服务状态
sudo systemctl status docker --no-pager
# 验证 helper.py 能否识别基础镜像
python3 infra/helper.py build_image --help

3. 项目示例

3.1 示例项目准备

tinyxml2 是轻量级 C++ XML 解析库,也是 OSS-Fuzz 官方内置的测试项目,但是官方的配置是拉取在线的 tinyxml2 源码进行测试,本次演示本地源码测试(而非官方在线拉取),先明确目录结构:

shell 复制代码
/home/xxx/Desktop/
├── oss-fuzz/          # OSS-Fuzz 根目录(所有操作的核心目录)
└── tinyxml2/          # tinyxml2 源码目录(与 oss-fuzz 同级,本地测试用)

克隆 tinyxml2 源码:

bash 复制代码
git clone https://github.com/leethomason/tinyxml2.git

3.2 项目配置文件编写

进入 OSS-Fuzz 的 projects 目录,创建本地测试配置目录:

shell 复制代码
cd oss-fuzz/projects
mkdir -p tinyxml2_local  # 创建 tinyxml2 本地测试配置目录
cd tinyxml2_local

目录结构如下:

3.2.1 Dockerfile 编写与参数解释

shell 复制代码
vim Dockerfile

文件内容:

dockerfile 复制代码
FROM gcr.io/oss-fuzz-base/base-builder:latest  # 基于 OSS-Fuzz C/C++ 基础镜像构建(必选,提供编译环境)
RUN apt-get update && apt-get install -y cmake make  # 安装 tinyxml2 编译所需的 cmake 和 make 工具
COPY build.sh $SRC/  # 将本地 build.sh 复制到容器内的 $SRC 目录(OSS-Fuzz 约定的源码目录)
COPY tinyxml2_local_fuzzer.cpp $SRC/  # 将模糊测试代码复制到 $SRC 目录

参数/指令解释

  • FROM:指定基础镜像,OSS-Fuzz 要求必须基于官方 base-builder 系列镜像(保证编译环境统一);
  • RUN:在容器内执行命令,此处安装 tinyxml2 编译依赖(cmake 用于生成 Makefile,make 用于编译);
  • COPY:将本地文件复制到容器内,$SRC 是 OSS-Fuzz 约定的源码工作目录,所有编译脚本/测试代码需放入该目录。

3.2.2 project.yaml 编写与参数解释

shell 复制代码
vim project.yaml  # 创建项目元信息配置文件

文件内容:

yaml 复制代码
homepage: "https://github.com/leethomason/tinyxml2"  # 项目官网/仓库地址
language: c++  # 项目开发语言(OSS-Fuzz 用于匹配对应编译环境)
primary_contact: "xxx@xx.com"  # 漏洞通知的主联系人
main_repo: "https://github.com/leethomason/tinyxml2"  # 项目主仓库地址

参数解释

  • homepage:用于 OSS-Fuzz 平台展示项目信息;
  • language:核心参数,OSS-Fuzz 会根据该值加载对应语言的编译工具链(如 C++ 加载 clang++、libFuzzer 等);
  • primary_contact:当 OSS-Fuzz 发现漏洞时,会通过该邮箱通知开发者;
  • main_repo:用于 OSS-Fuzz 自动拉取最新源码(本地测试时仅作元信息,无实际作用)。

3.3 编译脚本 build.sh 编写与参数解释

shell 复制代码
vim build.sh  # 创建编译脚本(OSS-Fuzz 核心脚本,负责编译项目和模糊测试用例)

# 保持后添加文件权限
chmod 755 build.sh

文件内容:

bash 复制代码
#!/bin/bash -eu

cd $SRC/tinyxml2_local
cmake -DCMAKE_CXX_COMPILER=$CXX -DCMAKE_CXX_FLAGS="$CXXFLAGS" .
make -j$(nproc)

$CXX $CXXFLAGS -std=c++17 -I. $SRC/tinyxml2_local_fuzzer.cpp -o $OUT/tinyxml2_local_fuzzer $LIB_FUZZING_ENGINE ./libtinyxml2.a -DTINYXML2_NO_EXCEPTIONS

核心参数解释

  • #!/bin/bash -eu:脚本解释器声明,-e-u 是 OSS-Fuzz 要求的脚本规范(避免静默失败);
  • $CXX/$CC:OSS-Fuzz 约定的编译器变量(C++ 用 CXX,C 用 CC),默认绑定 clang 系列编译器(内置 libFuzzer 支持);
  • $CXXFLAGS/$CFLAGS:OSS-Fuzz 预设的编译参数,包含 -fsanitize=address(ASAN,内存漏洞检测)、-O1(编译优化)、-fno-omit-frame-pointer(保留栈帧,方便崩溃调试)等核心参数;
  • $LIB_FUZZING_ENGINE:OSS-Fuzz 内置的 libFuzzer 库路径(无需手动指定,平台自动注入);
  • $OUT:OSS-Fuzz 约定的输出目录,所有编译生成的模糊测试二进制文件必须放入该目录(helper.py 会自动读取该目录的二进制);
  • -j$(nproc):编译并行度优化,利用所有 CPU 核心加速编译,是 OSS-Fuzz 编译脚本的通用优化手段。

3.4 模糊测试代码编写与规范说明

shell 复制代码
vim tinyxml2_local_fuzzer.cpp

文件内容:

cpp 复制代码
#include "tinyxml2.h"
#include <fuzzer/FuzzedDataProvider.h>  // OSS-Fuzz 提供的模糊数据解析工具
#include <stdint.h>    // 必选,LLVMFuzzerTestOneInput 函数参数依赖
#include <stddef.h>    // 必选,LLVMFuzzerTestOneInput 函数参数依赖
#include <string>

// 必须命名为 LLVMFuzzerTestOneInput,参数固定为 const uint8_t* data 和 size_t size
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
    if (size == 0) return 0;

    // 初始化模糊数据解析器:将原始字节数据转换为可按需提取的结构化数据
    FuzzedDataProvider provider(data, size);
    std::string xml_input = provider.ConsumeRandomLengthString(size);

    // 调用被测函数:tinyxml2 的 XML 解析逻辑
    tinyxml2::XMLDocument doc;
    doc.Parse(xml_input.c_str(), xml_input.size());

    // 覆盖错误处理逻辑
    if (doc.Error()) {
        doc.ErrorStr();
        doc.ErrorName();
        doc.ErrorLineNum();
    }

    return 0;  // 函数必须 0 表示正常结束
}

3.4.1 libFuzzer 固定格式

  1. 入口函数:必须命名为 LLVMFuzzerTestOneInput ,且必须用 extern "C" 修饰(避免 C++ 名字修饰导致 libFuzzer 无法识别);
  2. 函数参数:固定为 const uint8_t* data(模糊测试的原始字节数据)和 size_t size(数据长度),无其他参数;
  3. 返回值:必须为 int 类型,返回 0 表示正常结束(非 0 无特殊意义,libFuzzer 仅关注崩溃/内存错误);
  4. 头文件依赖:必须引入 stdint.hstddef.h(保证 uint8_t/size_t 类型定义),fuzzer/FuzzedDataProvider.h 是 OSS-Fuzz 推荐的辅助工具(可选但建议使用)。

3.4.2 fuzzer 编写重点

  1. 数据解析:避免直接使用原始 data,通过 FuzzedDataProvider 将字节数据转换为被测函数需要的类型(如字符串、整数、数组等),覆盖更多输入场景;
  2. 核心逻辑调用:聚焦被测项目的核心函数(如 tinyxml2 的 Parse 方法),确保模糊测试覆盖核心业务逻辑;
  3. 异常/错误处理:主动调用错误处理函数(如 ErrorStr()/ErrorLineNum()),提升代码覆盖率;
  4. 避免无关逻辑:不添加复杂的日志、休眠等逻辑,避免干扰模糊测试的执行效率;
  5. 边界处理:对空输入、超长输入等边界场景做基础处理(如 size == 0 时返回),避免无意义的崩溃。

3.5 测试步骤与参数解释

3.5.1 构建项目镜像

bash 复制代码
python3 infra/helper.py build_image tinyxml2_local

参数解释

  • infra/helper.py:OSS-Fuzz 核心辅助脚本;
  • build_image:子命令,用于构建指定项目的 Docker 镜像;
  • tinyxml2_local:项目名称(对应 projects 目录下的 tinyxml2_local 目录)。

3.5.2 构建模糊测试用例

bash 复制代码
python3 infra/helper.py build_fuzzers --sanitizer address tinyxml2_local /home/jerry/Desktop/tinyxml2

参数解释

  • build_fuzzers:子命令,用于编译模糊测试二进制文件;
  • --sanitizer address:指定漏洞检测工具为 ASAN(AddressSanitizer,内存越界/泄漏检测),可选值还有 undefined(UBSAN,未定义行为检测)、memory(MSAN,内存初始化检测)等;
  • tinyxml2_local:项目名称;
  • /home/jerry/Desktop/tinyxml2:本地 tinyxml2 源码目录(OSS-Fuzz 会将该目录挂载到容器内的 $SRC/tinyxml2_local 目录)。

编译结果验证:

3.5.3 验证构建结果

bash 复制代码
python3 infra/helper.py check_build tinyxml2_local

参数解释

  • check_build:子命令,验证模糊测试二进制文件是否符合 OSS-Fuzz 规范(如是否包含 ASAN 检测能力、是否放入 $OUT 目录等);
  • tinyxml2_local:项目名称。

输出 Check build passed 则表示构建正常:

3.5.4 运行模糊测试

bash 复制代码
python3 infra/helper.py run_fuzzer tinyxml2_local tinyxml2_local_fuzzer > fuzz.log 2>&1
tail -f fuzz.log  # 实时查看模糊测试日志

参数解释

  • run_fuzzer:子命令,运行指定的模糊测试二进制文件;
  • tinyxml2_local:项目名称;
  • tinyxml2_local_fuzzer:模糊测试二进制文件名称(对应 build.sh 中输出到 $OUT 目录的文件);
  • > fuzz.log 2>&1:将标准输出和标准错误重定向到 fuzz.log 文件(避免日志刷屏);
  • tail -f fuzz.log:实时跟踪日志文件内容。

3.6 模糊测试日志解读

日志核心字段解释:

复制代码
exec/s: 103159  # 每秒执行模糊测试用例数(数值越高,fuzzer 效率越高)
cov: 419        # 代码覆盖率(数值上升表示 fuzzer 覆盖了更多代码分支)
REDUCE          # 表示 fuzzer 发现了"更小的测试用例但覆盖相同代码"(便于后续漏洞复现)
DE: "\017\000"  # 自动字典功能:fuzzer 识别出被测函数的关键常量(如 XML 特殊字符),并组合测试

关键说明

  • cov 长时间(如 1 小时)无增长,说明 fuzzer 已穷尽当前变异路径,可停止测试;
  • 若 fuzzer 检测到崩溃(如内存越界、空指针解引用),会立即停止并输出崩溃信息(核心漏洞发现逻辑)。

4. 总结

OSS-Fuzz的部署与使用核心分为环境准备、项目配置、编译验证、模糊测试四大阶段:

  • 环境准备需安装Git、Python3等基础工具
  • 部署并配置Docker(国内需代理解决海外镜像拉取问题),克隆OSS-Fuzz官方仓库验证helper.py脚本可用性
  • 项目配置要在OSS-Fuzz的projects目录下创建项目目录,编写Dockerfile(基础镜像+依赖安装)、project.yaml(项目元信息),遵循OSS-Fuzz变量约定编写build.sh编译脚本,按libFuzzer固定格式编写聚焦被测核心函数的Fuzzer代码;
  • 编译验证需通过helper.py依次完成项目镜像构建、模糊测试二进制编译、二进制合规性校验
  • 模糊测试则通过helper.py启动fuzzer,监控执行效率、代码覆盖率,关注崩溃/错误提示以检测漏洞。

OSS-Fuzz通过Docker隔离环境、统一配置规范降低模糊测试门槛,开发者只需聚焦Fuzzer编写即可完成高效漏洞检测,是提升项目代码安全性的重要保障。

相关推荐
为你奋斗!7 小时前
在 Windows 上部署 Dify
测试工具
介一安全3 天前
BurpSuite 插件 FastjsonScan 使用和手动验证
测试工具·网络安全·安全性测试·安全靶场
胡楚昊4 天前
frida labs通关
安全性测试·frida
马克Markorg4 天前
使用rust实现的高性能api测试工具
开发语言·测试工具·rust·postman
介一安全5 天前
BurpSuite 插件 Log4j2Scan 使用和手动验证
测试工具·log4j·安全性测试
国科安芯6 天前
高可靠性电源方案的高温降额设计与热管理策略——基于ASP3605的温域特性实证研究
单片机·嵌入式硬件·安全威胁分析·安全性测试
观音山保我别报错6 天前
抽奖项目-接口自动化测试
功能测试·测试工具·单元测试
我的xiaodoujiao6 天前
使用 Python 语言 从 0 到 1 搭建完整 Web UI自动化测试学习系列 48--本地环境部署Jenkins服务
python·学习·测试工具·pytest
我的xiaodoujiao6 天前
使用 Python 语言 从 0 到 1 搭建完整 Web UI自动化测试学习系列 49--CI/CD-开始探索使用Jenkins
python·学习·测试工具·ci/cd·jenkins·pytest
学习3人组7 天前
Win11 使用 Proxifier 强制本地流量通过 Fiddler Classic 代理指南
前端·测试工具·fiddler