ファズテスト (ファジング) チュートリアル

⚡ スマートサマリー

ファジングテストは、無効なデータ、予期しないデータ、またはランダムなデータをプログラムに入力し、クラッシュ、ハングアップ、メモリエラーなどを監視することで、スクリプト化された機能テストだけではほとんど検出できないセキュリティ上の欠陥を明らかにします。

  • 🔘 原産地: バートン・ミラーがウィスコンシン大学マディソン校でこの用語を作り出し、1989年に行われた最初のファズテストでは、テスト対象となったUNIXユーティリティの約3分の1がクラッシュした。
  • ☑️ 6段階のループ: ターゲットを特定し、入力を特定し、ファジングデータを生成し、実行し、動作を監視し、発生したすべての欠陥をログに記録する。
  • 3つの世代戦略: 変異型ファザーは有効なサンプルを改変し、生成型ファザーはモデルから入力を生成し、プロトコル型ファザーは仕様に基づいて動作する。
  • 🧪 報道に対するフィードバックが、この分野を変えた。 最新のエンジンは、新しいコードに到達する入力データをすべて保持するため、純粋なランダムデータよりもはるかに深刻なバグを発見できる。
  • 🛠️ ツールは進化しました。 Peach FuzzerとWebScarabはアーカイブ化されており、AFL++、libFuzzer、OSS-Fuzz、boofuzz、OWASP ZAPがメンテナンス対象となっている。
  • ⚙️ 既知の制限: ファジングは論理的な欠陥ではなく、クラッシュを発見するため、コードレビューや侵入テストを代替するのではなく、補完するものです。

ファズテスト (ファジング) チュートリアル

ファズテストとは何ですか?

ファジングテストまたはファジング ファズテストとは、ソフトウェアシステムにファズと呼ばれる無効なデータやランダムなデータを挿入することで、コーディングエラーやセキュリティ上の脆弱性を発見するソフトウェアテスト手法です。ファズテストの目的は、自動化または半自動化された手法を用いてデータを挿入し、システムクラッシュや組み込みコードの不具合など、さまざまな例外が発生するかどうかをテストすることです。

ファズテストは、もともとウィスコンシン大学マディソン校のバートン・ミラーによって開発されました。彼はモデムリンクの回線ノイズによって使用していたプログラムがクラッシュしたことをきっかけにこの用語を考案しました。彼の学生たちは1989年に最初のファザーを実行し、ターゲットとしたUNIXユーティリティの約3分の1がクラッシュまたはハングアップすることを発見しました。ファズテストは、 ソフトウェアテスト 技術であり、それは セキュリティテスト.

下の図は、ファジングの基本的なループを示しています。生成されたデータがテスト対象のアプリケーションに送信され、その応答が観測されます。

ファジングテストのワークフロー:ファザーが不正な入力を生成し、テスト対象のアプリケーションに供給する。

ファズテストを行う理由

ファジングがテスト計画において重要な位置を占めるのは、誰もテストケースを作成することを考えていなかったような入力を検証できるからです。チームがファジングを採用する主な理由は以下のとおりです。

  • ファジングテストは、通常、最も深刻なセキュリティ上の欠陥や不具合を発見します。なぜなら、クラッシュは未処理の入力パスが存在することの直接的な証拠となるからです。
  • ファジングテストは、 ブラック Box テスト、ベータ テスト、およびその他のデバッグ方法。
  • ファジングテストはソフトウェアの脆弱性をチェックするために使用され、入力が手書きではなく生成されるため、非常に費用対効果の高いテスト手法です。
  • ファジングテストは、ブラックボックステストの手法の一つです。ファジングは、ハッカーがシステムの脆弱性を発見するために用いる最も一般的な方法の一つでもあるため、最初にファジングを実行することで、攻撃者にとって最も容易な侵入経路を排除できます。

ファジングテストの種類

ファジングツールは通常、攻撃対象のプログラムに関する知識の深さによって分類されます。ファジングツールがプログラムについてより多くの知識を持っているほど、コードのより深い部分まで侵入することができます。

タイプ ファザーが知っていること 典型的な使用
ブラックボックスファジング 内部構造については何も見えません。入力と出力しか認識しません。 Quick Smokeは、バイナリエンドポイントまたはライブエンドポイントに対して実行されます。
ホワイトボックスファジング 完全なソースコード。多くの場合、到達困難な分岐を解決するために、シンボリック実行と組み合わせて使用​​される。 情報源が判明している部品の詳細な分析。
グレーボックスファジング ソースコードのレビューは行わないが、入力がどのコード分岐に到達したかといった実行時フィードバックを提供する。 AFL++やlibFuzzerのような最新のエンジンにおけるデフォルト設定。

2番目の、より古い分裂は 愚かなファジング from スマートファジング単純なファザーは入力フォーマットを全く考慮せずにビットを反転させるため、ほとんどのデータは最初に遭遇したパーサーによって拒否されます。一方、高度なファザーはチェックサム、長さフィールド、メッセージ構造を理解するため、入力データは検証を通過し、内部のロジックに到達します。 カバレッジ誘導型ファジング これは、ファジングを主流にしたグレーボックスの改良版です。エンジンはバイナリを計測し、新しい分岐に到達した入力をすべて保持し、生き残ったものを突然変異させるため、コーパスはランダムなノイズからやり直すのではなく、未探索のコードに向かって着実に進化します。

ファズテストのやり方

ファジングテストの手順には、基本的なテスト手順が含まれます。

ステップ 1) ターゲット システムを特定する 攻撃対象となるバイナリ、ライブラリ、サービス、またはプロトコルエンドポイントを選択し、テストを行う許可を得ていることを確認してください。

ステップ 2) 入力を特定する ターゲットが読み込むすべてのエントリポイント(ファイル、コマンドライン引数、環境変数、ネットワークパケット、フォームフィールド、APIペイロード)を一覧表示します。

ステップ 3) ファジーデータの生成 有効なサンプルを改変したり、フォーマットのモデルからサンプルを生成したり、あるいはその両方を組み合わせたりして、不正な形式の入力を生成する。

ステップ4)ファジーデータを使用してテストを実行する 生成された入力に対してターゲットを実行する。理想的には、失敗するたびにプロセスが自動的に再開されるループ内で実行する。

ステップ 5) システムの動作を監視する 印刷された出力だけを確認するのではなく、クラッシュ、ハング、アサーション失敗、メモリの暴走使用、サニタイザーレポートにも注意してください。

ステップ 6) 欠陥を記録する 各障害を引き起こした正確な入力を保存し、それを最小の再現ケースに縮小してスタックに保存する。 traceを添付します。

ファザーの例

ファザーは入力データの構築方法によっても分類され、以下に挙げる3つのアプローチが最もよく見られるものです。

  • 突然変異ベースのファザー 既存のデータサンプルを変更して、新しいテストデータを作成します。これは非常にシンプルで分かりやすい方法です。プロトコルの有効なサンプルから始めて、すべてのバイトまたはファイルを改変していきます。
  • 世代ベースのファザー モデルへの入力に基づいて新しいデータを定義します。仕様に基づいて、入力をゼロから生成し始めます。
  • プロトコルベースのファジングツール これは、テスト対象のプロトコル形式に関する詳細な知識に依存しており、その知識は仕様書から得られます。仕様書の配列をツールに書き込み、モデルベースのテスト生成手法を使用して仕様書を走査し、データの内容、順序などに不規則性を加える必要があります。これは、構文テスト、文法テスト、または堅牢性テストとも呼ばれます。ファザーは、既存のテストケースからテストケースを生成することも、有効な入力または無効な入力を使用することもできます。

プロトコルベースのファジングには XNUMX つの制限があります。

  1. 仕様が完成するまでテストを進めることはできません。
  2. 多くの便利なプロトコルは、公開されたプロトコルの拡張です。 ファズテストが公開された仕様に基づいている場合、 テストカバレッジ 新しいプロトコルの場合は制限されます。

ファジング手法の最もシンプルな形態は、プロトコルパケットまたはイベントとしてソフトウェアにランダムな入力を送信することです。このランダム入力を送信する手法は、多くのアプリケーションやサービスにおけるバグの発見に非常に有効です。他にも様々な手法があり、実装も非常に簡単です。これらの手法を実装するには、既存の入力を変更するだけでよく、入力はビットを入れ替えるだけで簡単に変更できます。

ファズテストで検出されるバグの種類

ファジングは、期待値ではなくプログラムの動作に基づいて実行結果を評価するため、ファジングによって明らかになる欠陥は3つのグループに分類されます。

  • アサーションの失敗とメモリリーク: この手法は、メモリの安全性に影響を与えるバグが存在する大規模アプリケーションで広く使用されており、これは深刻な脆弱性である。 Buffer オーバーフロー、解放済みメモリの使用、境界外読み取りはすべてここに現れます。
  • 無効な入力: ファジングテストでは、ファザーを使用して無効な入力を生成し、エラー処理ルーチンをテストします。これは、入力を制御しないソフトウェアにとって重要です。単純なファジングは、自動化する方法と見なすことができます。 ネガティブテスト.
  • 正確性に関するバグ: ファジングは、破損したデータベースや不適切な検索結果など、ある種の「正当性」に関するバグを検出するためにも使用できます。このようなバグを検出する一般的な方法は、2つの実装に同じ入力を与えて結果を比較する差分ファジングです。

ファズテストツール

ウェブセキュリティで使用されるツールは、ファジングテストにも幅広く使用できます。 Burp Suite そしてピーチファザー。下記の古典的な名前のいくつかは現在アーカイブされているため、各項目の横に現在の状況が記載されています。

  • ピーチファザーPeach Fuzzerは、スキャナーよりも堅牢なセキュリティカバレッジを提供します。他のテストツールは既知の脅威のみを検索できますが、Peach Fuzzerを使用すると、既知および未知の脅威を検出できます。Peach TechはGitLabに買収され、Community Edition v3はメンテナンスされなくなりました。メンテナンスされている後継バージョンは GitLab Protocol Fuzzer Community Edition.
  • スパイクプロキシ: Webアプリケーションのアプリケーションレベルの脆弱性を探すプロフェッショナルグレードのツール。SPIKE Proxyは、次のような基本事項を網羅しています。 SQL インジェクションとクロスサイトスクリプティングは、完全にオープンな Python インフラストラクチャがあり、利用可能でした Linux (NAIST) と Windowsこれは長年メンテナンスされておらず、歴史的な背景を示すためにここに掲載されています。
  • ウェブスカラベ: WebScarabは Java そのため、多くのプラットフォームで利用可能です。WebScarabフレームワークはHTTPおよびHTTPSプロトコルを使用して通信し、傍受プロキシとして機能します。これにより、オペレーターはブラウザが作成したリクエストをサーバーが受信する前に確認および変更したり、サーバーが生成したレスポンスをブラウザが受信する前に確認および更新したりできます。WebScarabが発見した脆弱性はすべて、報告された問題のリストに追加されます。リポジトリは2024年4月にアーカイブされ、現在は読み取り専用です。
  • OWASP WSFuzzerWSFuzzerはGPLライセンスのプログラムで、 Python ウェブサービスを対象とし、最終バージョンではHTTPベース SOAPサービス 主なターゲットは であった。WebScarab の一部として出荷され、WebScarab と共に廃止された。 OWASP ZAPとそのFuzzerアドオン 推奨される代替品です。
  • 維持された代替案: AFL++ (NAIST) と libFuzzer はネイティブコード用の標準的なカバレッジガイドエンジンです。 OSS-ファズ オープンソースプロジェクト向けには継続的に無料で実行し、 ブーファズ ネットワークプロトコルのファジングについて Pythonより詳しいリストは、ガイドに掲載されています。 セキュリティテストツール.

ファジングテストのベストプラクティス

ターゲットに向けられたまま放置されたファジングツールは、ほとんど何も発見しない。以下の手法は、実際に欠陥報告につながるキャンペーンと、単にCPU時間を浪費するだけのキャンペーンを区別するものである。

  • 良質なシードコーパスから始めましょう。 アプリケーションが既に受け入れている、実際の有効な入力データを収集します。実際のファイルを改変する方が、ランダムなバイトを改変するよりもはるかに速く解析コードに到達します。
  • 小型で高速なハーネスを作成する。 エントリポイントは、実行ごとに1つの処理のみを行い、ネットワーク呼び出しやディスク書き込みを避け、迅速に処理を終了させるべきである。なぜなら、スループットは1秒あたりの実行回数で測定されるからである。
  • 消毒剤を作動させてください。 サイレントメモリ破損は、多くの場合、クラッシュを引き起こしません。AddressSanitizerとUndefinedBehaviorSanitizerは、それを即座に診断可能な障害に変換します。
  • 長距離を走り、途切れることなく走り続ける。 1時間か2時間の実行で浅いバグは検出できますが、深いパスの検出には通常何時間もかかります。そのため、ファジングは手動で行うのではなく、毎晩のCIジョブに組み込むべきです。
  • すべてのクラッシュを最小化し、重複を削除します。 失敗した入力を最小形式に縮小し、スタックごとにクラッシュをグループ化する tracそうでなければ、1つのバグが数百件のチケットとして報告されることになる。
  • 回帰分析用のコーパスを保持してください。 再現する入力をそれぞれ、ビルドごとに実行される永続的なセットに追加することで、修正済みの不具合がひっそりと再発するのを防ぎます。
  • 法的に適切な範囲で対象を特定する。 書面による許可なく稼働中のサードパーティ製サービスに対してファジングを行うことは、攻撃と区別がつかない。

ファズテストの利点

現実的な期待値で使用すれば、ファジングは他の手法ではなかなか実現できない価値をもたらします。

  • ファジングテストはソフトウェアのセキュリティテストを向上させる。
  • ファジングで発見されるバグは、時に深刻なものであり、クラッシュ、メモリリーク、未処理の例外など、攻撃者が利用するバグと同じものであることが多い。
  • 時間とリソースの制約によりテスターが見落としたバグがあった場合、それらのバグもファジングテストで発見される。
  • 入力データは機械によって生成されるため、追加の手作業を必要とせずに、カバー範囲は毎晩拡大し続けます。

ファズテストの欠点

ファジングを安価にする特性は、同時にそれが証明できることを制限する要因にもなる。

  • ファジングテストだけでは、セキュリティ上の脅威やバグの全体像を完全に把握することはできません。
  • ファジングテストは、一部のウイルス、ワーム、トロイの木馬など、プログラムのクラッシュを引き起こさないセキュリティ上の脅威に対処する上では効果が低い。
  • ファジングテストは比較的単純な欠陥や脅威しか検出できず、ビジネスロジックに関する推論は行いません。
  • 効果的に実行するには、かなりの機械時間が必要となる。
  • ランダムな入力を用いて境界値条件を設定することは非常に困難ですが、現在ではテスターはユーザー入力に基づいて動作する決定論的なアルゴリズムを用いて、この問題の多くを解決しています。

ファジングテストとペネトレーションテストの比較

どちらの活動もセキュリティ上の欠陥を探すものですが、それぞれ異なる問いに答えるものであり、互換性はほとんどありません。

基準 ファジングテスト 侵入テスト
駆動される 不正な入力を生成する自動エンジン 熟練したテスターがシステムについて考察する
検索対象 クラッシュ、フリーズ、メモリ安全性の障害 悪用可能な脆弱性(論理的欠陥や設定上の欠陥を含む)
深さ 入力範囲は非常に広いが、推論は浅い。 狭い範囲をカバーし、深い論理を展開する
出力 入力とスタックを再現する traces 攻撃経路とリスク評価を含む調査結果レポート
最高の瞬間 ビルドパイプラインで継続的に 定期的に、リリース候補に対して

実際には、この2つは互いに良い影響を与え合う。ファジングによって、安価で自動化可能なクラッシュが排除されるため、テスターの限られた時間を、人間でなければ見つけられないような欠陥の発見に費やすことができる。

よくあるご質問

シードコーパスとは、ファザーが変異させる有効な入力データの初期セットのことです。小さくて多様な実在のファイルが最適です。なぜなら、それぞれのファイルが既にパーサーを通過しているため、エンジンは最初の妥当性チェックではなく、より深いコードにリソースを集中させることができるからです。

ファジングハーネスとは、テスト対象のコードにファジングされたバイト列のバッファを1つ渡す小さな関数です。グローバル状態、ファイルへの書き込み、ネットワーク呼び出しを避けることで、エンジンが毎秒数千回実行できるようにする必要があります。

1~2時間あれば、軽微なバグは明らかになる。本格的なキャンペーンは、新たな情報が断続的に入ってくるため、数時間から数日間続く。キャンペーンの成果が上がらなくなったことを示す正直な兆候は、時間ではなく、情報量の推移を示すグラフの横ばい状態である。

AddressSanitizerはバッファオーバーフローと解放後使用を検出し、UndefinedBehaviorSanitizerは整数とポインタの誤用を検出し、MemorySanitizerは初期化されていないメモリの読み取りを検出します。これらがないと、多くの不正行為が黙って見過ごされ、ファザーはエラーを全く報告しません。

再現し、入力を最小限の失敗ケースに絞り込み、同じスタックを共有するクラッシュとグループ化する trace、その後、通常の方法でチケットを1枚提出してください。 欠陥管理プロセス そして、その入力データを回帰分析用コーパスに追加する。

それらは偶然性という点では共通しているが、意図は異なる。 猿を使った実験 ファジングは実行中のインターフェースに任意のユーザー操作を投げかけるのに対し、特定の入力パーサーをターゲットにしてコードカバレッジを測定することで、以前の入力では到達しなかったコードへと自らを導くことができる。

言語モデルは、ファジングされていないAPI用のテストハーネスの作成、特殊なフォーマットのシード入力の合成、クラッシュレポートのクラスタリングと要約などに利用されています。エンジンは引き続きカバレッジに関するフィードバックを提供しますが、モデルは主に手動による設定作業を不要にします。

GitHubコパイロット 既存のAPIシグネチャから、libFuzzerのエントリポイント、ビルドファイル、シードジェネレーターを作成できます。 Revエラーを静かに隠蔽するハーネスはクラッシュを報告しないため、結果を注意深く確認してください。