上級
Mayhem で libFuzzer、AFL、honggfuzz OSS ファザーを使用する¶
このレッスンでは、最も広く利用されている 3 つのオープン ソース ソフトウェアのファジング フレームワークである libFuzzer、AFL および honggfuzz を Mayhem とともに使用する方法を順を追って学びます。
学習時間の目安: 15 分
このレッスンを終了すると、以下のことができるようになります。
- AFL、libFuzzer、および honggfuzz ファジング フレームワークについて説明する。
testme
ターゲットで各ファジング フレームワークを使用するためのMayhemfile
を構成する。- 各ファジング フレームワークを使用して
testme
ターゲットに対して Mayhem ランを実行する。
レッスンを駆け足で
始める前に前提条件を確認します。
-
mayhem package
コマンドを使用して、libFuzzer インストゥルメンテーション付きのtestme
バイナリをパッケージ化します。mayhem package ./testme -o /tmp/libfuzzer-pkg
-
mayhem run
コマンドに次の Mayhemfile を指定して、libFuzzer インストゥルメンテーション付きのtestme
バイナリに対して Mayhem ランを実行します。1 2 3 4 5 6 7 8 9
project: libfuzzer target: testme duration: 90 advanced_triage: false cmds: - cmd: /root/tutorial/oss-fuzzers/libfuzzer/testme libfuzzer: true sanitizer: true
-
mayhem package
コマンドを使用して、afl インストゥルメンテーション付きのtestme
バイナリをパッケージ化します。mayhem package ./testme -o /tmp/afl-pkg
-
mayhem run
コマンドに次の Mayhemfile を指定して、afl インストゥルメンテーション付きのtestme
バイナリに対して Mayhem ランを実行します。1 2 3 4 5 6 7 8
project: afl target: testme duration: 90 advanced_triage: false cmds: - cmd: /root/tutorial/oss-fuzzers/afl/testme @@ afl: true
-
mayhem package
コマンドを使用して、honggfuzz インストゥルメンテーション付きの (hfuzz-clang
を使用してコンパイルされた)testme
バイナリをパッケージ化します。mayhem package ./testme -o /tmp/hfuzz-libfuzzer-pkg
-
mayhem run
コマンドに次の Mayhemfile を指定して、honggfuzz インストゥルメンテーション付きの (hfuzz-clang
を使用してコンパイルされた)testme
バイナリに対して Mayhem ランを実行します。1 2 3 4 5 6 7 8 9
project: honggfuzz-libfuzzer target: testme duration: 90 advanced_triage: false cmds: - cmd: /root/tutorial/oss-fuzzers/honggfuzz-libfuzzer/testme honggfuzz: true sanitizer: true
-
mayhem package
コマンドを使用して、honggfuzz インストゥルメンテーション付きの (hfuzz-gcc
を使用してコンパイルされた)testme
バイナリをパッケージ化します。mayhem package ./testme -o /tmp/honggfuzz-pkg
-
mayhem run
コマンドに次の Mayhemfile を指定して、honggfuzz インストゥルメンテーション付きの (hfuzz-gcc
を使用してコンパイルされた)testme
バイナリに対して Mayhem ランを実行します。1 2 3 4 5 6 7 8
project: honggfuzz target: testme duration: 90 advanced_triage: false cmds: - cmd: /root/tutorial/oss-fuzzers/honggfuzz/testme honggfuzz: true
以下が必要です。
- Mayhem CLI がインストールされ、Mayhem サーバーで認証済みであること。
-
あらかじめビルドされた Docker イメージを実行し、チュートリアル サンプルにアクセスできること。
docker pull forallsecure/tutorial:2.10 docker run -ti --privileged --rm forallsecure/tutorial:2.10
LibFuzzer を使用したファジング¶
LibFuzzer は、LLVM プロジェクトによって開発されたインプロセスのファザーです。インプロセスのファザーは、呼び出しのたびに fork() を使用してプログラムを再実行するのではなく、同じインメモリ プロセス内で新しい入力を使用して反復的にターゲットを呼び出します。
このサンプルをビルドし、実行するには、oss-fuzzers/libfuzzer
ディレクトリに移動 (cd
) します。次に示す、新しいバージョンの testme.c
を使用します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
|
変更点は次のとおりです。
-
行 17: 以前の
testme.c
はabort()
関数を使用して不適切な入力検証の欠陥を作成していました。このabort()
関数が、無効なメモリアクセスに置き換えられました。 -
行 22-26: LibFuzzer では、テスト ドライバーを作成する必要があります。テスト ドライバーについては、後ほどより詳しく説明します。今のところは、 テスト対象の関数を指定し、
Data
およびSize
という 2 つの引数を渡す必要があるという点が重要です。2 つの引数には、ファザーによって値が入力されます。
Mayhem で LibFuzzer を使用するには、実行対象コマンド (cmd
) に libfuzzer: true
を指定する必要があります。さらに、sanitizer: true
を使用し、ターゲットがサニタイザーを使用してビルドされることを指定します。
Note
どのサニタイザーの場合でも (UndefinedBehaviorSanitizer、AddressSanitizer、MemorySanitizer など) sanitizer: true
を使用します。
Mayhemfile
全体は次のようになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
Mayhem を実行するには、次のコマンドを実行します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
Mayhem UI に移動すると、Mayhem がターゲットをファジングしているのがわかります。
AFL を使用したファジング¶
AFL は、よく知られたプロセスベースのファザーです。AFL を使用するには、AFL ツールチェーンを使用してアプリケーションを再ビルドする必要があります。ツールチェーンは AFL インストゥルメンテーションを実行ファイルにインライン化し、それがファザーのガイドとして使用されます。
このサンプルをビルドし、実行するには、oss-fuzzers/afl
ディレクトリに移動 (cd
) します。ディレクトリには以下のファイルがあります。
testme.c
- これまでのレッスンで使用したものと同じ、脆弱性のあるアプリケーションです。-
Makefile
- AFL インストゥルメンテーション付きでターゲットをビルドするための UNIX Makefile ファイルです。afl-gcc
コマンド - これまでのサンプルど同様にgcc
を使用します。ターゲットをビルドするには、make clean && make
を実行します。 -
Mayhemfile
- 内容は下記のとおりです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
|
Mayhemfile
に afl: true
が追加されていることに注目してください。これは、ターゲットが AFL を使用してコンパイルされていることを Mayhem に通知します。
Mayhem を実行するには、次のコマンドを実行します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
Mayhem UI に移動すると、Mayhem がターゲットをファジングしているのがわかります。
honggfuzz を使用したファジング¶
Honggfuzz は、いくつかの解析オプションを備え、先進的で使いやすいセキュリティ志向のフィードバック駆動型ファザーです。Honggfuzz は、clang および GCC に対応するコンパイラ ラッパーである hfuzz-clang
および hfuzz-gcc
を提供します。これらのラッパーを使用すると、さまざまなコンパイル時カバレッジ インストゥルメンテーションの形式でコンパイルできます。
hfuzz-clang
または hfuzz-gcc
のどちらも同じように使用できます。
Info
Honggfuzz にはいくつかのモードがありますが、このレッスンではLLVMFuzzerTestOneInput
または HF_ITER
スタイルのテスト ドライバーを使用して honggfuzz persistent モードのバイナリをコンパイルする方法を説明します。詳細については honggfuzz の persistent mode を参照してください。
hfuzz-clang
を使用した Honggfuzz (推奨)¶
Mayhem は、hfuzz-clang
を使用してコンパイルされた honggfuzz persistent モード バイナリのファジングをサポートします。このセクションでは、libFuzzer スタイルのテスト ドライバー (LLVMFuzzerTestOneInput
など) を使用してコンパイルする方法を説明します。
このサンプルをビルドし、実行するには、oss-fuzzers/honggfuzz-libfuzzer
ディレクトリに移動 (cd
) します。以下のファイルがあります。
testme.c
- 上記の libFuzzer サンプルで使用したものと同じ、脆弱性のあるアプリケーションです。Makefile
- ターゲットをビルドするための UNIX Makefile ファイルです。Makefile
はhfuzz-clang
を使用します。Mayhemfile
- 内容は下記のとおりです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
|
Note
honggfuzz: true
および sanitizer: true
を指定する必要があります。honggfuzz: true
は、honggfuzz ファザーの使用を指示します。sanitizer: true
は、ターゲット バイナリがサニタイザー付きでコンパイルされていることを Mayhem に通知します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
Mayhem UI に移動すると、Mayhem がターゲットをファジングしているのがわかります。
Warning
サニタイザー付きのターゲットで sanitizer: true
が指定されていない場合、Mayhem は発見されたバグを適切にレポートしません。
hfuzz-gcc
を使用した Honggfuzz¶
Mayhem は、hfuzz-gcc
を使用してコンパイルされた honggfuzz persistent モード バイナリのファジングもサポートします。このセクションでは、HF_ITER
スタイルのテスト ドライバーを使用してバイナリをコンパイルする方法を説明します。
Info
Mayhem は Honggfuzz インストゥルメンテーション付きでコンパイルされた non-persistent モードのバイナリの実行もサポートしています。ただし、non-persistent モードのバイナリは非インストゥルメンテーションバイナリと同様に扱われるため、推奨されていません。
基本的なサンプルを見てみましょう。oss-fuzzers/honggfuzz
ディレクトリに移動 (cd
) します。次のファイルがあります。
testme.c
- 前のレッスンで使用したtestme
アプリケーションの修正版です。Makefile
- ターゲットをビルドするための UNIX Makefile ファイルです。Makefile
はhfuzz-gcc
を使用します。これによって特殊な honggfuzz インストゥルメンテーションが追加されます。Mayhemfile
- Mayhem ランの構成ファイルです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
|
修正された testme.c
は HF_ITER
関数を使用していることに注目してください。これは、persistent モードのバイナリであることを示しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
persistent モードの testme
バイナリでは、cmd
パラメーターから @@
を削除する必要があります。
Mayhem を実行するには、次のコマンドを実行します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
Mayhem UI に移動すると、Mayhem がターゲットをファジングしているのがわかります。
✏️ まとめと振り返り¶
このレッスンでは、 AFL、libFuzzer および honggfuzz ファジング フレームワークを使用してターゲットをファジングする方法を学びました。
学習内容
1.AFL、libFuzzer および honggfuzz ファジング フレームワークについて説明します。
- AFL は、よく知られたプロセスベースのファザーです。AFL を使用するには、AFL ツールチェーンを使用してアプリケーションを再ビルドする必要があります。ツールチェーンは AFL インストゥルメンテーションを実行ファイルにインライン化し、それがファザーのガイドとして使用されます。
- LibFuzzer は、LLVM プロジェクトによって開発されたインプロセスのファザーです。インプロセスのファザーは、呼び出しのたびに fork() を使用してプログラムを再実行するのではなく、同じインメモリ プロセス内で新しい入力を使用して反復的にターゲットを呼び出します。
- Honggfuzz は、魅力的な解析オプションを備え、先進的で使いやすいセキュリティ志向のフィードバック駆動型ファザーです。Honggfuzz は、Honggfuzz 独自の
hfuzz-gcc
や libFuzzer など、異なるインストゥルメンテーション タイプでコンパイルする機能を備えています。
2. testme ターゲットに対してそれぞれのファジング フレームワークを使用するよう Mayhemfile を構成します。
-
AFL Mayhemfile:
1 2 3 4 5 6 7
project: afl target: testme duration: 90 advanced_triage: false cmds: - cmd: /root/tutorial/oss-fuzzers/afl/testme @@ afl: true
-
LibFuzzer Mayhemfile:
1 2 3 4 5 6 7 8 9
project: libfuzzer target: testme duration: 90 advanced_triage: false cmds: - cmd: /root/tutorial/oss-fuzzers/libfuzzer/testme libfuzzer: true # this is a libfuzzer target sanitizer: true # A sanitizer was used (the average case)
-
Honggfuzz Mayhemfile:
1 2 3 4 5 6 7 8 9
project: honggfuzz-libfuzzer target: testme duration: 90 advanced_triage: false cmds: - cmd: /root/tutorial/oss-fuzzers/honggfuzz-libfuzzer/testme honggfuzz: true sanitizer: true
3.testme ターゲットに対してそれぞれのファジング フレームワークを使用して Mayhem ランを実行します。
- AFL、libFuzzer および honggfuzz のそれぞれに対して
mayhem run
コマンドを実行します。