name: fuzzing-dictionary type: technique description: > 模糊测试字典通过提供特定领域的令牌来指导模糊测试器。 当模糊测试解析器、协议或格式特定代码时使用。
模糊测试字典
模糊测试字典为模糊测试器提供特定领域的令牌,以引导其生成更有趣的输入。与纯粹的随机突变不同,模糊测试器会结合已知的关键词、魔法数字、协议命令和格式特定的字符串,这些更有可能在解析器、协议处理器和文件格式处理器中触及更深的代码路径。
概述
字典是包含带引号字符串的文本文件,这些字符串代表您目标的有意义令牌。它们帮助模糊测试器绕过早期的验证检查,探索仅通过盲目突变难以触及的代码路径。
关键概念
| 概念 | 描述 |
|---|---|
| 字典条目 | 一个带引号的字符串(例如 "keyword")或键值对(例如 kw="value") |
| 十六进制转义 | 字节序列如 "\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 中显示
- 令牌在确定性和混乱阶段使用
cargo-fuzz(Rust)
cargo fuzz run fuzz_target -- -dict=./dictionary.dict
集成技巧:
- cargo-fuzz 使用 libFuzzer 后端,因此所有 libFuzzer 字典标志都适用
- 将字典文件放在
fuzz/目录中,与工具代码一起 - 从工具代码目录引用:
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 | 工具结构决定哪些字典令牌有用 |
资源
关键外部资源
AFL++ 字典 预建字典用于常见格式(HTML、XML、JSON、SQL 等)。适合格式特定模糊测试的起点。
libFuzzer 字典文档 官方 libFuzzer 文档关于字典格式和用法。解释令牌插入策略和性能影响。
额外示例
OSS-Fuzz 字典
来自 Google 连续模糊测试服务的真实世界字典。搜索项目目录中的 *.dict 文件以查看生产示例。