mcpField
I
implementing-fuzz-testing-in-cicd-with-aflplusplus

implementing-fuzz-testing-in-cicd-with-aflplusplus

github.com/mukul975テスト・品質35.2k42 回インストール8 週間前に更新
リポジトリ

implementing-fuzz-testing-in-cicd-with-aflplusplus について

コンパイル済みアプリケーションのCI/CDに、AFL++のカバレッジガイド型ファジングを導入するガイドです。ハーネス、計装、コーパス準備、並列実行、クラッシュ分析を扱います。

主な機能

  1. 01カバレッジガイド型の入力変異テスト
  2. 02ソースとバイナリの計装モード
  3. 03ファジングを高速化する永続モード
  4. 04シードコーパスの最小化
  5. 05CI/CDと夜間テストの設定
  6. 06クラッシュの再現とトリアージ

活用シーン

  1. 01信頼できない入力を扱うパーサーのテスト
  2. 02CI/CDでの定期的なファジング実行
  3. 03ソースコードのないバイナリのファジング
  4. 04発見したクラッシュの再現と整理

インストール

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

$npx skills add https://github.com/mukul975/anthropic-cybersecurity-skills --skill implementing-fuzz-testing-in-cicd-with-aflplusplus

インストール後、Claude Code で/implementing-fuzz-testing-in-cicd-with-aflplusplusを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

LICENSE
assets/
template.md
references/
api-reference.md
standards.md
workflows.md
scripts/
agent.py
process.py

詳細

AFL++ を使用した CI/CD でのファジングテストの実装

概要

AFL++(American Fuzzy Lop Plus Plus)は、コミュニティによって維持されている AFL のフォークであり、コンパイル済みアプリケーションの脆弱性を発見するための最先端のカバレッジガイド型ファジングテストを提供します。AFL++ は遺伝的アルゴリズムを使用して入力を変異させ、コードカバレッジを追跡することで、クラッシュ、ハング、未定義動作を引き起こす新しい実行パスを見つけ出します。CI/CD 環境では、AFL++ を統合して、パーサー、プロトコルハンドラー、ファイル形式プロセッサー、および信頼できない入力を処理するあらゆるコードを継続的にテストできます。AFL++ は、高速ファジング用の永続モード(毎秒 100,000 回以上の実行)、カスタムミューテーター、バイナリのみのファジング用の QEMU モード、自動辞書抽出用の CmpLog/RedQueen をサポートしています。

使用するタイミング

  • 環境で AFL++ を用いた CI/CD でのファジングテストの実装機能を展開または構成する場合
  • コンプライアンス要件に沿ったセキュリティ統制を確立する場合
  • この分野のセキュリティアーキテクチャを構築または改善する場合
  • この実装を必要とするセキュリティ評価を実施する場合

前提条件

  • Linux ベースの CI ランナー(AFL++ は Windows をネイティブにサポートしていません)
  • GCC または Clang コンパイラツールチェーン
  • AFL++ のインストール(apt install aflplusplus またはソースからのビルド)
  • 入力処理を分離するハーネス関数を備えた対象アプリケーション
  • 有効な入力サンプルのシードコーパス

中核的な概念

カバレッジガイド型ファジング

AFL++ は、コンパイル時(またはバイナリのみの対象の場合は QEMU/Frida 経由)に対象バイナリをインストルメント化し、各入力がどのコードパスを実行するかを追跡します。変異させた入力が新しいコードパスをトリガーすると、さらに変異させるためにコーパスに保存されます。このフィードバックループにより、AFL++ はプログラムの状態空間を体系的に探索できます。

インストルメンテーションモード
モード用途パフォーマンス
afl-clang-fast (LTO)ソースあり、最高のパフォーマンス最高
afl-clang-fastソースあり、標準高
afl-gcc-fastGCC ベースのプロジェクト高
QEMU modeバイナリのみ、ソースなし中
Frida modeバイナリのみ、クロスプラットフォーム中
Unicorn modeファームウェア、組み込み低
永続モード

永続モードは、ループ内でファジングを行うことにより fork のオーバーヘッドを回避します。

#include <unistd.h>

__AFL_FUZZ_INIT();

int main() {
    __AFL_INIT();
    unsigned char *buf = __AFL_FUZZ_TESTCASE_BUF;

    while (__AFL_LOOP(10000)) {
        int len = __AFL_FUZZ_TESTCASE_LEN;
        // Process buf[0..len-1]
        parse_input(buf, len);
    }
    return 0;
}

ワークフロー

ステップ 1 --- ファジングハーネスの構築

AFL++ の入力を対象関数に供給するハーネスを作成します。

// fuzz_harness.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "target_parser.h"

__AFL_FUZZ_INIT();

int main() {
    __AFL_INIT();
    unsigned char *buf = __AFL_FUZZ_TESTCASE_BUF;

    while (__AFL_LOOP(10000)) {
        int len = __AFL_FUZZ_TESTCASE_LEN;
        if (len < 4) continue;

        // Reset state between iterations
        parser_context_t ctx;
        parser_init(&ctx);
        parser_process(&ctx, buf, len);
        parser_cleanup(&ctx);
    }
    return 0;
}
ステップ 2 --- AFL++ インストルメンテーションでのコンパイル
# Standard instrumentation
export CC=afl-clang-fast
export CXX=afl-clang-fast++

# Enable AddressSanitizer for better crash detection
export AFL_USE_ASAN=1

# Build the target with instrumentation
$CC -o fuzz_harness fuzz_harness.c -ltarget_parser -fsanitize=address

# Build a CmpLog binary for better coverage
$CC -o fuzz_harness_cmplog fuzz_harness.c -ltarget_parser \
  -fsanitize=address -DCMPLOG
ステップ 3 --- シードコーパスの準備
mkdir -p corpus/
# Add valid input samples
cp test_inputs/* corpus/
# Minimize the corpus
afl-cmin -i corpus/ -o corpus_min/ -- ./fuzz_harness @@
# Further minimize individual inputs
mkdir -p corpus_tmin/
for f in corpus_min/*; do
    afl-tmin -i "$f" -o "corpus_tmin/$(basename $f)" -- ./fuzz_harness @@
done
ステップ 4 --- CI/CD 統合の構成

GitHub Actions:

name: Fuzz Testing
on:
  push:
    branches: [main]
  schedule:
    - cron: '0 2 * * *'  # Nightly fuzzing

jobs:
  fuzz:
    runs-on: ubuntu-latest
    timeout-minutes: 120
    steps:
      - uses: actions/checkout@v4

      - name: Install AFL++
        run: |
          sudo apt-get update
          sudo apt-get install -y aflplusplus

      - name: Restore corpus cache
        uses: actions/cache@v4
        with:
          path: corpus/
          key: fuzz-corpus-${{ github.sha }}
          restore-keys: fuzz-corpus-

      - name: Build fuzzing harness
        run: |
          export CC=afl-clang-fast
          export AFL_USE_ASAN=1
          make fuzz_harness

      - name: Run AFL++ fuzzing (CI mode)
        env:
          AFL_CMPLOG_ONLY_NEW: 1
          AFL_FAST_CAL: 1
          AFL_NO_STARTUP_CALIBRATION: 1
        run: |
          mkdir -p findings/
          timeout 7200 afl-fuzz \
            -S ci_fuzzer \
            -i corpus/ \
            -o findings/ \
            -t 5000 \
            -- ./fuzz_harness @@ || true

      - name: Check for crashes
        run: |
          CRASHES=$(find findings/ -path "*/crashes/*" -not -name "README.txt" | wc -l)
          echo "Found $CRASHES unique crashes"
          if [ "$CRASHES" -gt 0 ]; then
            echo "::error::AFL++ found $CRASHES crashes"
            for crash in findings/*/crashes/*; do
              [ -f "$crash" ] && echo "Crash: $crash ($(wc -c < $crash) bytes)"
            done
            exit 1
          fi

      - name: Update corpus cache
        if: always()
        run: |
          afl-cmin -i findings/ci_fuzzer/queue/ -o corpus/ -- ./fuzz_harness @@
ステップ 5 --- 夜間実行のための並列ファジング
# Launch multiple secondary instances for better coverage
for i in $(seq 1 $(nproc)); do
    afl-fuzz -S fuzzer_$i \
      -i corpus/ \
      -o findings/ \
      -- ./fuzz_harness @@ &
done

# Wait for all fuzzers
wait

# Merge and minimize corpus
afl-cmin -i findings/*/queue/ -o corpus_merged/ -- ./fuzz_harness @@
ステップ 6 --- クラッシュのトリアージ
# Reproduce and categorize crashes
for crash in findings/*/crashes/*; do
    echo "=== Testing: $crash ==="
    timeout 5 ./fuzz_harness_asan "$crash" 2>&1 | head -20
    echo "---"
done

# Deduplicate crashes by stack trace
afl-collect findings/ crashes_deduped/ -- ./fuzz_harness @@

AFL++ の CI/CD ベストプラクティス

設定CI 短時間実行夜間長時間実行
実行時間30〜60 分4〜24 時間
モード-S(セカンダリのみ)-S(CI では -M なし)
AFL_CMPLOG_ONLY_NEW11
AFL_FAST_CAL10
AFL_NO_STARTUP_CALIBRATION10
コーパスのキャッシュ必須必須
並列インスタンス1〜2nproc

ファジングキャンペーンの監視

# View fuzzing statistics
afl-whatsup findings/

# Key metrics to track:
# - Total paths found (code coverage indicator)
# - Unique crashes / unique hangs
# - Stability percentage (should be >90%)
# - Exec speed (execs/sec)
# - Cycles done (full corpus cycles completed)

参考資料

コメント