上級
ベース実行ファイル C/C++ ターゲット¶
テスト対象はインストゥルメンテーションされていない、またはベース実行ファイルの C/C++ ターゲットでしょうか? このレッスンでは、Mayhem でベース実行ファイル C/C++ ターゲットをテストする方法を手順を追って説明します。
学習時間の目安: 15 分
このレッスンを終了すると、以下のことができるようになります。
- 不適切な入力検証の欠陥があるベース実行ファイル C ターゲットをコンパイルし、ファジングする。
- 不適切な入力検証の欠陥があるベース実行ファイル C++ ターゲットをコンパイルし、ファジングする。
レッスンを駆け足で
始める前に前提条件を確認します。
-
c-base-executable.tgz をダウンロードし、c-base-executable` Docker イメージをビルドし、指定された Docker レジストリにプッシュします。
docker build -t <DOCKERHUB_USERNAME>/c-base-executable . docker push <DOCKERHUB_USERNAME>/c-base-executable
docker build -t $MAYHEM_DOCKER_REGISTRY/forallsecure/c-base-executable . docker push $MAYHEM_DOCKER_REGISTRY/forallsecure/c-base-executable
-
Mayhem UI または Mayhem CLI で次の Mayhemfile を使用して
c-base-executable
Docker イメージに対して Mayhem ランを実行します。1 2 3 4 5 6
image: <DOCKERHUB_USERNAME>/c-base-executable:latest duration: 90 project: mayhem-examples target: c-base-executable cmds: - cmd: /mayhemit @@
1 2 3 4 5 6
image: $MAYHEM_DOCKER_REGISTRY/forallsecure/c-base-executable:latest duration: 90 project: mayhem-examples target: c-base-executable cmds: - cmd: /mayhemit @@
以下が必要です。
- Docker がインストールされていること *有効なインターネット接続 (Docker Hub ベース イメージをプルするため)
ワン クリック テスト¶
次のボタンをクリックし、Create New Run フローの最後で Start Run をクリックしてベース実行ファイル C ターゲットのテストを開始します。Mayhemfile
はすでに用意されているため、何も設定する必要はありません。
Mayhem ランが始まると、次のようなラン ページが表示されます。
すばらしい! Mayhem によるベース実行ファイル C ターゲットのテストを確認したので、次に、たった今実行した Mayhem ランの c-base-executable
ターゲットをコンパイルし、テストする方法を順を追って説明します。
ベース実行ファイル C ターゲットのコンパイルとテスト¶
ファイル: c-base-executable.tgz
上記の c-base-executable.tgz
をダウンロードして展開し、次のバグのある mayhemit.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 27 28 29 30 31 32 33 34 35 36 |
|
プログラムの行 1-2 でヘッダー ファイル stdio.h
および string.h
がインクルードされ、次の 2 つの注目するべき関数があるのがわかります: main
および mayhemit
Info
C++ プログラムは iostream
ヘッダー ファイルを使用しますが、C プログラムは stdio.h
ヘッダー ファイルを使用します。他の C++ プログラムを参照すると、通常、ソース コードは iostream
ヘッダー ファイルを使用しています。
main
関数はファイル入力を処理し、プログラムに適切にファイルが指定されている場合、mayhemit
関数を呼び出します。その後、mayhemit
関数は入力ファイルを解析し、プログラムに入力されたテスト ケースが "bug" である場合、不適切な入力検証エラーを返します。そのため、このターゲットで不適切な入力検証の欠陥を明らかにするには、Mayhem はプログラムをファジングしてクラッシュを起こすテスト ケース "bug" を入力できなければなりません。
しかしその前に、プログラムをファジングするには、プログラムをコンパイルし、ターゲットを Mayhem にアップロードして取り込めるようにする必要があります。この最初のステップとして、ターゲット アプリケーションとプログラム依存性を組み合わせた Docker コンテナーを使用し、Mayhem が正常に C ターゲットを実行してファジングできるようにすることを推奨します。
関連する Dockerfile
を見てみると、次の操作があります。
1 2 3 4 5 6 7 8 9 10 |
|
- 行 1: 新規 Docker コンテナーのベース イメージとして
debian:buster-slim
イメージがインポートされています。 - 行 2-4: 必要な依存関係がダウンロードされ、新規 Docker コンテナーにインストールされています。
- 行 5: Docker コンテナーに
mayhemit.c
ソース コードがコピーされています。 - 行 6:
gcc
C コンパイラを使用してmayhemit.c
ソース コードがmayhemit
実行ファイルにコンパイルされています。 - 行 10: Docker コンテナーのデフォルト実行ファイルとして
/mayhemit @@
コマンドが設定されています。
次に、docker build
および docker push
コマンドを使用して、実際に Docker イメージをビルドして Docker Hub レジストリにプッシュする必要があります。
次に、docker build
および docker push
コマンドを使用して、実際に Docker イメージをビルドして Mayhem サーバーにプッシュする必要があります。$MAYHEM_DOCKER_REGISTRY
は、プライベートな Mayhem Docker レジストリの URL の環境変数を表します。
情報
たとえば、次のコマンドを実行して、$DOCKER_REGISTRY
環境変数に tutorial.forallsecure.com:5000
を設定できます。
export DOCKER_REGISTRY=tutorial.forallsecure.com:5000
c-base-executable
ディレクトリで次のコマンドを実行します。
docker build -t <DOCKERHUB_USERNAME>/c-base-executable .
docker push <DOCKERHUB_USERNAME>/c-base-executable
docker build -t $MAYHEM_DOCKER_REGISTRY/forallsecure/c-base-executable .
docker push $MAYHEM_DOCKER_REGISTRY/forallsecure/c-base-executable
新しく作成した Docker イメージをパブリックな Docker Hub レジストリに正常にプッシュしたら、Mayhem UI から新規ランを作成し、アップロードされた <DOCKERHUB_USERNAME>/c-base-executable
Docker イメージを選択します。新規ランの作成フローで [Next] をクリックし、Mayhem ファイルが次のようになっていることを確認してからランを開始します。
新しく作成した Docker イメージをプライベートな Mayhem Docker レジストリに正常にプッシュしたら、Mayhem UI から新規ランを作成し、アップロードされた forallsecure/c-base-executable
Docker イメージを選択します。新規ランの作成フローで [Next] をクリックし、Mayhem ファイルが次のようになっていることを確認してからランを開始します。
1 2 3 4 5 6 |
|
1 2 3 4 5 6 |
|
Mayhem が不適切な入力検証の欠陥を発見できたことがわかるはずです。C ターゲットのコンパイルとテストが成功しました。
⚡ 現実的な演習: ベース実行ファイル C++ ターゲットのコンパイルとテスト¶
ベース実行ファイル C ターゲットのコンパイルおよびテスト手順がわかったので、次に、同じことをベース実行ファイル C++ ターゲットに対して行うことができるか、やってみましょう。
ファイル: cpp-base-executable.tgz
手順
- 上記の
cpp-base-executable.tgz
ファイルをダウンロードして展開し、Mayhem が<DOCKERHUB_USERNAME>/cpp-base-executable
ターゲットをファジングできるよう、docker build
およびdocker push
コマンドを使用して Docker イメージをビルドしてプッシュします。 - Mayhem UI から、新しくアップロードした
<DOCKERHUB_USERNAME>/cpp-base-executable
Docker イメージをファジングします。
- 上記の
cpp-base-executable.tgz
ファイルをダウンロードして展開し、Mayhem がforallsecure/cpp-base-executable
ターゲットをファジングできるよう、docker build
およびdocker push
コマンドを使用して Docker イメージをビルドしてプッシュします。 - Mayhem UI から、新しくアップロードした
forallsecure/cpp-base-executable
Docker イメージをテストします。
🔍 確認ベース実行ファイル C++ ターゲットのコンパイルとテスト¶
解答
結果を確認しましょう。まず、mayhemit.cpp
プログラムのソース コードを見てみましょう。
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 27 28 29 30 31 32 33 34 35 36 |
|
C の stdio.h
ヘッダーファイルが C++ の
iostream
ヘッダーに置き換えられている以外は、cpp-base-executable
ソース コードは、ほとんど c-base-executable
ソース コードと同じであることがわかります。
次に、対応する Dockerfile を確認します。次の操作があるのがわかります。
1 2 3 4 5 6 7 8 9 10 |
|
- 行 1: 新しい Docker コンテナーのベース イメージとして、
debian:buster-slim
イメージがインポートされています。 - 行 2-4: 必要な依存関係がダウンロードされ、新しい Docker イメージ内にインストールされています。
- 行 5:
mayhemit.cpp
ソース コードが Docker コンテナーにコピーされています。 - 行 6:
g++
C++ コンパイラを使用してmayhemit.cpp
ソース コードがmayhemit
実行ファイルにコンパイルされています。 - 行 10: 結果の Docker コンテナーのデフォルト実行ファイルとして
/mayhemit @@
コマンドが設定されています。
これで、ほとんど終わりです。次は、前にも行ったように、Docker イメージをビルドしてプッシュしてから、コンテナー化された cpp-base-executable
ターゲットを Mayhem で実行します。
docker build -t <DOCKERHUB_USERNAME>/cpp-base-executable .
docker push <DOCKERHUB_USERNAME>/cpp-base-executable
docker build -t $MAYHEM_DOCKER_REGISTRY/forallsecure/cpp-base-executable .
docker push $MAYHEM_DOCKER_REGISTRY/forallsecure/cpp-base-executable
ランの Mayhemfile
は次のようになっているはずです。
1 2 3 4 5 6 |
|
1 2 3 4 5 6 |
|
最後に、次のようなラン ページが表示されるはずです。
cpp-base-executable
ターゲットをテストできた場合、よくできました! 自力で C++ ターゲットをビルドしてテストできました。
✏️ まとめと振り返り¶
このレッスンでは、Mayhem でベース実行ファイル C/C++ ターゲットをコンパイルし、テストする方法を学びました。
学習内容
1. 不適切な入力検証の欠陥があるベース実行ファイル C ターゲットをコンパイルし、テストする。
-
ソース コードには次の欠陥が含まれているはずです:
1 2 3 4 5 6 7 8 9 10 11
int mayhemit(char *buf) { if(strlen(buf) >= 3) if(buf[0] == 'b') if(buf[1] == 'u') if(buf[2] == 'g') { printf("You've got it!"); abort(); // Defect: SIGABRT. } return 0; }
-
C のベース実行ファイル ターゲットをファジングするには、次の
Dockerfile
およびMayhemfile
を使用して C プログラムを含む Docker イメージをビルドし、Mayhem でファジングを実行します。1 2 3 4 5 6 7 8 9 10
FROM debian:buster-slim as builder RUN apt-get update && \ apt-get install -y gcc make libc6-dbg && \ rm -rf /var/lib/apt/lists/* COPY mayhemit.c . RUN gcc -o mayhemit -Wno-div-by-zero -fno-stack-protector -zexecstack -no-pie mayhemit.c # Set to fuzz! ENTRYPOINT [] CMD /mayhemit @@
1 2 3 4 5 6
image: <DOCKERHUB_USERNAME>/c-base-executable:latest duration: 90 project: mayhem-examples target: c-base-executable cmds: - cmd: /mayhemit @@
1 2 3 4 5 6
image: $MAYHEM_DOCKER_REGISTRY/forallsecure/c-base-executable:latest duration: 90 project: mayhem-examples target: c-base-executable cmds: - cmd: /mayhemit @@
2. 不適切な入力検証の欠陥があるベース実行ファイル C++ ターゲットをコンパイルし、ファジングする。
-
ソース コードには次の欠陥が含まれているはずです:
1 2 3 4 5 6 7 8 9 10 11
int mayhemit(char *buf) { if(strlen(buf) >= 3) if(buf[0] == 'b') if(buf[1] == 'u') if(buf[2] == 'g') { printf("You've got it!"); abort(); // Defect: SIGABRT. } return 0; }
-
C++ のベース実行ファイル ターゲットをファジングするには、次の
Dockerfile
およびMayhemfile
を使用して C++ プログラムを含む Docker イメージをビルドし、Mayhem でファジングを実行します。1 2 3 4 5 6 7 8 9 10
FROM debian:buster-slim as builder RUN apt-get update && \ apt-get install -y gcc g++ make libc6-dbg && \ rm -rf /var/lib/apt/lists/* COPY mayhemit.cpp . RUN g++ -Wno-div-by-zero -fno-stack-protector -zexecstack -no-pie -o mayhemit mayhemit.cpp # Set to fuzz! ENTRYPOINT [] CMD /mayhemit @@
1 2 3 4 5 6
image: <DOCKERHUB_USERNAME>/cpp-base-executable:latest duration: 90 project: mayhem-examples target: cpp-base-executable cmds: - cmd: /mayhemit @@
1 2 3 4 5 6
image: $MAYHEM_DOCKER_REGISTRY/forallsecure/cpp-base-executable:latest duration: 90 project: mayhem-examples target: cpp-base-executable cmds: - cmd: /mayhemit @@