6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Docker Quiz を解いてみる

Last updated at Posted at 2020-09-13

Docker Quiz とは

まだ挑戦したことがない方は是非この記事を読む前に挑戦してみてください。Docker の知識があまりなくても、調べれば回答できる問題が多いです。

後に講義の動画もアップされるようです。

解いてみる

Q1 [sanity check] 次の文字列を入力してください: FLAG_3u8z4xst

sanity check です。FLAG_3u8z4xst と入力します。

Q2 -q2 オプション引数を渡して起動せよ

docker run --rm hatena/intern-2020-docker-quiz -q2 のようにオプション引数付きで起動すると答えが表示されます。

ちなみに -hint オプションをつけて起動すると、各問題のヒントを見ることができます。

Q3 このイメージのentrypointとして指定されているコマンドのフルパスは何か

docker inspect hatena/intern-2020-docker-quiz でこのイメージの情報を見ることができます。その中に entrypoint が記載されているので、入力します。

Q4 /app/flag.txt をホストにコピーしてファイルの内容を取得せよ

docker cp <コンテナ名 or コンテナ ID>:/app/flag.txt ./flag.txt のようにしてホストにコピーできます。
コンテナ名は docker ps などから確認できます。

Q5 シェルを起動して /app/get_flag2.exe を実行せよ

docker run --rm --entrypoint /app/get_flag2.exe hatena/intern-2020-docker-quiz のようにして entrypoint を指定して実行します。

Q6 このイメージに含まれるpythonについて、Trivyによって検出されるseverityがHIGHの脆弱性のCVE番号を答えよ

Trivy というコンテナの脆弱性スキャナーを使います。

下記のコマンドで簡単にスキャンできます(macOS)。

docker run --rm -v /var/run/docker.sock:/var/run/docker.sock -v $HOME/Library/Caches:/root/.cache/ aquasec/trivy image hatena/intern-2020-docker-quiz

スキャンが完了すると脆弱性のあるパッケージの一覧が表示されるので、python パッケージの中から severity(重症度)が HIGH の CVE 番号(共通脆弱性識別子)を探して入力する...

...はずですが、python で脆弱性が HIGH の CVE 番号は見つかりませんでした。原因は分かりませんでしたが、表示された python の CVE 番号を片っ端から入力していったら正解することができました。何かご存知の方がいましたら教えていただけるとありがたいです。

(補足)オプションに --severity HIGH を指定すると severity が HIGH のものだけを表示できます。

docker run --rm -v /var/run/docker.sock:/var/run/docker.sock -v $HOME/Library/Caches:/root/.cache/ aquasec/trivy image --severity HIGH hatena/intern-2020-docker-quiz

Q7 このイメージのentrypointとして指定されているコマンドのソースコードを復元して、この問題の答えを取得せよ

docker history hatena/intern-2020-docker-quiz でこのイメージの履歴を表示することができます。

truncate されている & 見づらいので、docker history --no-trunc --format "{{.CreatedAt}}: {{.CreatedBy}}" hatena/intern-2020-docker-quiz のようにして整形して出力します。

履歴を見てみると、下記の 2 ファイルがコンテナにコピーされていることが分かります。

  • docker_quiz.go.enc(暗号化されたソースコードっぽい)
  • password__delete_me_after_decrypting(復号に使うパスワードが書かれたファイルっぽい)

残念ながら、 password__delete_me_after_decrypting は復号に使われたあと削除されています。

docker save hatena/intern-2020-docker-quiz > docker-quiz.tar で、イメージを tar ファイルとして出力することができます。tar の中身はレイヤの集合になっています。その中から前述の 2 ファイルがコピーされたときのレイヤを探し出せば復元することができそうです。

tar ファイルを展開し、2 つのファイルがコピーされたときっぽいレイヤの layer.tar を見つけ出し、展開します。tar tvf path/to/layer.tar で tar ファイルの中身を表示したり、ファイルサイズから推測したりすると比較的容易に見つけられます。

2 つのファイルを回収することができたら、前述の docker history で見つかった履歴と同じコマンドでソースコードを復号します。

openssl enc -d -aes-256-cbc -pbkdf2 -in docker_quiz.go.enc -out docker_quiz.go -pass file:password__delete_me_after_decrypting

ソースコードを見てみると、Q7 は入力した答えのバイト列のそれぞれの値に 0xff との排他的論理和をとった値が、[0xb9, 0xb3, 0xbe, 0xb8, 0xa0, 0xce, 0xc9, 0x8a, 0xca, 0x95, 0x88, 0x9d, 0x8d] と一致するかどうかを判定しているのが分かります。この答えは逆算することができます。下記は JavaScript で逆算する例です。

[0xb9, 0xb3, 0xbe, 0xb8, 0xa0, 0xce, 0xc9, 0x8a, 0xca, 0x95, 0x88, 0x9d, 0x8d].map((b) => String.fromCharCode(b ^ 0xff)).join('');

手に入った文字列が答えになります。

失敗した方法

/app/docker_quiz をホストにコピーし、 objdump -d ./docker_quiz で逆アセンブルをしてみたけど何も分からなかった。

感想

Docker は普段から使っていましたが知らないことも多く、勉強になりました。楽しかったです。

6
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?