ビギナー
Mayhem での Docker ターゲットのテスト¶
テスト対象は、Docker イメージとしてパッケージ化されたコンテナー アプリケーションですか? このレッスンでは、Docker イメージをコンパイルおよびアップロードし、Mayhem を使用して内部のコンテナー化されたアプリケーションをテストする手順を説明します。
学習時間の目安: 30 分
このレッスンを終了すると、以下のことができるようになります。
- 独自のローカル Docker イメージをビルドする。
- ローカルな Docker イメージを Docker Hub レジストリにプッシュする。
- アップロードされた Docker イメージに対して Mayhem UI から Mayhem ランを実行する。
- アップロードされた Docker イメージに対して Mayhem CLI から Mayhem ランを実行する。
- 独自のローカル Docker イメージをビルドする。
- ローカルな Docker イメージを Mayhem Docker レジストリにプッシュする。
- アップロードされた Docker イメージに対して Mayhem UI から Mayhem ランを実行する。
- アップロードされた Docker イメージに対して Mayhem CLI から Mayhem ランを実行する。
レッスンを駆け足で
始める前に前提条件を確認してください。
-
Mayhem で Docker ターゲットをテストするには、次のステップを認識する必要があります。
- docker build コマンドを使用してローカルな Docker イメージをビルドします。
- Docker イメージをパブリックな Docker Hub レジストリにアップロードします (Docker Hub アカウントが必要です)。
- Mayhem UI または Mayhem CLI を使用して Mayhem ランを実行します。Mayhem API によって、Mayhem ランに必要な指定された Docker イメージが Docker Hub レジストリからプルされます。
- ランが実行され、結果が利用可能になります。
- docker build コマンドを使用してローカルな Docker イメージをビルドします。
- Docker イメージをパブリックな Docker Hub レジストリまたはプライベートな Mayhem Docker レジストリ (mayhem login を使用した認証が必要です) にアップロードします。
- Mayhem UI または Mayhem CLI を使用して Mayhem ランを実行します。Mayhem API によって、Mayhem ランに必要な指定された Docker イメージが指定されたレジストリからプルされます。
- ランが実行され、結果が利用可能になります。
-
Download testme-docker をダウンロードしてファイルを展開し、
docker build
コマンドおよび次のDockerfile
を使用してtestme-docker
イメージをビルドしてタグを付けます。1 2 3 4 5 6 7
FROM debian:buster-slim as builder RUN apt-get update && \ apt-get install -y gcc make libc6-dbg && \ rm -rf /var/lib/apt/lists/* WORKDIR /mayhem COPY src testme RUN cd testme && make
-
docker tag
およびdocker push
コマンドを使用して、testme-docker
イメージのタグを変更して Mayhem Docker レジストリにプッシュします。docker tag testme-docker <DOCKERHUB_USERNAME>/testme-docker docker push <DOCKERHUB_USERNAME>/forallsecure/testme-docker
docker tag testme-docker $MAYHEM_DOCKER_REGISTRY/forallsecure/testme-docker docker push $MAYHEM_DOCKER_REGISTRY/forallsecure/testme-docker
-
Mayhem UI or Mayhem CLI で次の Mayhemfile を指定して、
testme-docker
イメージに対して Mayhem ランを実行します。1 2 3 4 5 6
image: $MAYHEM_DOCKER_REGISTRY/forallsecure/testme-docker:latest duration: 90 project: forallsecure-testme-docker target: testme cmds: - cmd: /mayhem/testme/v1/testme @@
1 2 3 4 5 6
image: $MAYHEM_DOCKER_REGISTRY/forallsecure/testme-docker:latest duration: 90 project: forallsecure-testme-docker target: testme cmds: - cmd: /mayhem/testme/v1/testme @@
ターミナル記録¶
Mayhem Docker ターゲットのワークフロー¶
次の図を見て、Mayhem で Docker ターゲットをテストするために必要な手順を最初から最後まで感覚的につかみましょう。
特に、次のステップに注意する必要があります。
docker build
コマンドを使用してローカルな Docker イメージをビルドします。- Docker イメージをパブリックな Docker Hub にアップロードします。
- Mayhem UI または Mayhem CLI を使用して Mayhem ランを実行します。Mayhem API によって、Mayhem ランに必要な指定された Docker イメージが Docker Hub レジストリからプルされます。
- ランが実行され、結果が利用可能になります。
docker build
コマンドを使用してローカルな Docker イメージをビルドします。- Docker イメージをパブリックな Docker Hub レジストリまたはプライベートな Mayhem Docker レジストリ (
mayhem login
を使用した認証が必要です) にアップロードします。 - Mayhem UI または Mayhem CLI を使用して Mayhem ランを実行します。Mayhem API によって、Mayhem ランに必要な指定された Docker イメージが指定されたレジストリからプルされます。
- ランが実行され、結果が利用可能になります。
最初のステップであるローカルな Docker イメージの構築から始めましょう。
Docker イメージをビルドしてプッシュする¶
Docker を使用すると、ターゲット バイナリを含む独自のイメージを簡単にビルドできます。それには、Dockerfile
を指定して docker build
コマンドを実行するだけです。
始めるための準備として、次のファイルをダウンロードして展開します: testme-docker
展開されたファイルは次のようになります。
├── testme-docker
└── Dockerfile: 実行される Docker build コマンドを定義する
└── Makefile: 実行されるビルド タスクを定義する
└── src: testme アプリケーションのソース ファイルを含むフォルダー
Dockerfile
は、基になる Docker コンテナーから Docker イメージを作成するための命令をテキストベースで記述したスクリプトです。Dockerfile
では、ユーザーのニーズに合わせて Docker を作成および修正するためのオプションを使用できます。準備ができたら、Dockerfile
を指定して docker build
コマンドを実行し、Dockerfile の命令に従って Docker コンテナー イメージをビルドしてタグを付加します。
testme-docker
ディレクトリに移動して Dockerfile
を開きます。
1 2 3 4 5 6 7 |
|
Dockerfile
で次のコマンドが使用されているのがわかります。
- FROM: 新規ビルド ステージを初期化し、その後の命令で使用するベース イメージを設定します。有効な Dockerfile は必ず
FROM
命令で始まります。 - RUN: 現在のイメージに重ねられた新しいレイヤーでコマンドを実行し、結果をコミットします。結果としてコミットされたイメージが Dockerfile の次のステップで使用されます。
- WORKDIR:
Dockerfile
内で後に続くRUN
、CMD
、ENTRYPOINT
、COPY
、ADD
命令の作業ディレクトリを設定します。 - COPY: 新規ファイルまたはディレクトリを
からコピーし、コンテナーのファイルシステムのパス に追加します。
次のコマンドを実行すると、Dockerfile
を使用して Docker イメージをビルドします。
docker build -f Dockerfile -t testme-docker .
docker build
は、Dockerfile
から Docker イメージをビルドするのに使用されます。-f
パラメーターは、Dockerfile
の名前を指定します (デフォルト値はPATH/Dockerfile
)。-t
パラメーターは、ビルドされた Docker イメージに人間が読みやすい名前をタグ付けします。.
は、ビルドおよび (tar
によって) パッケージ化されて Docker デーモンに送られるローカル ディレクトリのすべてのファイルの「コンテキスト」へのPATH
を指定します。
Info
Dockerfile
の設定と Docker イメージのビルドの詳細については「Dockerfile Reference」および「docker build examples」を参照してください。
今回使用する testme-docker
サンプルでは、Dockerfile
は debian:buster-slim
ベース イメージを設定し、apt-get
コマンドを使用して gcc
や make
などの必要なビルド ツールをダウンロードします。その後、作業ディレクトリとして /mayhem
を設定し、src
ローカル フォルダーの内容を testme
フォルダーにコピーし、testme
フォルダーに移動してフォルダー内の Makefile
に対して make
コマンドを実行します。Docker コンテナーがビルドされ、Docker イメージに testme-docker
という名前がタグ付けされます。
docker build
が成功すると、次のように出力されます。
testme-docker
イメージが正常にビルドされたことを確認するには、docker images
コマンドを実行して出力を grep testme-docker
にパイプし、testme-docker
に一致するものを検索して出力します。
$ docker images | grep testme-docker
testme-docker latest 118f9b5b7874 5 minutes ago 201MB
おめでとうございます! 初めてのローカル Docker イメージを一から作成できました。
無事に Docker イメージをビルドできたので、今度は Docker Hub にイメージをアップロードして、Mayhem がイメージを取り込んでコンテナー化された testme
アプリケーションをファジングできるようにします。
無事に Docker イメージをビルドできたので、今度は Mayhem にイメージをアップロードして、Mayhem がイメージを取り込んでコンテナー化された testme
アプリケーションをファジングできるようにします。それには、ローカルにある Docker イメージをプライベートな Docker レジストリにプッシュします。すべての Mayhem デプロイメントはプライベートな Docker レジストリを備えています。
ただし、その前に Mayhem CLI から mayhem login
コマンドを実行する必要があります。このコマンドは次の 2 つの処理を行います。
- Mayhem サーバーでユーザー認証情報を認証します。
- Mayhem Docker レジストリにログインします。
$ mayhem login <MAYHEM_HOST_URL> <USER_API_KEY>
Logged in successfully at '<MAYHEM_HOST_URL>:443' as '<USER>'.
Syncing default settings: /Users/andrew/.config/mayhem/mayhem.
Logging into the Docker registry at <MAYHEM_HOST_URL>:5000
Successfully logged in to the remote Docker registry.
そのため、mayhem login
コマンドを使用して Mayhem サーバーにログインします。Mayhem Docker レジストリへのログインが成功したら、docker tag
および docker push
コマンドを続けて実行し、Mayhem Docker レジストリ向けにローカルな Docker イメージのタグを付けなおし、結果のイメージをレジストリにアップロードできます。
Docker イメージをパブリックな Docker Hub レジストリにアップロードするための docker tag
および docker push
コマンドの形式は次のとおりです。
Docker イメージをプライベートな Docker レジストリにアップロードするための docker tag
および docker push
コマンドの形式は次のとおりです。
docker tag <DOCKER_IMAGE> <DOCKERHUB_USERNAME>/<DOCKER_IMAGE>
docker push <DOCKERHUB_USERNAME>/<DOCKER_IMAGE>
docker tag <DOCKER_IMAGE> <REGISTRY_HOST>/<DOCKER_REPO>/<DOCKER_IMAGE>
docker push <REGISTRY_HOST>/<DOCKER_REPO>/<DOCKER_IMAGE>
警告
このサンプルでは、Mayhem デプロイメントは tutorial.forallsecure.com
にあり、Mayhem Docker レジストリはポート 5000
にあります。ただし、お使いの Mayhem デプロイメントおよびプライベートな Docker レジストリの場所は異なる可能性があります。
Docker イメージを正常にプッシュするには、mayhem login
または mayhem docker-registry
コマンドを使用して Mayhem サーバーにログインし、
プライベートな Docker レジストリの場所を確認してください。
したがって、次のコマンドを実行すると、ローカルな testme-docker
イメージのタグが付けかえられ、新しくタグ付けされた testme-docker
イメージがパブリックな Docker Hub レジストリにプッシュされます。
したがって、次のコマンドを実行すると、ローカルな testme-docker
イメージのタグが付けかえられ、新しくタグ付けされた forallsecure/testme-docker
イメージが tutorial.forallsecure.com:5000
にあるプライベートな Mayhem Docker レジストリにプッシュされます。
重要
次のサンプルでは、andrew5194
Docker Hub リポジトリが使用されています。ユーザーはそれぞれの Docker Hub アカウント/リポジトリ名を使用してローカルな testme-docker
イメージにタグを付ける必要があります。
docker tag testme-docker docker.io/<DOCKERHUB_USERNAME>/testme-docker
docker push docker.io/<DOCKERHUB_USERNAME>/testme-docker
docker tag testme-docker tutorial.forallsecure.com:5000/forallsecure/testme-docker
docker push tutorial.forallsecure.com:5000/forallsecure/testme-docker
ローカルな Docker イメージが Docker Hub レジストリに正常にアップロードされたことを確認するには、Docker Hub に移動して <DOCKERHUB_USERNAME>/testme-docker
イメージを検索します。
ローカルな Docker イメージがプライベートな Mayhem Docker レジストリに正常にアップロードされたことを確認するには、Mayhem UI の Mayhem Docker レジストリ ページに移動して forallsecure/testme-docker
イメージを検索します。
注意
Mayhem Docker レジストリページの右上隅にある情報アイコン を使用してプライベートな Docker レジストリの場所を確認し、表示される
docker tag
および docker push
コマンドをブックマークすることもできます。
Mayhem UI から Docker イメージをテストする¶
Docker イメージをパブリックな Docker Hub レジストリにアップロードしたので、あとは 、前のレッスンで実行したように、Mayhem UI から新規 Mayhem ランの作成を実行するだけです。
Docker イメージを Mayhem Docker レジストリにアップロードしたので、あとは 、前のレッスンで実行したように、Mayhem UI から新規 Mayhem ランの作成を実行するだけです。
ソースとして Docker Hub レジストリを選択し、先ほどアップロードした <DOCKERHUB_USERNAME>/testme-docker
イメージを検索します。新規 Mayhem ランを開始し、関連する Mayhemfile
をプレビューして、内容が次のようになっていることを確認します。
ソースとして Mayhem Docker レジストリを選択し、先ほどアップロードした forallsecure/testme-docker
イメージを検索します。新規 Mayhem ランを開始し、関連する Mayhemfile
をプレビューして、内容が次のようになっていることを確認します。
1 2 3 4 5 6 |
|
1 2 3 4 5 6 |
|
最後に、オプションの選択を確認し、新規ランの作成フローの最後で [Start Run] ボタンをクリックしてローカルな Docker イメージに対する Mayhem ランを実行します。
よくできました! ローカルな Docker イメージを一からビルドし、パブリックな Docker Hub レジストリにアップロードし、コンテナー化されたターゲットをファジングして不適切な入力検証の欠陥を検出できました。
よくできました! ローカルな Docker イメージを一からビルドし、Mayhem Docker レジストリにアップロードし、コンテナー化されたターゲットをファジングして不適切な入力検証の欠陥を検出できました。
Mayhem CLI から Docker イメージをテストする¶
UI ではなく Mayhem CLI を使用したい場合、Mayhemfile
を作成し、次のように Docker Hub レジストリにある <DOCKERHUB_USERNAME>/testme-docker
イメージを指すよう image
を変更することもできます。
1 2 3 4 5 6 |
|
情報
mayhem login
コマンドを使用してユーザー認証情報が正常に Mayhem サーバーで認証され、プライベートな Mayhem Docker レジストリにログインすると、 $MAYHEM_DOCKER_REGISTRY
環境変数が設定されます。
その後、新しく作成した Mayhemfile
と同じディレクトリで mayhem run
を実行します。
$ mayhem run .
Run started: forallsecure-testme-docker/testme/2
Run URL: https://tutorial.forallsecure.com:443/mayhemuser/forallsecure-testme-docker/testme/2
⚡ 現実的な演習: testme-npd
のビルドとテスト¶
セグメンテーション違反はメモリ エラーの一種であり、不正なメモリ位置への読み取りまたは書き込みを行おうとしたときに発生します。一例として、値が NULL
であるポインターを有効なメモリ領域を指すポインターと同様に使用するという null ポインター間接参照があります。
int *p = NULL;
int y = *p;
この null ポインター間接参照を既存の testme
アプリケーションに追加して再ビルドし、Mayhem を使用して変更後の testme-npd
アプリケーションをファジングし、新たに追加されたバグを検出できるかどうか試してみましょう。
手順
-
次をダウンロードして展開します: testme-docker.zip
-
テスト ケースがアプリケーションに
null
を入力した場合にnull
null ポインター間接参照のバグを引き起こす if-else 文をtestme.c
ファイルに追加します。 -
docker build
コマンドを使用して Dockerfile を再ビルドし、結果の Docker イメージにtestme-npd
というタグを付けます。 -
docker tag
およびdocker push
コマンドを使用してtestme-npd
Docker イメージを内部的な Mayhem Docker レジストリにプッシュします。 -
Mayhem UI または Mayhem CLI を使用して
testme-npd
Docker イメージをファジングします。追加の欠陥を検出するのに必要な時間の増加に対応するため、Mayhemfile
でduration
に120
秒を指定するのを忘れないでください。testme-npd
バイナリで 2 つの欠陥を発見できるはずです。
-
次をダウンロードして展開します: testme-docker.zip
-
テスト ケースがアプリケーションに
null
を入力した場合にnull
null ポインター間接参照のバグを引き起こす if-else 文をtestme.c
ファイルに追加します。 -
docker build
コマンドを使用して Dockerfile を再ビルドし、結果の Docker イメージにtestme-npd
というタグを付けます。 -
docker tag
およびdocker push
コマンドを使用してtestme-npd
Docker イメージを内部的な Mayhem Docker レジストリにプッシュします。 -
Mayhem UI または Mayhem CLI を使用して
testme-npd
Docker イメージをファジングします。追加の欠陥を検出するのに必要な時間の増加に対応するため、Mayhemfile
でduration
に120
秒を指定するのを忘れないでください。testme-npd
バイナリで 2 つの欠陥を発見できるはずです。
🔍 確認 testme-npd
のビルドとテスト¶
解答
修正済みファイル: testme-npd.zip
まず、testme
関数に null ポインター間接参照を行うコード スニペットを追加します。testme
アプリケーションをファジングすると、入力テスト ケースが "null" だった場合に null ポインター間接参照のエラーを引き起こします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
|
次に、Dockerfile
と同じディレクトリで Dockerfile
コマンドを実行して、結果の Docker イメージを testme-npd
としてタグ付けします。
docker build -f Dockerfile -t testme-npd .
次に、testme-npd
Docker イメージを内部的な Mayhem Docker レジストリにプッシュします。
docker tag testme-npd tutorial.forallsecure.com:5000/forallsecure/testme-npd
docker push tutorial.forallsecure.com:5000/forallsecure/testme-npd
この例では、tutorial.forallsecure.com
Mayhem デプロイメント、具体的にはポート 5000
の内部的な Docker レジストリに testme-npd
Docker イメージをアップロードしました。Docker イメージを正常にアップロードするには、お使いの Mayhem デプロイメントの Docker レジストリに合わせて URL を修正する必要があります。
最後に、Mayhemfile
が次のようになっていれば、Mayhem UI または Mayhem CLI を使用して、アップロードされた testme-npd
Docker イメージに対して Mayhem ランを実行できたはずです。
image: $MAYHEM_DOCKER_REGISTRY/forallsecure/testme-npd:latest
duration: 120
project: forallsecure-testme-npd
target: testme-npd
cmds:
- cmd: /mayhem/testme/v1/testme @@
最新のラン ページは次のように表示されるはずです。
おめでとうございます! Mayhem は不適切な入力検証の欠陥とともに、追加した null ポインター間接参照の欠陥も発見しました。Docker イメージを一からビルドし、脆弱性を追加して、Mayhem で検出できました。
✏️ まとめと振り返り¶
このレッスンでは、Docker イメージをビルドして Docker Hub にプッシュし、ファジングを行う方法を学びました。
このレッスンでは、Docker イメージをビルドして Mayhem のプライベートな Docker レジストリにプッシュし、ファジングを行う方法を学びました。
Docker イメージは Dockerfiles
および docker build
コマンドを使用してビルドできます。Docker イメージをビルドしたら、デプロイ済みの Mayhen インスタンスにある Docker レジストリにプッシュできます。Docker イメージを Mayhem に取り込みできるようになったら、Mayhem UI または Mayhem CLI を使用して Docker イメージに対してランを実行できます。
学習内容
1. ローカルな Docker イメージをビルドする
-
Docker を使用すると、ターゲット バイナリを含む独自のイメージを簡単にビルドできます。それには、Dockerfile を指定して docker build コマンドを実行するだけです。
1 2 3 4 5 6 7
FROM debian:buster-slim as builder RUN apt-get update && \ apt-get install -y gcc make libc6-dbg && \ rm -rf /var/lib/apt/lists/* WORKDIR /mayhem COPY src testme RUN cd testme && make
-
Dockerfile で次のコマンドが使用されているのがわかります。
- FROM: 新規ビルド ステージを初期化し、その後の命令で使用するベース イメージを設定します。有効な Dockerfile は必ず
FROM
命令で始まります。 - RUN: 現在のイメージに重ねられた新しいレイヤーでコマンドを実行し、結果をコミットします。結果としてコミットされたイメージが Dockerfile の次のステップで使用されます。
- WORKDIR:
Dockerfile
内で後に続くRUN
、CMD
、ENTRYPOINT
、COPY
、ADD
命令の作業ディレクトリを設定します。 - COPY: 新規ファイルまたはディレクトリを
からコピーし、コンテナーのファイルシステムのパス に追加します。
- FROM: 新規ビルド ステージを初期化し、その後の命令で使用するベース イメージを設定します。有効な Dockerfile は必ず
2. Docker イメージを Docker レジストリにプッシュする
- ビルドした Docker イメージをパブリックな Docker Hub レジストリにプッシュできます。
- Docker イメージが正常に Docker Hub にプッシュされたことを確認するには、Docker Hub の Web サイトに移動し、イメージ名を検索します。
- ビルドした Docker イメージを Mayhem の内部的な Docker レジストリにプッシュできます。内部的な Docker レジストリは、すべての Mayhem デプロイメントに含まれています。
- まず
mayhem login
コマンドを使用して Mayhem Docker レジストリにログインしてから、docker tag
およびdocker push
コマンドを使用して Docker イメージにタグを付け、プライベートな Mayhem Docker レジストリに アップロードします。 - Docker イメージが正常に Mayhem Docker レジストリにプッシュされたことを確認するには、Mayhem UI 内の Mayhem Docker レジストリに移動します。
3. Mayhem UI から Docker イメージに対して Mayhem ランを実行する
- Docker イメージが正常に Mayhem の内部的な Docker レジストリにアップロードされたら、Mayhem UI で新規ランの作成フローを使用して、アップロード済みの Docker イメージをファジングできます。
4. Mayhem CLI から Docker イメージに対して Mayhem ランを実行する
- Docker イメージが正常に Mayhem の内部的な Docker レジストリにアップロードされたら、
Mayhemfile
を構成し、image
パラメーターがアップロード済みの Docker イメージを指すよう設定します。その後、Mayhem CLI からmayhem run
コマンドを実行してアップロード済みの Docker イメージをファジングできます。