mcpField
O
offensive-fuzzing

offensive-fuzzing

github.com/snailsploitセキュリティ9.7k194 回インストール2 週間前に更新
リポジトリ

offensive-fuzzing について

セキュリティ研究者向けのファジング手法とツールのガイドです。ターゲット調査、テスト環境の構築、実行、クラッシュ分析を、手順やコマンド例とともに扱います。

主な機能

  1. 01ファジング方式とツールの比較
  2. 02ターゲット調査と作業手順
  3. 03ハーネスとシードコーパスの準備
  4. 04並列実行と停滞への対処
  5. 05クラッシュの分析と分類
  6. 06カーネル・言語別の参考情報

活用シーン

  1. 01ターゲットに合うファジング方式の選定
  2. 02C/C++ ソフトウェアのテスト構築
  3. 03検出クラッシュの分析と分類
  4. 04カーネルや言語別テストの計画

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/snailsploit/claude-red --skill offensive-fuzzing

インストール後、Claude Code で/offensive-fuzzingを入力して読み込まれたか確認します。

詳細

オフェンシブファジング

ファザーの種類

種類カバレッジ速度ツール
BlackBox低い高速Peach, Boofuzz
GreyBox良好高速AFL++, Honggfuzz, libFuzzer, WinAFL
Snapshot良好最速Nyx, wtf, Snapchange
WhiteBox最良低速KLEE, QSYM, SymSan
Ensemble最良高速AFL++ + Honggfuzz + libFuzzer

GreyBox のサブタイプ: Directed(AFLGo, UAFuzz)、Grammar(AFLSmart, Tlspuffin)、Concolic(QSYM, Driller)、Kernel(syzkaller, kAFL, wtf)。

基本的なワークフロー

Research target → Choose analyses → Build harness → Seed corpus → Instrument → Fuzz → Triage crashes → Report
1. 対象を調査する
  • すべての入力箇所(ファイル、ネットワーク、IPC、システムコール、IOCTL)を洗い出します
  • 価値の高い領域を特定します。過去にパッチが適用されたコード、複雑なパーサー、新たに追加されたコード、入力の取り込み箇所などです
  • カーネルモジュールの場合は、copy_from_user だけでなく、DMA-BUF の操作、ページフォールトハンドラー、VM 操作構造体、割り当てコールバックも調べます
2. 計装してビルドする
# AFL++ (preferred for GreyBox)
CC=afl-clang-fast CXX=afl-clang-fast++ cmake -DCMAKE_BUILD_TYPE=Release .. && make -j

# libFuzzer + ASan/UBSan (C/C++)
cmake -DCMAKE_CXX_FLAGS="-fsanitize=fuzzer,address,undefined -O1 -g" ..

# CmpLog build for hard compares
AFL_LLVM_CMPLOG=1 CC=afl-clang-fast CXX=afl-clang-fast++ make clean all

Windows(MSVC): Project Properties → C/C++ → Address Sanitizer: Yes (/fsanitize=address)

3. ハーネスを作成する

libFuzzer(C++):

#include <cstdint>
#include <cstddef>
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
    parse_or_process(data, size);
    return 0;
}

Honggfuzz HF_ITER(永続モード — 大規模な対象に推奨):

#include "honggfuzz.h"
int main(int argc, char** argv) {
    initialize_target(); // runs once
    for (;;) {
        size_t len; uint8_t *buf;
        HF_ITER(&buf, &len);
        FILE* s = fmemopen(buf, len, "r");
        target_function(s);
        fclose(s);
        reset_target_state();
    }
}

AFL++ 永続モード(__AFL_LOOP):

while (__AFL_LOOP(10000)) {
    // re-read input and process
}

macOS IPC(Mach メッセージファジング):

void *lib_handle = dlopen("libexample.dylib", RTLD_LAZY);
pFunction = dlsym(lib_handle, "DesiredFunction");
4. シードコーパスを作成する
  • 対象のテストスイート、バグ報告、実際のサンプルから収集します
  • ファイル形式については Web をクロール(Common Crawl)し、MIME タイプでフィルタリングします
  • 最小化します:afl-cmin -i raw_corpus -o seeds -- ./target @@
  • 入力をトリミングします:afl-tmin -i crash -o crash.min -- ./target @@
5. ファジングを開始する

AFL++ 並列実行(プライマリ + cmplog を使用するセカンダリ):

afl-fuzz -M f1 -i seeds -o findings -x dict.txt -- ./target @@
afl-fuzz -S s1 -i seeds -o findings -c 0 -- ./target @@

libFuzzer:

./target_libfuzzer corpus/ -max_total_time=3600 -workers=4

バイナリのみ(QEMU):

afl-fuzz -Q -i seeds -o findings -- target.exe @@

スナップショット(AFL++ Nyx):

NYX_MODE=1 AFL_MAP_SIZE=1048576 afl-fuzz -i seeds -o findings -- ./target_nyx @@

Ensemble(AFL++ + Honggfuzz でコーパスを共有):

# Terminal 1
afl-fuzz -M fuzzer1 -i seeds -o sync_dir -- ./target @@
# Terminal 2
../honggfuzz/honggfuzz -i sync_dir/fuzzer1/queue -W sync_dir/hfuzz \
  --linux_perf_ipt_block -t 10 -- ./target ___FILE___
6. 進捗を監視し、停滞を解消する

進捗が停滞した場合:

  • AFL++ のセカンダリで CmpLog を有効にします:-c 0
  • 辞書を追加します:-x dict.txt または AFL_TOKEN_FILE
  • 特定の BB/関数を対象に、Directed ファジング(AFLGo)へ切り替えます
  • 難しい分岐では、コンコリック実行による支援(QSYM, Driller)を使用します
  • 対象をスナップショット化して exec/s を増やします
  • MOpt スケジューラーでは AFL_MAP_SIZE=1048576、-L 0 を指定します
7. クラッシュをトリアージする
# 1. Minimize
afl-tmin -i crash -o crash.min -- ./target @@
# 2. Symbolize
ASAN_OPTIONS=abort_on_error=1:symbolize=1 ./target crash.min 2>asan.log
# 3. Hash + bucket
./cov-tool --bbids ./target crash.min > cov.hash
./bucket.py --key "$(cat cov.hash)" --log asan.log --out triage/

サニタイザー環境変数のクイックリファレンス:

ASAN_OPTIONS=abort_on_error=1:symbolize=1:detect_stack_use_after_return=1
UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1
TSAN_OPTIONS=halt_on_error=1:history_size=7
MSAN_OPTIONS=poison_in_dtor=1:track_origins=2

オラクルの選択

バグの種類オラクル
メモリー安全性ASan, HWASan(AArch64、オーバーヘッドが低い)
初期化されていない読み取りMSan
並行処理TSan
未定義動作UBSan
型安全性TypeSan
ヒープの強化Scudo Hardened Allocator
ロジックバグ差分/冪等性オラクル
カーネルメモリーKASAN, KMSAN, KCSAN
カーネルの未定義動作KUBSan(CONFIG_UBSAN_TRAP=y)
CFIKCFI(-fsanitize=kcfi、Clang 18)
バイナリのみQASAN(QEMU+ASan)、DynamoRIO

プロパティオラクルのパターン:

  • 冪等性:f(x) == f(f(x))
  • 差分:2 つの実装を比較し、出力の不一致で分類します
  • 不変条件:単調な長さ、チェックサムの一致、解析後のスキーマ検証

特殊な対象

カーネル(Linux)— syzkaller
{
  "target": "linux/arm64",
  "http": ":56700",
  "workdir": "/path/to/workdir",
  "kernel_obj": "/path/to/kernel",
  "image": "/path/to/rootfs.ext3",
  "sshkey": "/path/to/id_rsa",
  "procs": 8,
  "enable_syscalls": ["openat$module_name", "ioctl$IOCTL_CMD", "mmap"],
  "type": "qemu",
  "vm": { "count": 4, "cpu": 2, "mem": 2048 }
}
  • 特定のサブシステムのカバレッジを深めるため、enable_syscalls を制限します
  • syz-extract を使用して、カスタムモジュール向けの定数を取得します
  • CONFIG_KASAN=y、CONFIG_KCFI=y、CONFIG_DEBUG_INFO_BTF=y を有効にします
  • kcov フィルターと syz_cover_filter を使用してカバレッジを誘導します
  • ネットワークファジング:TUN/TAP と疑似システムコール(syz_emit_ethernet)を介して注入します
  • クラッシュのデコード:./scripts/decode_stacktrace.sh vmlinux ... < dmesg.log

syzkaller の再現ケース:

syz-execprog -repeat=0 -procs=1 -cover=0 -debug target.repro
EDR/Windows スキャンエンジン

WTF スナップショットハーネスのひな形(mpengine.dll / mini-filter):

g_Backend->SetBreakpoint("nt!KeBugCheck2", [](Backend_t *Backend) {
    const uint64_t BCode = Backend->GetArg(0);
    Backend->Stop(Crash_t(fmt::format("crash-{:#x}", BCode)));
});

FilterConnectionPort のファジング:

HANDLE hPort;
FilterConnectCommunicationPort(L"\\PortName", 0, NULL, 0, NULL, &hPort);
FilterSendMessage(hPort, fuzzData, sizeof(fuzzData), NULL, 0, &bytesReturned);

IOCTL ファジングのパターン:

HANDLE hDev = CreateFile(L"\\\\.\\DeviceName", GENERIC_READ|GENERIC_WRITE, ...);
DeviceIoControl(hDev, ioctlCode, inputBuf, inputLen, outBuf, outLen, &ret, NULL);
  • 初期化後、解析/ディスパッチループの直前にスナップショットを取得します
  • カバレッジを可視化するには IDA Lighthouse を使用します
  • DRIVER_VERIFIER_DETECTED_VIOLATION (0xc4)、IRQL_NOT_LESS_OR_EQUAL (0xa) を監視します
  • WinDbg:.symfix; !analyze -v; k; !heap -p -a @rax

Linux 上のクロスプラットフォーム mpengine.dll(loadlibrary + HF_ITER + Intel PT):

// Bypass Lua VM to avoid stability issues
insert_function_redirect((void*)luaV_execute_address, my_lua_exec, HOOK_REPLACE_FUNCTION);
for (;;) {
    HF_ITER(&buf, &len);
    ScanDescriptor.UserPtr = fmemopen(buf, len, "r");
    __rsignal(&KernelHandle, RSIG_SCAN_STREAMBUFFER, &ScanParams, sizeof ScanParams);
}
Rust
# Full Rust fuzzing pipeline
cargo test                                         # 1. property tests
cargo +nightly miri test                           # 2. UB via interpreter
cargo +nightly careful test                        # 3. runtime bounds checks
cargo fuzz run fuzz_target_1 -- -max_total_time=3600  # 4. libFuzzer crashes
RUSTFLAGS="--cfg loom" cargo test --release        # 5. concurrency (if needed)
cargo fuzz coverage fuzz_target_1                  # 6. coverage report

次の項目に関する unsafe ブロックに重点を置きます:Vec::from_raw_parts、境界チェックなしのインデックスアクセス、transmute のサイズ不一致、ポインター演算、FFI の整数切り詰め。

組み込み/バイナリのみ
  • LibAFL:モジュール式の Rust フレームワーク。Unicorn エンジン、スナップショットモジュール、LBRFeedback(Intel でインストルメンテーションなし)、SAND による分離型サニタイズに対応
  • Retrowrite / QASAN:ソースなしでカバレッジと ASan を実現するバイナリ書き換え
  • Nautilus:構造化フォーマット向けの文法ベースのファジング
言語エコシステム
  • Go 1.18+:go test -fuzz=Fuzz -run=^$ ./...
  • Python:Atheris(CPython ネイティブ拡張のファジング)
  • Rust:cargo-fuzz または honggfuzz-rs
  • JS エンジン:拡張インストルメンテーションを備えた Fuzzilli(PC の追跡には __builtin_return_address(0) を使用)
  • Wasm ランタイム:V8/Wasmer/Wasmtime 間の差分ファジングには wasmtime-fuzz、wafl
  • スマートコントラクト:Echidna、Foundry-fuzz(Solidity);Move-Fuzz(Aptos/Sui)

CI/CD 統合

- name: Build with afl-clang-fast
  run: CC=afl-clang-fast make -j
- name: Fuzz (smoke, 15 min)
  run: timeout 15m afl-fuzz -i seeds -o findings -- ./target @@ || true
- name: Upload crashes
  if: always()
  uses: actions/upload-artifact@v4
  with:
    path: findings/**/crashes/*

永続的な継続的ファジングには ClusterFuzzLite を使用し、実行間でコーパスをキャッシュします。

クラッシュ分析のクイックリファレンス

Linux:

ulimit -c unlimited && sysctl -w kernel.core_pattern=core.%e.%p
gdb -q ./target core.* -ex 'bt' -ex 'info reg' -ex q
addr2line -e ./target 0xDEADBEEF

Windows:

# Enable local dumps
New-Item 'HKLM:\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps' -Force
# PageHeap
gflags /p /enable target.exe /full

カーネル KASAN/KMSAN:

dmesg -T | egrep -i 'kasan|kmsan' -A 60
./scripts/decode_stacktrace.sh vmlinux /lib/modules/$(uname -r)/build < dmesg.log

再現性: CPU ガバナーを固定し、安全な場合に限り ASLR を無効にし、RNG シードを固定します。永続モードでは入力シーケンスを保存し、クラッシュごとにバイナリのハッシュとサニタイザーのオプションを記録します。

ツール一覧

ツール用途
AFL++汎用 GreyBox、CmpLog、MOpt、Nyx
HonggfuzzIntel PT、クラッシュ検出、HF_ITER
libFuzzerプロセス内、ソースコードが利用可能な場合
syzkallerLinux/Windows カーネルのシステムコールファジング
wtfスナップショットファジング、Windows ターゲット
NyxAFL++ のスナップショットモード(Intel PT)
SnapchangeAWS のスナップショットファジング
LibAFLカスタム Rust ファジングフレームワーク
AFLGo対象の BB/関数に向けた指向性ファジング
kAFLカーネルおよび OS のファジング
Jackalopeバイナリのカバレッジガイド型ファジング(Windows/macOS)
cargo-fuzzRust と libFuzzer の統合
AtherisPython のファジング
Nautilus文法ベースのファジング
AFLTriageクラッシュの自動トリアージ
afl-covAFL++ のカバレッジ分析
ClusterFuzz分散ファジングインフラストラクチャ

コメント