2020年03月07日00:00から09日00:00 UTCにzer0pts CTF 2020を開催しました。 今回はいままでと違い、zer0ptsで開催したという点と、CTFtimeに載せたという点で初だったので緊張感がありました。 開催記を残すとともに、CTFtimeに載せる手順や攻撃への対応なども書くので今後CTFをグローバルで開催したい、という方の参考になれば嬉しいです。
イベントの登録
過去にCTFを開催したことがない場合、CTFを登録する前にまずイベントを登録する必要があります。 イベントを開催するためには、CTFtime上でどこかのCTFチームに所属している必要があります。 ロゴやイベントの説明などを書いてフォームからCTFtimeの運営に送るのですが、承認されるまでに1週間程かかりました。 これは1週間という規定なのか、運営がチェックするまでに1週間かかったのか、あるいはその間に追加・変更したサーバー情報やCTFの説明が影響したのかは分かりませんが、とにかく思った以上に時間がかかりました。
CTFの登録
イベントが承認されたら今度はCTFを登録します。 CTF・賞金の説明、URL、形式や開催場所などとともに、JSONによるスコアボードのfeed用URLを指定します。 スコアボードのfeedは必要なのかは分かりませんが、theoremoonがスコアボードのfeed用APIを作ってくれたので登録しました。 タイムゾーンなどとともに開催期間を指定するのですが、これは一度確定すると変更できないので注意が必要です。 こちらはフォームを送信してから反映されるまでに4日, 5日ほどかかりました。 結果としてCTFtimeに登録されるのが想定よりも遅くなってしまいましたが、何とか開催までに載せることができました。
結果の登録
CTFが終了したらスコアボードを登録します。 これをしないとpublic votingができず、weightも付かないので競技終了後すぐに送りましょう。 スコアボードはJSON形式で送信するのですが、送信したら「Successfully sent」みたいなメッセージが出るだけで編集とかはできません。
Weight
初回は最大25でweightが付けられます。 ここはお祈りタイムで、満点を付けてくれる人もいれば「Too hard」とかいう理由で低い点数を付けてくる人もいます。 なんか全部満点ならレートが50になるらしいですが、なかなか起こり得ないと思います。 なお、特定の国だけを対象にしていたり、競技が「小さい」と判断されたりするとweightは付きません。 「小さい」の基準はよく分かりませんが、24時間以内だとグローバルでもそうなった事例があります。 weightが欲しい場合は36h以上は開催した方が良いでしょう。
作問
pwnに関しては昨年の4月頃から思いついたら作る、という形でちまちま作っていました。 なんでこんなに早くから始めたかというと、作った直後は質の悪い問題も良問と思いやすいからです。 実際、この頃から作っていたいくつかの問題は時間が経つと「既出だろ」とか「面倒なだけだろ」みたいな理由で結構消滅しました。 そのためpwnは他のジャンルに比べて難化 + 問題量増しました。 個人的に初心者向けの問題は各ジャンル最低1問は必要と思っているので、開催前に簡単なmeowmowとhipwnを追加して緩和しました。 が、meowmowは実は難しかったらしいです。 Kernel Exploit初めて1ヶ月程度なので難易度感が分からずmediumにしましたが、hardで良かったかもしれません。
そんな具合で早い段階からpwn問を作っていたのですが、なんと問題が足りなかったのです。 僕が早々にpwnとかrevばっかり作っていたので問題数が足りると思い込んでいたのか、webやcryptoが明らかに少ないことに徐々に気付き始めました。 cryptoは僕も多少分かるので簡単な問題をいくらか作ったのですが、とうとう1週間前くらいになって「いやweb全然なくね?」となって燃えました。 5問くらいは欲しいということで、チームメンバーにお願いしてぎりぎりでurlappとMusicBlogを作って貰いました。 こういうのはもっと前からpingし続けないとダメですね。
作問チェック
問題はチーム内でチェックして不備が無いかを確認しました。 pwn担当が僕以外いなかったのでチェックできるか不安でしたが、今年から入ったaventadorさんが一気に全部解いてくれて無事解決しました。 作問チェックは大切で、例えばcryptoではCBC gadgetを使うhardな問題を出題予定だったのですが、作問チェックで簡単な解法が見つかったので無事墓地に送ることができました。
ただ、唯一dirty laundryはyoshiking以外誰も理解不能だったのでチェックしないまま出題しました。(とりあえず簡単な解法が無いことだけ確認した) そもそもcrypto全般の担当がおらず、古典暗号担当、RSA担当、楕円曲線担当みたいな分かれ方をしているのでcryptoのチェックが難しかったです。
開催期間
36hにすべきでした。 36h段階でぎりぎり上位チームが全完していない程度だったので、明らかに36hが適切でした。 コロナでキャンセルになったイベントの空きを使って48hにしたのでコロナのせいです。(は?)
問題数が足りないことに気づいた段階で36hにしたかったのですが、CTFtimeは時間が変えられないのでダメでした。
運営
やること
前回は開始直後にサーバーが落ちる504 CTFを開催してしまったので、今回は事前にtheoremoonが負荷テストをしてくれました。 質問対応にはタイムテーブルを作って必ず2人以上は起きているようにしました。 開催中はCPU使用率とかネットワークの状態をぼーっと眺めて、やばそうだったら問題ごと再起動するなどしていました。 私はpwnのパケットを見て「あー非想定解だなー」とか思っていました。
攻撃
ちょくちょくbrute forceが飛んできます。 brute forceをbanするはっきりとした指標はなかったのですが、CPU使用率が100%になったりネットワークリソースが枯渇するような攻撃は私の中でban対象にしました。 (どうせ解けないので)web問にツールを回すくらいは許容し、babybofを16bitくらいの総当りで解こうとする攻撃はさすがに重かったのでban対象にしました。 banしたIPの方からはすぐに「やっちまったぜ」連絡が来て、スクリプトも止んだのでbanはすぐに解除しました。
問題
問題数
問題数の指標としては、24h開催で25問、48h開催で40問程度を指標に考えていました。 結果としてWelcomeとSurveyを除いて25問で、明らかに48h開催の問題数ではありませんでした。 簡単な問題と非常に難しい問題を序盤に出すようにしましたが、難しいと思っていたものも予想以上にすぐ解かれてしまいました。
点数
「guessできたら簡単だけど解ける人は少ない」問題は出さないので動的配点を採用しました。 動的配点の式としては「CTF Design Guideline」に載っている式を使いました。 しかしこれには罠があり、この式は500点満点を前提としているため、1000点満点にするにはKの計算式中に出てくる200を450程度に変える必要があります。 最初の方はこれに気づいていなかったので、たくさん解かれても点数が減らなくて :thinking_face: になっていました。
問題内容
初回InterKosenCTFからguessは出さない、ソースコードはできるだけオープンに、を守って問題を作っているのでその点は相変わらずで良かったと思います。 pwnはソースコードをほぼ全部公開したにも関わらず、割と時間がかかる問題を量産できたので良かったです。 一方でrevが簡単すぎるという声が多くて悔しかったので、rev力を高めて次はもっと面白くて難しい問題を作ろうと思います。
それから前回のInterKosenCTFに続き、特殊なSurvey問を用意しました。 正直動的配点だと効力が出る様子が目に見えないのですが、zer0pts CTFのSurveyは解いても最終回答時間が更新されません。 これは、同じ点数を持つチームAとBがあり、もともとAの順位が高かったのにBが先にSurveyを解いて順位が上がることを防ぐためです。 これにより、Surveyを回収しつつ、フラグを得るためだけの適当な回答を防ぐことができます。 実際には適当回答をしてくるチームは少しいました。
難易度
最初は中級者〜上級者向けのみを考えていたのですが、初心者も参加することは明らかだったので、0 solveを防ぐためにwarmup問を各ジャンル1問は用意しました。 ただ、CTF終了後に「想定難易度を記載する必要は無いのでは」という意見がチーム内で出たので、次は検討しようと思います。 (warmupは初心者の道標なので、warmupタグだけは付けるとかを考えてみたい。)
今回のCTFは賞金が付いており、今までのように自分たちのお金や個人スポンサーからの支援だけでは回せませんでした。 トップページにも載っていますが、株式会社アクティブディフェンス研究所様、株式会社ヘマタイト様の2社にご支援いただきました。 リンクとロゴを載せるくらいしかできないのですが、それでもzer0pts CTFの運営を理解していただき、ご支援くださいましたことを心より感謝いたします。
初回開催にも関わらず、強いチームがたくさん参加して、かつ高い評価をくれたのが嬉しかったです。 スコアボードやサーバーにちょくちょく問題が発生しましたが、今回ので修正&知見を得たので、次はその辺の質も高いCTFにしたいです。 去年に続き、たぶん次は初心者向けのInterKosenCTF 2020を開催します。