コンテンツにスキップ

cargo-fuzz - Rustをlibfuzzerでファジング チートシート

cargo-fuzz - Rustをlibfuzzerでファジング チートシート

cargo-fuzzはRustコードをファザーする標準方法。ライブラリー処理されたワークフロー:ファザー ターゲットを書く 任意バイトを取りlibfuzzerCargoネイティブ、cargo fuzz runを実行、カバレッジガイド付きファジング狩り パニック、算術オーバーフロー、および—unsafeコード—本当の メモリー エラー。安全Rustはメモリー 腐敗を防ぎ、パニック、無限ループ、またはロジック バグを防ぎません、CFF 依存関係はメモリー クラス 全体を再導入します。

インストール

StepCommand
Installcargo install cargo-fuzz
Nightly requiredrustup install nightly(libFuzzer 夜 必要)
Initializecargo fuzz init(クレートで)
Verifycargo fuzz --version

ファザー ターゲット作成

cargo fuzz init                 # fuzz/ディレクトリー作成
cargo fuzz add parse_input      # 新しいターゲット作成
// fuzz/fuzz_targets/parse_input.rs
#![no_main]
use libfuzzer_sys::fuzz_target;

fuzz_target!(|data: &[u8]| {
    if let Ok(s) = std::str::from_utf8(data) {
        let _ = my_crate::parse(s);   // ここパニック 検査結果
    }
});

実行

CommandDescription
cargo fuzz run parse_inputターゲット ファザー
cargo fuzz run parse_input -- -max_total_time=3005分で実行
cargo fuzz run parse_input -j 88並列ジョブ
cargo fuzz listターゲット リスト
cargo fuzz buildビルド実行なし

任意で構造化入力

ロー バイトは時間入力パーサー即座に拒否に無駄。arbitraryクレート 構築型値 代わりに:

use arbitrary::Arbitrary;

#[derive(Arbitrary, Debug)]
struct Config { name: String, retries: u8, enabled: bool }

fuzz_target!(|cfg: Config| {
    let _ = my_crate::apply_config(cfg);
});
BenefitWhy
Valid-shaped inputsより深いロジック到達
Typed targetsAPI ファザー、パーサー だけではなく
Debug output読み取り可能な 再ジューサー

サニタイザー

SanitizerFlag
AddressSanitizer (default)-s address
LeakSanitizerASanに含まれる
MemorySanitizer-s memory
ThreadSanitizer-s thread
None (faster)-s none
# ASan持つ unsafe FFI コードをファザー
cargo fuzz run ffi_target -s address

コーパスおよびカバレッジ

CommandPurpose
fuzz/corpus/<target>/興味深い 入力 蓄積ところ
cargo fuzz cmin <target>コーパス 最小化
cargo fuzz tmin <target> <input>クラッシュ 入力を最小化
cargo fuzz coverage <target>カバレッジ データ生成
Seed corpus有効な 例でブートストラップ

コーパスをシード 実在する、有効な 例で入力:単一最も効果的なファジングを高速生産的にするする方法。

クラッシュを再現

# クラッシュfuzz/artifacts/<target>/ランド
cargo fuzz run parse_input fuzz/artifacts/parse_input/crash-abc123

# 最小ケースに縮小
cargo fuzz tmin parse_input fuzz/artifacts/parse_input/crash-abc123

最小化 入力をレギュラー#[test]にバグにとどまります。

Rustでファザー何

Good targetWhy
Parsers / deserializers信頼できない入力、複雑状態
unsafe blocksメモリー安全性 実際に危険
FFI boundariesC コード後面
Protocol/state machines順序バグ
Compression / encoding古典的なバグ テリトリー
Less usefulWhy
Pure safe arithmeticパニック通常明白
Thin wrappersロジック少ない探索

cargo-fuzz対他のファザー

Aspectcargo-fuzzAFL++ (afl.rs)LibAFLhonggfuzz-rs
EnginelibFuzzerAFL++カスタムhonggfuzz
SetupRust用最簡単中程度独自に構築簡単
Structured inputarbitraryarbitraryカスタム タイプarbitrary
Best for標準Rust ファジング永続/バイナリー モード異常なターゲットハードウェア フィードバック

Rust 以外ターゲット用AFL++またはhonggfuzzを参照;カスタム ファザー用LibAFL

リソース