mcpField
F
fuzzing-dictionary

fuzzing-dictionary

github.com/trailofbits测试与质量7.9k5.3k 次安装今天更新
代码仓库

关于 fuzzing-dictionary

fuzzing-dictionary 是一项指导模糊测试的技术技能,介绍如何为解析器、协议处理程序和文件格式处理器准备特定词典。内容涵盖词典格式、生成方法及与多种模糊测试器的用法。

主要功能

  1. 01关键字与魔数词条
  2. 02文本及十六进制转义格式
  3. 03从头文件和二进制提取词条
  4. 04libFuzzer、AFL++ 和 cargo-fuzz 用法
  5. 05词典优化与效果排查

适用场景

  1. 01探索 JSON、XML 和配置解析器
  2. 02测试 HTTP、DNS 等协议实现
  3. 03触达 PNG、PDF 等文件格式处理逻辑

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/trailofbits/skills --skill fuzzing-dictionary

安装后在 Claude Code 中输入/fuzzing-dictionary确认已加载。

附带文件agents/openai.yamlassets/trail-of-bits-mark.svg

详细介绍

模糊测试词典

模糊测试词典提供特定领域的词元,引导模糊测试器生成有趣的输入。模糊测试器不再只进行随机变异,而是利用已知关键词、魔数、协议命令和特定格式的字符串,这些内容更有可能让解析器、协议处理程序和文件格式处理器进入更深层的代码路径。

概述

词典是包含带引号字符串的文本文件,这些字符串代表目标程序有意义的词元。它们有助于模糊测试器绕过早期的验证检查,并探索仅靠盲目变异难以触及的代码路径。

核心概念
概念描述
词典条目带引号的字符串(例如 "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:创建词典文件

创建一个文本文件,每行包含一个带引号的字符串。使用注释(#)添加说明。

词典格式示例:

# Lines starting with '#' and empty lines are ignored.

# Adds "blah" (w/o quotes) to the dictionary.
kw1="blah"
# Use \\ for backslash and \" for quotes.
kw2="\"ac\\dc\""
# Use \xAB for hex values
kw3="\xF7\xF8"
# the name of the keyword followed by '=' may be omitted:
"foo\x0Abar"
步骤 2:生成词典内容

根据可用资源选择生成方式:

**使用 LLM:**向 ChatGPT 或 Claude 提示:

A dictionary can be used to guide the fuzzer. Write me a dictionary file for fuzzing a <PNG parser>. Each line should be a quoted string or key-value pair like kw="value". Include magic bytes, chunk types, and common header values. Use hex escapes like "\xF7\xF8" for binary values.

从头文件生成:

grep -o '".*"' header.h > header.dict

从 man 页面生成(适用于 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 methods
"GET"
"POST"
"PUT"
"DELETE"
"HEAD"

# Headers
"Content-Type"
"Authorization"
"Host"

# Protocol markers
"HTTP/1.1"
"HTTP/2.0"
模式:魔数字节和文件格式头

**适用场景:**对图像解析器、媒体解码器、归档处理程序进行模糊测试

词典内容:

# PNG magic bytes and chunks
png_magic="\x89PNG\r\n\x1a\n"
ihdr="IHDR"
plte="PLTE"
idat="IDAT"
iend="IEND"

# JPEG markers
jpeg_soi="\xFF\xD8"
jpeg_eoi="\xFF\xD9"
模式:配置文件关键词

**适用场景:**对配置文件解析器进行模糊测试(YAML、TOML、INI)

词典内容:

# Common config keywords
"true"
"false"
"null"
"version"
"enabled"
"disabled"

# Section headers
"[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
# Dictionary saved to auto.dict
afl-fuzz -x auto.dict -i in -o out -- ./target
合并多个词典

某些模糊测试器支持多个词典文件:

# AFL++ with multiple dictionaries
afl-fuzz -x keywords.dict -x formats.dict -i in -o out -- ./target

反模式

反模式问题正确做法
包含完整句子Fuzzer 需要的是原子标记,而不是文章拆分为单个关键词
重复条目浪费变异预算使用 sort -u 去重
字典过大会拖慢 Fuzzer,并稀释有用标记保持精简:仅保留 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-clang-lto 时,可通过 AFL_LLVM_DICT2FILE 自动生成字典
  • 字典效果会显示在 Fuzzer 统计信息界面中
  • 标记会在确定性阶段和 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 不支持内置字典,但你可以手动使用字典条目填充语料库:

# Convert dictionary to corpus files
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=.

故障排除

问题原因解决方案
未加载字典文件路径错误或格式错误检查 Fuzzer 输出中是否有字典解析错误;验证文件格式
覆盖率没有提升字典标记不相关分析目标代码,找出实际使用的关键词;尝试不同的生成方法
字典文件中有语法错误引号未转义或转义序列无效反斜杠使用 \\,引号使用 \";通过测试运行进行验证
Fuzzer 忽略较长条目条目超过 -max_len将条目控制在最大输入长度以内,或增大 -max_len
条目过多导致 Fuzzer 变慢字典过大精简至 50-200 个最相关的条目

相关技能

使用此技术的工具
技能应用方式
libfuzzer通过 -dict= 标志提供原生字典支持
aflpp通过 -x 标志提供原生字典支持;使用 AUTODICTIONARIES 自动生成
cargo-fuzz使用 libFuzzer 后端,继承 -dict= 支持
相关技术
技能关联
fuzzing-corpus字典与语料库互为补充:语料库提供结构,字典提供关键词
coverage-analysis使用覆盖率数据验证字典效果
harness-writingharness 结构决定哪些字典标记有用

资源

主要外部资源

AFL++ Dictionaries 针对常见格式(HTML、XML、JSON、SQL 等)的预置字典,是进行特定格式模糊测试的良好起点。

libFuzzer Dictionary Documentation libFuzzer 关于字典格式和用法的官方文档,介绍标记插入策略及其对性能的影响。

更多示例

OSS-Fuzz Dictionaries 来自 Google 持续模糊测试服务的真实字典示例。搜索项目目录中的 *.dict 文件,查看生产环境中的示例。

评论

支持 Markdown