名称: 模糊测试字典 类型: 技术 描述: > 模糊测试字典通过领域特定的令牌指导模糊测试器。 当模糊测试解析器、协议或格式特定代码时使用。
模糊测试字典
一个模糊测试字典提供领域特定的令牌来指导模糊测试器生成有趣的输入。而不是纯粹的随机变异,模糊测试器会结合已知的关键词、魔法数字、协议命令和格式特定的字符串,这些更可能达到解析器、协议处理器和文件格式处理器中更深的代码路径。
概述
字典是包含带引号的字符串的文本文件,代表您目标的有意义令牌。它们帮助模糊测试器绕过早期验证检查,探索难以通过盲目变异达到的代码路径。
关键概念
| 概念 | 描述 |
|---|---|
| 字典条目 | 一个带引号的字符串(例如,"关键词")或键值对(例如,kw="值") |
| 十六进制转义 | 字节序列如 "\xF7\xF8" 用于非打印字符 |
| 令牌注入 | 模糊测试器将字典条目插入生成的输入中 |
| 跨模糊测试器格式 | 字典文件适用于 libFuzzer、AFL++ 和 cargo-fuzz |
何时应用
应用此技术当:
- 模糊测试解析器(JSON、XML、配置文件)
- 模糊测试协议实现(HTTP、DNS、自定义协议)
- 模糊测试文件格式处理器(PNG、PDF、媒体编解码器)
- 覆盖率早期停滞,未达到更深逻辑
- 目标代码检查特定关键词或魔法值
跳过此技术当:
- 模糊测试纯算法,无格式预期
- 目标无基于关键词的解析
- 语料库已实现高覆盖率
快速参考
| 任务 | 命令/模式 |
|---|---|
| 与 libFuzzer 使用 | ./fuzz -dict=./dictionary.dict ... |
| 与 AFL++ 使用 | afl-fuzz -x ./dictionary.dict ... |
| 与 cargo-fuzz 使用 | cargo fuzz run fuzz_target -- -dict=./dictionary.dict |
| 从头部提取 | grep -o '".*"' header.h > header.dict |
| 从二进制生成 | strings ./binary | sed 's/^/"&/; s/$/&"/' > strings.dict |
逐步操作
步骤 1: 创建字典文件
创建一个文本文件,每行包含带引号的字符串。使用注释(#)进行文档化。
示例字典格式:
# 以 '#' 开头的行和空行被忽略。
# 添加 "blah"(不带引号)到字典。
kw1="blah"
# 使用 \\ 表示反斜杠,\" 表示引号。
kw2="\"ac\\dc\""
# 使用 \xAB 表示十六进制值
kw3="\xF7\xF8"
# 关键字名称后跟 '=' 可以省略:
"foo\x0Abar"
步骤 2: 生成字典内容
基于可用的内容选择生成方法:
从 LLM: 用以下内容提示 ChatGPT 或 Claude:
可以使用字典来指导模糊测试器。为我编写一个用于模糊测试 <PNG 解析器> 的字典文件。每行应该是一个带引号的字符串或键值对,如 kw="value"。包括魔法字节、块类型和常见头部值。对二进制值使用十六进制转义如 "\xF7\xF8"。
从头部文件:
grep -o '".*"' header.h > header.dict
从手册页(用于 CLI 工具):
man curl | grep -oP '^\s*(--|-)\K\S+' | sed 's/[,.]$//' | sed 's/^/"&/; s/$/&"/' | sort -u > man.dict
从二进制字符串:
strings ./binary | sed 's/^/"&/; s/$/&"/' > strings.dict
步骤 3: 将字典传递给模糊测试器
使用适当的标志为您的模糊测试器(见上面快速参考)。
常见模式
模式: 协议关键词
使用案例: 模糊测试 HTTP 或自定义协议处理器
字典内容:
# HTTP 方法
"GET"
"POST"
"PUT"
"DELETE"
"HEAD"
# 头部
"Content-Type"
"Authorization"
"Host"
# 协议标记
"HTTP/1.1"
"HTTP/2.0"
模式: 魔法字节和文件格式头部
使用案例: 模糊测试图像解析器、媒体解码器、归档处理器
字典内容:
# PNG 魔法字节和块
png_magic="\x89PNG\r
\x1a
"
ihdr="IHDR"
plte="PLTE"
idat="IDAT"
iend="IEND"
# JPEG 标记
jpeg_soi="\xFF\xD8"
jpeg_eoi="\xFF\xD9"
模式: 配置文件关键词
使用案例: 模糊测试配置文件解析器(YAML、TOML、INI)
字典内容:
# 常见配置关键词
"true"
"false"
"null"
"version"
"enabled"
"disabled"
# 部分头部
"[general]"
"[network]"
"[security]"
高级用法
技巧与窍门
| 技巧 | 为什么有帮助 |
|---|---|
| 结合多种生成方法 | LLM 生成的关键词 + 来自二进制的字符串覆盖广泛表面 |
| 包括边界值 | "0", "-1", "2147483647" 触发边缘情况 |
| 添加格式分隔符 | :, =, {, } 帮助模糊测试器构建有效结构 |
| 保持字典聚焦 | 50-200 条目比数千条表现更好 |
| 测试字典效果 | 运行有和无字典,比较覆盖率 |
自动生成字典(AFL++)
当使用 afl-clang-lto 编译器时,AFL++ 自动从二进制中的字符串比较提取字典条目。这通过 AUTODICTIONARY 特性在编译时发生。
启用自动字典:
export AFL_LLVM_DICT2FILE=auto.dict
afl-clang-lto++ target.cc -o target
# 字典保存到 auto.dict
afl-fuzz -x auto.dict -i in -o out -- ./target
结合多个字典
一些模糊测试器支持多个字典文件:
# AFL++ 与多个字典
afl-fuzz -x keywords.dict -x formats.dict -i in -o out -- ./target
反模式
| 反模式 | 问题 | 正确方法 |
|---|---|---|
| 包含完整句子 | 模糊测试器需要原子令牌,而不是散文 | 分解为独立关键词 |
| 重复条目 | 浪费变异预算 | 使用 sort -u 去重 |
| 过大的字典 | 减慢模糊测试器,稀释有用令牌 | 保持聚焦:50-200 个最相关条目 |
| 缺少十六进制转义 | 非打印字节被破坏 | 对二进制值使用 \xXX |
| 无注释 | 难以维护和审计 | 用 # 注释文档化部分 |
工具特定指导
libFuzzer
clang++ -fsanitize=fuzzer,address harness.cc -o fuzz
./fuzz -dict=./dictionary.dict corpus/
集成提示:
- 字典令牌在变异期间插入/替换
- 结合
-max_len控制输入大小 - 使用
-print_final_stats=1查看字典效果指标 - 超过
-max_len的字典条目被忽略
AFL++
afl-fuzz -x ./dictionary.dict -i input/ -o output/ -- ./target @@
集成提示:
- AFL++ 支持多个
-x标志用于多个字典 - 使用
AFL_LLVM_DICT2FILE与afl-clang-lto用于自动生成字典 - 字典效果显示在模糊测试器统计 UI
- 令牌在确定性和 havoc 阶段使用
cargo-fuzz (Rust)
cargo fuzz run fuzz_target -- -dict=./dictionary.dict
集成提示:
- cargo-fuzz 使用 libFuzzer 后端,所以所有 libFuzzer 字典标志有效
- 将字典文件放在
fuzz/目录中,与 harness 相邻 - 从 harness 目录引用:
cargo fuzz run target -- -dict=../dictionary.dict
go-fuzz (Go)
go-fuzz 没有内置字典支持,但您可以手动播种语料库与字典条目:
# 转换字典为语料库文件
grep -o '".*"' dict.txt | while read line; do
echo -n "$line" | base64 > corpus/$(echo "$line" | md5sum | cut -d' ' -f1)
done
go-fuzz -bin=./target-fuzz.zip -workdir=.
故障排除
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 字典文件未加载 | 错误路径或格式错误 | 检查模糊测试器输出以解析字典错误;验证文件格式 |
| 无覆盖率改进 | 字典令牌不相关 | 分析目标代码的实际关键词;尝试不同的生成方法 |
| 字典文件语法错误 | 未转义的引号或无效转义 | 使用 \\ 表示反斜杠,\" 表示引号;通过测试运行验证 |
| 模糊测试器忽略长条目 | 条目超过 -max_len |
保持条目在最大输入长度下,或增加 -max_len |
| 过多条目减慢模糊测试器 | 字典太大 | 修剪到 50-200 个最相关条目 |
相关技能
使用此技术的工具
| 技能 | 如何应用 |
|---|---|
| libfuzzer | 通过 -dict= 标志原生支持字典 |
| aflpp | 通过 -x 标志原生支持字典;通过 AUTODICTIONARIES 自动生成 |
| cargo-fuzz | 使用 libFuzzer 后端,继承 -dict= 支持 |
相关技术
| 技能 | 关系 |
|---|---|
| fuzzing-corpus | 字典补充语料库:语料库提供结构,字典提供关键词 |
| coverage-analysis | 使用覆盖率数据验证字典效果 |
| harness-writing | Harness 结构决定哪些字典令牌有用 |
资源
关键外部资源
AFL++ Dictionaries 预构建字典用于常见格式(HTML、XML、JSON、SQL 等)。格式特定模糊测试的良好起点。
libFuzzer Dictionary Documentation libFuzzer 官方文档关于字典格式和用法。解释令牌插入策略和性能影响。
额外示例
OSS-Fuzz Dictionaries
来自 Google 连续模糊测试服务的真实世界字典。搜索项目目录中的 *.dict 文件以查看生产示例。