この記事は富士通クラウドテクノロジーズ Advent Calendar 2021 6日目の投稿です。
昨日の投稿はこちらです。 qiita.com
本番環境のほかに開発やテスト用の環境は大抵必要ですし、本番環境も一つとは限らないこともあり、似たようなManifestを微妙に変えて使いたいことはたくさんあると思います。 Helm Chartを自作するとそのあたりを柔軟に行えるので重宝しますね。Helm Chartの作成が結構簡単にできる事が伝わるかと思うので、まだの方は是非読んでみてください。
さて、本日の記事では10月に弊社内でCTFを開催したことについて紹介したいと思います。
CTFとは
コンピュータセキュリティの分野において、その知識や技術を競い合う競技としてCTF("Capture The Flag" の略)というものがあります。 競技形式は様々ですが、今回社内CTFとして採用した「Jeopardy形式」と呼ばれるものについて簡単に説明します。
競技は主催者が問題をいくつか用意し、参加者がその問題に各自で挑む形になります。 「フラグ」と呼ばれる事前に定められたフォーマットに従った文字列がそれぞれの問題の中には隠されており、それを見つけ出すためには、与えられた暗号やバイナリファイルを解析したり、用意されたシステムの脆弱性を発見し攻撃するなどといった形で、セキュリティの知識・技術を活用する必要があります。(後程、問題の具体例も交えつつ説明します。) この「フラグ」を見つけ出し回答することで参加者は得点を得ることができ、獲得した得点を競うといった流れになっています。
国内外問わず、誰でも参加できるようなオープンなCTFはたくさんありますので、興味があれば調べてみて下さい。 例えば、 https://ctftime.org/ では色々なCTFの開催情報を調べることができます。
なぜ社内CTFを開催するのか
そんなCTFをなぜ社内開催することになったのか、個人的な部分も含めて経緯を話したいと思います。
DEF CON 27 見学
DEF CONという有名なセキュリティに関するイベントがあります。 私はコンピュータセキュリティに詳しいというわけでもないのですが、それでも名前は知っているぐらいのイベントです。
弊社では社員の技術系イベントへの参加を推奨する取り組みがあり、2年前にラスベガスで開催されたDEF CON 27に関しても、会社の費用負担にて参加できるという話がありました。
これに志願し、運良く見学してきてよいことになりました。 DEF CONの中では色々なセッションを聴講して興味深い話をたくさん聞きましたし、色々なブースでCTFが開かれていたり、会場全体の雰囲気も刺激的でした。
全社的なスキルアップの必要性
DEF CONで多くの刺激を受けた私は、見学の成果報告としてレポートを作成したり社内で報告会を実施するだけではつまらないと感じるようになっていました。そこで、弊社のサービスの開発用の環境で、実際に攻撃を試してみることにしました。そして、DEF CON内の発表で初めて知ったある典型的な脆弱性について探してみたところ、その途中にそれとは異なる脆弱性を見つけてしまいました。
迅速に修正は行われましたし、情報流出などにつながるような致命的な脆弱性でもありませんでしたが、似たようなことが起きないようにするための取り組みが必要であると感じることになりました。
弊社が提供するサービス(及びその中の機能)は多岐にわたり、それらを支えているシステムや開発・運用のチームは一つではありませんが、そのすべてにおいて強固なセキュリティを実現していく必要があります。それらのサービスに対して横断的に対処するアプローチ(簡単なところでは標準化されたチェックリストのようなものや、脆弱性診断など)も重要だと考えていますが、それと同時に、サービスを深く理解している人がそれぞれセキュリティに対する知識を磨き、各々が堅牢なサービスを作り上げていく必要もあると個人的には考えています。
CTFを企画
社内の各所にセキュリティの知識を磨く人がいるべきだという思いから、
- 社内でセキュリティに関心を持つ人を増やす
- セキュリティに関する情報交換ができるような社内交流の促進
を目的に、自主的な取り組みとして社内CTFを開くことにしました。
実は社内でCTFが開催されたことはこれが初めてではなく、私の所属していた部内で数年前に開催されたことがありました。 当時は私は運営に関わらないただの参加者であったどころか、CTFに触れること自体が初めてでしたが、それによって関心を持つようになったこともあり、社内CTFによってセキュリティに興味を持つ人が増えることを期待しました。
また、オープンなCTFもたくさんありますが、未知の競技にいきなり参加するのはある程度心理的なハードルがあり、参加のしやすさを考えると社内で開催するメリットもあると思います。
CTF準備
社内CTFを開催するにあたって、作問含めた運営に協力してくれる同僚を募集し、私含めて3人で運営しました。
CTF未経験者を想定して易しめの問題を中心に、以下のジャンルの問題を合計11問(ウェルカム問題除く)作問しています。
社内交流の促進も狙っているので、チームを組んでの参加を認めつつ、参加者が一斉に挑めるよう競技時間は短期集中で90分とすることにしました。
問題例
CTFを知らない方にはイメージが付きづらいかと思うので、出題した問題について一つ紹介します。
「Webhook」というタイトルの問題では、CTF用に用意されたWebアプリのURLと共に、そのアプリの動作環境の /flag
というファイルの中身に答えである「フラグ」がかかれていることが問題文にて示されています。したがって、このWebアプリの脆弱性を見つけ出し、それを利用して /flag
というファイルの中身を読み出すことが、この問題を解く上でやるべきことになります。
実際にWebアプリを見てみると、以下のようなことが分かります。
- WebhookエンドポイントのURLを登録できる
- 登録時にはテストメッセージを送り、正常に応答が返ってきた場合のみ登録できる作り(応答内容も表示する)
- トップページからは登録したWebhookに対してメッセージを送信できる
- アプリのソースコードも確認できる
(ソースコードが確認できる点については、CTFとしての出題の都合で与えているものになります。)
Webhookのエンドポイントを登録する際に正常に応答が得られるURLかを確認していますが、この部分は「事実上任意のURLに対しリクエストを投げその結果を取得できる」という性質を持っていることになります。
せっかくソースコードが与えられているので、その中身を見に行くと、内部的に pycurl
(libcurl
のpython用ライブラリ)を使っていることが分かります。
libcurl
はCLI上で curl
コマンドとしてよく利用されていますが、 curl
コマンドがそうであるように、様々なプロトコルを扱うことができます。
目的である /flag
というファイルは、 libcurl
からは file:///flag
というURLによってアクセスできるので、これをWebhookエンドポイントの代わりに指定することで、「フラグ」を得ることができます。
これをスコアサーバーにて回答することで、得点を得ることができます。
この問題で用意したWebアプリの脆弱性は、一般に SSRF (Server-side Request Forgery) として知られているもので、SSRFを題材にして作問しようとしてできたのがこの問題でした。
インフラ周りの工夫
CTF開催に必要となるシステムはニフクラを利用して用意しましたが、以下のような工夫をしています。
- スコアサーバー(参加者が問題を閲覧したり回答を送信するシステム)にはお手軽に使えるCTFdをニフクラのサーバー上で動かして利用
- 社内向けなので、社員であることが認証できた人だけに利用を制限
- CTF未経験者は問題を解くための環境を持っていない可能性があるため、Unix系のCLIが欲しくなるような部分では共用サーバーを提供
- 参加者間で共通ユーザーを利用してもらうが、ログインごとにDockerコンテナを立ち上げ、ログインセッションごとに隔離された環境が利用できる少し変わった設定
- 一般的なLinux共用サーバーのようにユーザーで分けると、参加者ごとにユーザーを作成するのが面倒になるため
- 問題を解くために必要になるツール類をインストールしておいたコンテナイメージを利用
- 参加者間で共通ユーザーを利用してもらうが、ログインごとにDockerコンテナを立ち上げ、ログインセッションごとに隔離された環境が利用できる少し変わった設定
開催前後の流れ
開催まで
開催3週間前ほどに告知をして参加者を募ることにしました。 CTFが何ものかを知らない人が多いかと思うので、単にCTFを開催すると言っても伝わりにくいのが難しいところでした。 また、未経験者からは難しそうで取っつきにくいイメージを持たれやすいと思うので、未経験者でも解けることをアピールするようにしました。
最終的には、1人のみのチームも含め、14チームが参加してくれました。
当日
多くの社員が基本的に在宅勤務をしている状況なので、参加者はZoomを利用してチーム内でのコミュニケーションをとったりしつつ問題を解いていたようです。
運営としては、競技開始前後はかなり慌ただしかったです。参加者へ注意事項などを説明するオープニングの実施をしつつ、参加者が問題を閲覧できるようにスコアサーバーやWebジャンルやPwnジャンルの問題を配置しているサーバーの設定を変更する作業も必要になるためです。 競技開始後はしばらく見守るだけになりますが、スコアサーバーの設定ミスなどが見つかることもあり、気は抜けませんでした。
そして実際の競技結果が以下のスコアボードです。
90分と時間が短かったこともあり、1チームあたりの正答数は少なめですが、終了1分前に首位が逆転している、なかなか熱い展開でした。
後日
数日の間を空けて、問題の解説をする会を開きました。 その際には、その問題に正答した参加者に解法を説明してもらえないかお願いし、正答者がいた問題すべてで参加者から解説してもらうことができました。 運営側で用意していたものよりも遥かに丁寧で分かりやすい解説資料を用意して下さった人もいたぐらい、参加者の皆さんの解説が素晴らしかったのが印象的でした。
振り返って
実際に開催してみてわかったことも多く、今後の取り組みにも生かしていきたいなと思っています。
苦労した点
- 難易度の調整が難しい
- CTF未経験者を想定しているので、難易度は控えめにしたい
- 一方で、セキュリティに関心を持ってもらうことを意図しているため、現実からかけ離れた設定にはできず、ある程度の難易度にはなってしまう
- 結局のところ、実際に開催してみないと難易度が適正だったか判断がつかない
- 開催時間の調整が難しい
- 参加者の拘束時間を長くしすぎるのも負担になってしまう
- 短期間すぎると、問題を満足いくまで解けない可能性も増えてくる
- 運営面での負担も大きい
- 自主的に開催しており、通常の業務もしながら準備していたのでまとまった時間は取りにくかった
良かったこと
- 開催後に取ったアンケートでは、好意的な意見がほとんどで、再度社内CTFを開いて欲しいという声もあった
- 競技後に自主的に反省会をする参加者がいたり、社内コミュニケーションに利用しているSlackでエゴサしたところ結構話題にしてもらえていて、当初の目的に含まれていた社内交流の促進にいくらか繋がっている
- 個人的な話だが、作問などを通じて新しく学ぶことも多く、運営をすることが良い勉強になった
明日の記事は @HanchA さんから「AWS EC2にPostfix, Dovecot, Zabbixを入れてサーバーを監視してみる」の予定です。 Postfixを運用していたことがあるのですが、上手く監視する方法が分からず苦労した記憶があります。もしかしたらPostfixの監視についての話題もあるのでしょうか?個人的にも気になります。 お楽しみに!