mcpField
F
fuzzing-dictionary

fuzzing-dictionary

github.com/trailofbitsテスト・品質7.9k5.3k 回インストール今日更新
リポジトリ

fuzzing-dictionary について

fuzzing-dictionary は、ファザーをより深いコードパスへ導くトークン辞書の作成方法を説明する技術ガイドです。辞書形式や生成方法、複数のファザーでの利用手順を扱います。

主な機能

  1. 01キーワードとマジック値の登録
  2. 02テキストと16進エスケープ形式
  3. 03ヘッダーやバイナリからの抽出
  4. 04libFuzzer、AFL++、cargo-fuzzでの利用
  5. 05辞書の調整と問題の診断

活用シーン

  1. 01JSON、XML、設定ファイルパーサーの調査
  2. 02HTTP、DNSなどのプロトコル実装のテスト
  3. 03PNGや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")
16 進エスケープ印字できない文字のバイト列(例:"\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

アンチパターン

アンチパターン問題正しい方法
完全な文章を含めるファザーに必要なのは文章ではなく、個別のトークンです個々のキーワードに分割します
エントリーを重複させるミューテーションの予算を無駄にしますsort -u で重複を削除します
辞書が大きすぎるファザーの速度が低下し、有用なトークンが埋もれます重要度の高い50~200個に絞ります
16進エスケープがない印字できないバイトが文字化けしますバイナリ値には \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 を使用します
  • 辞書の有効性はファザーの統計 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 には組み込みの辞書サポートがありませんが、辞書のエントリーを使ってコーパスに手動でシードを追加できます:

# 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=.

トラブルシューティング

問題原因解決策
辞書ファイルが読み込まれないパスが間違っているか、形式エラーがあるファザーの出力で辞書の解析エラーを確認し、ファイル形式を検証します
カバレッジが改善しない辞書トークンが対象に関連していない対象コードを分析して実際のキーワードを確認し、別の生成方法を試します
辞書ファイルの構文エラー引用符のエスケープ漏れ、または無効なエスケープバックスラッシュには \\、引用符には \" を使用し、テスト実行で検証します
ファザーが長いエントリーを無視するエントリーが -max_len を超えているエントリーを最大入力長未満にするか、-max_len を増やします
エントリーが多すぎてファザーが遅くなる辞書が大きすぎる重要度の高い50~200個に絞ります

関連スキル

この手法を使うツール
スキル適用方法
libfuzzer-dict= フラグによるネイティブの辞書サポート
aflpp-x フラグによるネイティブの辞書サポート。AUTODICTIONARIES による自動生成
cargo-fuzzlibFuzzer バックエンドを使用し、-dict= のサポートを継承
関連する手法
スキル関連性
fuzzing-corpus辞書はコーパスを補完します。コーパスが構造を提供し、辞書がキーワードを提供します
coverage-analysisカバレッジデータを使用して、辞書の有効性を検証します
harness-writingハーネスの構造によって、どの辞書トークンが有用かが決まります

リソース

主な外部リソース

AFL++ 辞書 一般的な形式(HTML、XML、JSON、SQL など)向けの事前構築済み辞書です。形式固有のファジングを始める際に役立ちます。

libFuzzer 辞書のドキュメント 辞書の形式と使い方に関する libFuzzer の公式ドキュメントです。トークンの挿入方法とパフォーマンスへの影響について説明しています。

追加の例

OSS-Fuzz の辞書 Google の継続的ファジングサービスで使用されている、実際の辞書です。プロジェクトのディレクトリで *.dict ファイルを検索すると、実運用の例を確認できます。

コメント