コンテンツにスキップ

ビギナー

ターミナルからのコード テスト

もっと深く学びましょう! このレッスンでは、Mayhem CLI をインストールしてコマンド ラインからターゲットをテストする手順を説明します。


学習時間の目安: 20 分

このレッスンを終了すると、以下のことができるようになります。

  1. Mayhem CLI をダウンロードしてインストールする。
  2. mayhem login コマンドを使用して Mayhem で認証する。
  3. Mayhem CLI から Docker イメージに対して Mayhem ランを実行する。
  4. クラッシュを起こすテスト ケースを使用して Docker コンテナー内で欠陥を再現する。
  5. スクリプトを使用して Mayhem ワークフローを作成する。

レッスンを駆け足で

  1. Mayhem CLI をダウンロードし、正常にインストールされたことを確認します。

    mayhem --version
    2.10.0rc16+a374eca
    
  2. mayhem login コマンドを使用して Mayhem サーバーで認証します。

    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.
    
    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.
    
  3. 次の Mayhemfile を指定して mayhem run コマンドを使用し、Docker ターゲットに対して Mayhem ランを実行します。

    1
    2
    3
    4
    5
    6
    image: forallsecure/tutorial:2.10
    duration: 90
    project: forallsecure-tutorial
    target: latest
    cmds:
      - cmd: /root/tutorial/testme/v1/testme @@
    
    1
    2
    3
    4
    5
    6
    image: $MAYHEM_DOCKER_REGISTRY/forallsecure/tutorial:2.10
    duration: 90
    project: forallsecure-tutorial
    target: latest
    cmds:
      - cmd: /root/tutorial/testme/v1/testme @@
    

以下が必要です。

  • Linux または MacOS オペレーティング システム
  • Docker がインストールされていること (Mayhem Docker レジストリでの認証に必要)
  • 有効なインターネット接続 (パブリックにアクセス可能な Docker Hub イメージのテストに必要)

ターミナル記録

Mayhem CLI から Docker イメージに対して Mayhem ランを実行する

ターゲット アプリケーションをテストするのに Mayhem UI を使用する場合でも、Mayhem CLI を使用する場合でも、Mayhem ランにはターゲット用に構成された Mayhemfile が必要です。そのため、Mayhem CLI を使用してターゲット バイナリをテストする場合、Docker ターゲット用に Mayhemfile を構成してから mayhem run コマンドを実行する必要があります。やり方を見てみましょう。

Warning

Mayhem CLI が正常にインストールされ、認証情報が認証されていることを Mayhem CLI のインストール ページで確認してください。

まず、新しいフォルダー tutorial を作成して移動します。次に、新しい Mayhemfile を作成し、次の構成をコピー&ペーストします。

1
2
3
4
5
6
image: forallsecure/tutorial:2.10
duration: 90
project: forallsecure-tutorial
target: testme
cmds:
  - cmd: /root/tutorial/testme/v1/testme @@
1
2
3
4
5
6
image: $MAYHEM_DOCKER_REGISTRY/forallsecure/tutorial:2.10
duration: 90
project: forallsecure-tutorial
target: testme
cmds:
  - cmd: /root/tutorial/testme/v1/testme @@

結果として、フォルダー構成は次のようになります。

├── tutorial
    └── Mayhemfile: Mayhem ランの構成ファイル

Mayhemfile を設定したので、mayhem run コマンドを実行できるようになりました。mayhem run コマンド形式は次のとおりです。

mayhem run <mayhemfile_directory>

したがって、先ほど Mayhemfile を作成した tutorial フォルダーでは、単に次のコマンドを実行して Mayhem ランを実行できます。

mayhem run .

ランが成功すると、次のように出力されます。

$ mayhem run .
Run started: forallsecure-tutorial/testme/4
Run URL: https://tutorial.forallsecure.com:443/mayhemuser/forallsecure-tutorial/testme/4

Mayhem UI に新しく実行された Mayhem ランが反映されます。

mayhem-cli-run

すばらしい! Mayhem CLI を使用して別の Mayhem ランを実行できました。

Tip

特定のプロジェクトおよびターゲットの過去のランを表示するには、mayhem show <project>/<target> コマンドを使用します。たとえば、mayhem show forallsecure-tutorial/testme を実行すると、次のように表示されます。

Name                            Status                                                                                 Reports    Crashes    Defects  Date
------------------------------  -----------------------------------------------------------------------------------  ---------  ---------  ---------  ------------------------------
forallsecure-tutorial/testme/3  dynamic_analysis:completed, regression_testing:completed, static_analysis:completed         30          7          1  Fri Jan 28 15:29:19 2022 +0000
forallsecure-tutorial/testme/2  regression_testing:completed                                                                24          0          0  Fri Jan 28 15:21:47 2022 +0000
forallsecure-tutorial/testme/1  dynamic_analysis:completed, regression_testing:completed, static_analysis:completed         24          1          1  Fri Jan 28 15:01:51 2022 +0000

コンテナー化されたターゲット バイナリの欠陥を再現する

Mayhem ターゲットで推奨されるパッケージ方法は、Docker コンテナーにアプリケーション バイナリをコンテナー化し、Docker イメージによって共有できるようにすることです。これは、ファジングされたターゲット バイナリで見つかった欠陥を検証したい場合、単にランの Docker イメージをダウンロードし、コンテナー内のターゲット バイナリに対してテスト ケースを再実行するだけですむようにするためです。

すでに Mayhem ランが実行済みである場合、コンテナー化されたターゲット バイナリで欠陥を再現するには、次の手順を実行します。

すでに Mayhem ランが実行済みで、ユーザーがローカルマシンの docker CLI からプライベートな Mayhem Docker レジストリにログイン済みである場合、コンテナー化されたターゲット バイナリで欠陥を再現するには、次の手順を実行します。

  1. ランの Docker イメージの docker pull を実行します。
  2. ダウンロードした Docker イメージに対してインタラクティブ モードで docker run を実行します。
  3. 実行中のコンテナーにテスト ケースをコピーします。
  4. 該当テスト ケースのファジング手順を実行して欠陥を再現します。

たとえば先ほどの Mayhem ランの場合、Mayhemfile の image の値を使用して docker pull を実行します。

1
2
3
4
5
6
image: forallsecure/tutorial:2.10
duration: 90
project: forallsecure-tutorial
target: testme
cmds:
  - cmd: /root/tutorial/testme/v1/testme @@
1
2
3
4
5
6
image: $MAYHEM_DOCKER_REGISTRY/forallsecure/tutorial:2.10
duration: 90
project: forallsecure-tutorial
target: testme
cmds:
  - cmd: /root/tutorial/testme/v1/testme @@
$ docker pull forallsecure/tutorial:2.10
latest: Pulling from forallsecure/tutorial
0f7bc87f0b77: Already exists 
30cc39211964: Pull complete 
b2cea678fd2b: Pull complete 
980e4fca2c5e: Pull complete 
c95be0a0e427: Pull complete 
b2f764506b1d: Pull complete 
ab5ce6632a38: Pull complete 
c8f755707129: Pull complete 
362f2e212a33: Pull complete 
0c6af55db2b2: Pull complete 
4dac91f0ff83: Pull complete 
d223eb603e3e: Pull complete 
Digest: sha256:dfc613cb21f206027970363fec47a3c82280f0c6a3f46f29a089af5dae92dfd4
Status: Downloaded newer image for forallsecure/tutorial:2.10
docker.io/forallsecure/tutorial:2.10
$ docker pull tutorial.forallsecure.com:5000/forallsecure/tutorial:2.10
latest: Pulling from forallsecure/tutorial
0f7bc87f0b77: Already exists 
30cc39211964: Pull complete 
b2cea678fd2b: Pull complete 
980e4fca2c5e: Pull complete 
c95be0a0e427: Pull complete 
b2f764506b1d: Pull complete 
ab5ce6632a38: Pull complete 
c8f755707129: Pull complete 
362f2e212a33: Pull complete 
0c6af55db2b2: Pull complete 
4dac91f0ff83: Pull complete 
d223eb603e3e: Pull complete 
Digest: sha256:dfc613cb21f206027970363fec47a3c82280f0c6a3f46f29a089af5dae92dfd4
Status: Downloaded newer image for tutorial.forallsecure.com:5000/forallsecure/tutorial:2.10
tutorial.forallsecure.com:5000/forallsecure/tutorial:2.10

Docker イメージがダウンロードされたら、docker run -it コマンドを使用して forallsecure/tutorial Docker イメージをインタラクティブに実行し、コンテナー自体の中でコマンドを実行します。

$ docker run -it forallsecure/tutorial:2.10
~/tutorial# 
$ docker run -it tutorial.forallsecure.com:5000/forallsecure/tutorial:2.10
~/tutorial# 

その後、クラッシュを起こすテスト ケースをダウンロードし、docker ps コマンドおよび docker cp を使用して、実行中の Docker コンテナーにテスト ケースをコピーします。

crashing-test-case

$ docker ps
CONTAINER ID   IMAGE                   COMMAND       CREATED         STATUS         PORTS     NAMES
abc183c111ff   forallsecure/tutorial   "/bin/bash"   6 seconds ago   Up 4 seconds             mystifying_hofstadter
$ docker cp aca42ffba79fea39a6b4876a7b6e0be67128f0aee2024b194e47a23cc3d08110 abc183c111ff:/root/tutorial/testme/v1

最後に、コンテナー自体の中で該当テスト ケースを実行して、コンテナー化されたバイナリ ターゲットで欠陥を再現できます。

$ ./root/tutorial/testme/v1/testme aca42ffba79fea39a6b4876a7b6e0be67128f0aee2024b194e47a23cc3d08110
Aborted

現実的な演習: Mayhem CLI を使用してワークフローを自動化する

Mayhem CLI を使用する主な利点の 1 つは、Mayhem コマンドを実行するスクリプトを作成できることです。他のコマンドと組み合わせると、ターゲットのテストに有用なワークフローを構築できます。たとえば、次の mayhem コマンドをスクリプトで実行できます。

  • mayhem run <path_to_Mayhemfile> は指定された Mayhemfile で Mayhem ランを実行します。
  • mayhem wait <id> はランが完了するまで待機します。このコマンドは、Mayhem が解析を終了するまで待機する必要があるスクリプトを作成する場合に便利です。
  • mayhem sync <path_to_Mayhemfile> はローカル マシンと最新の Mayhem の状態 (テスト スイートを含む) を同期します。

ヒント

mayhem wait コマンドに適切な $id 変数を指定するには、id=$(mayhem run <path_to_Mayhemfile>) 構文を使用します。

手順

  1. 以前に作成された Mayhemfile を使用して、forallsecure/tutorial Docker イメージに含まれる testme アプリケーションに対して Mayhem ランを実行する一連のスクリプト/ワークフローを作成します。

  2. forallsecure/tutorial Docker イメージのコンテナーにアクセスするには、次のコマンドを実行します。

    docker pull forallsecure/tutorial:2.10
    docker run -ti --privileged --rm forallsecure/tutorial:2.10
    
  3. 次に、forallsecure/tutorial コンテナーの中で次のスクリプトを作成して実行します。

    1. Mayhem ランを実行し、完了を待機し、生成されたテスト ケースをローカル マシンに同期するスクリプト。
    2. リグレッション テストを実行し、完了を待機し、テスト ケースをローカル マシンに同期するスクリプト。

    Note

    この演習は forallsecure/tutorial Docker コンテナーの中で作業するため、同期されたテスト ケース ファイルは Docker コンテナー内にダウンロードされます。

🔍 確認 Mayhem CLI を使用してワークフローを自動化する

解答

最初のスクリプトについては、次のような Mayhemfile があるとします。

1
2
3
4
5
6
image: $MAYHEM_DOCKER_REGISTRY/forallsecure/tutorial:2.10
duration: 90
project: forallsecure-tutorial
target: latest
cmds:
- cmd: /root/tutorial/testme/v1/testme @@

次のように、Mayhem ランを実行し、ランが終了するのを待機し、生成されたテストをローカル マシンにダウンロードする簡単なスクリプト run.shMayhemfile と同じディレクトリに作成します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
#!/usr/bin/env sh

# Run mayhem. The run ID is saved to $id
id=$(mayhem run .)

# Wait for the run to finish
mayhem wait $id

# Sync the test suite to the "testsuite" directory.
mayhem sync .

次のコマンドを実行してスクリプトを開始します。

$ sh run.sh
/tmp/tmpi2_eubh4/Mayhemfile 100% |#################| Time:  0:00:00   7.6 KiB/s
Run started: forallsecure-tutorial/testme/1
Run URL: https://tutorial.forallsecure.com:443/mayhemuser/forallsecure-tutorial/testme/1
Downloaded: Mayhemfile.
Downloading testsuite.tar: 138.0 KiB |#                 | Elapsed Time: 0:00:00 150.7 KiB/s
Extracting test 128 of 128 |#######################| Time:  0:00:00
Target synced at: '.'.

この時点で、次のようなファイルが作成されているはずです。

  1. Mayhemfile: Mayhem の構成ファイル
  2. run.sh: テスト スクリプト
  3. testsuite: Mayhem ランから同期されたテスト ケース

testsuite ディレクトリを確認すると、testme ターゲットのテストで使用されたテスト ケースがあるのがわかるでしょう。これは、不適切な入力検証の欠陥につながったクラッシュを起こすテスト ケースも含めたすべてのテスト ケースにアクセスできるようになったことを意味するため、重要です。

~/testsuite# ls -l | head -n 10
total 448
-rw-r--r-- 1 root root 14 Jan  1  1970 03be4170751ccbfeb3a1e9ef2b7b4f32bb7dd259a4cc0744d0e4ab1182c30821
-rw-r--r-- 1 root root 14 Jan  1  1970 04520a13840f8a3d0d6393e4a3a27c28531deddd0fbb20be565a21aa74837f2a
-rw-r--r-- 1 root root  8 Jan  1  1970 054fb66d37ab1222584a8f5e40d1d1dd9b1a52bf278ed5b5e34305a502dddc93
-rw-r--r-- 1 root root 12 Jan  1  1970 08bab601cb90a24a8fface4991fb2bdd78073c249c881e321f3b4b1be37ac9b8
-rw-r--r-- 1 root root 16 Jan  1  1970 0909ed9a9705deb19525e5af04eb1f0fec67a00f17ef048f3077304844b265b2
-rw-r--r-- 1 root root  5 Jan  1  1970 0a679f190e7e16930e9ad1fd9e113015e7300e6ef141612f2c05175d0090b972
-rw-r--r-- 1 root root 12 Jan  1  1970 0af2a88ccebf716e022b634526cd09a1ef23ea17c2dbc36ebc486f586dcad9dc
-rw-r--r-- 1 root root  6 Jan  1  1970 0bffd96d0cbdf2a7881ae8514c720a2c42aaea3d3c9a4f4f46c149ed75fd0db2
-rw-r--r-- 1 root root 36 Jan  1  1970 0d98d3438376a8a5d4b678ffb9c3439a28c923ff661c3f5bb656a27405f7238c

次に、2 つ目のリグレッション テスト スクリプトについてもプロセスはほとんど同じです。修正された (不適切な入力検証の欠陥が修正された) testme ターゲットを指す次の Mayhemfile があるとします。

1
2
3
4
5
6
7
8
image: $MAYHEM_DOCKER_REGISTRY/forallsecure/tutorial:2.10
duration: 90
project: forallsecure-tutorial
tasks:
- name: regression_testing
target: latest
cmds:
- cmd: /root/tutorial/testme/v2/testme @@

次のリグレッション テスト スクリプトがあれば、単にスクリプトを実行して自動リグレッション テスト ワークフローを作成できます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#!/usr/bin/env sh

# Run Mayhem regression testing
# The run ID is saved to $id
id=$(mayhem run . --regression)

# Wait for the run to finish
mayhem wait $id --regression

# Sync the test suite to the "testsuite" directory.
mayhem sync .
$ sh regression_testing.sh
/tmp/tmp6t6ue4e9/Mayhemfile 100% |#################| Time:  0:00:00   7.6 KiB/s
Run started: forallsecure-tutorial/testme/2
Run URL: https://tutorial.forallsecure.com:443/andrewyang/forallsecure-tutorial/testme/2
Downloaded: Mayhemfile.
Downloading testsuite.tar: 122.0 KiB |#               | Elapsed Time: 0:00:00 223.6 KiB/s
Extracting test 112 of 112 |#####################| Time:  0:00:00
Target synced at: '.'.

これで終わりです。初めての Mayhem ワークフローを作成できました。

✏️ まとめと振り返り

このレッスンでは、Mayhem CLI をインストールし、コマンド ラインからターゲットをファジングする方法を学びました。

Mayhem CLI をインストールする際、mayhem login コマンドを使用して Mayhem サーバーで認証を行ってから、mayhem run コマンドを使用して Mayhemfile に対する Mayhem ランを実行します。mayhem wait や mayhem sync などのその他の Mayhem CLI コマンドを使用すると、Mayhem ランをより詳細に制御できます。


学習内容

1. Mayhem CLI をダウンロードしてインストールする
  • Mayhem UI の CLI Installation ページに移動して、使用している OS (Linux または macOS) に合わせた適切な Mayhen CLI パッケージをダウンロードできます。
2. mayhem login コマンドで Mayhem を認証する
  • Mayhem ランを実行するには、mayhem login コマンドを使用して、Mayhem サーバーで認証情報を認証する必要があります。
  • Mayhem UI の CLI Installation ページに移動して、API トークンをコピーし、mayhem login コマンドで使用します。
3. Mayhem CLI から Docker イメージに対して Mayhem ランを実行する
  • Mayhemfile を指定して mayhem run を実行します。image パラメーターを指定すると、プライベートな Docker イメージまたはパブリックな Docker Hub イメージをランのターゲットとして指定できます。
4. クラッシュを起こすテスト ケースによって生成された欠陥を Docker コンテナー内で再現する
  • すでに Mayhem ランを実行し、ローカル マシンで docker CLI からプライベートな Mayhem Docker レジストリにログイン済みである場合、コンテナー化されたターゲット バイナリの欠陥を再現するには、次の手順を実行します。

    1. ランの対象となる Docker イメージの docker pull を実行します。
    2. ダウンロードした Docker イメージに対して docker run をインタラクティブ モードで実行します。
    3. 実行中の Docker コンテナー内にテスト ケースをコピーします。
    4. 欠陥を再現する特定のテスト ケースのファジング手順を実行します。
5. スクリプトを使用して Mayhem ワークフローを作成する
  • Mayhem CLI を使用する主な利点の 1 つは、Mayhem コマンドを実行するスクリプトを作成できることです。他のコマンドと組み合わせると、次のようにターゲットのテストに有用なワークフローを構築できます。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    #!/usr/bin/env sh
    
    # Run mayhem. The run ID is saved to $id
    id=$(mayhem run .)
    
    # Wait for the run to finish
    mayhem wait $id
    
    # Sync the test suite to the "testsuite" directory.
    mayhem sync .
    
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    #!/usr/bin/env sh
    
    # Run Mayhem regression testing
    # The run ID is saved to $id
    id=$(mayhem run . --regression)
    
    # Wait for the run to finish
    mayhem wait $id --regression
    
    # Sync the test suite to the "testsuite" directory.
    mayhem sync .