見出し画像

合宿でCTFの主催をした記録

大学でNakano Computer Club(NCC)というサークルに所属しています。
NCCの合宿は、onsen-(YYYY)-(SEASON) というナンバリングが為されています(NCCの合宿では温泉に行くのが通例です)。
今回の onsen-2018-summer では最後を締めくくるイベントとしてCTFを企画しました。
企画したのは僕(mayoneko)、幹事長(progfay)、会計(nekomaru)の3人です。
それぞれが自分の作った問題の解き方などについて今記事を書いています。
合宿前半についてはおそらく他の誰かが書いてくれるのだろうと思うので、そこについては省略します。
代わりに僕は作問についてとか、サーバーについても少し話そうと思っています。

CTFとは

Capture The Flagの略です。
情報技術やセキュリティの知識を駆使して、隠されたflagと呼ばれる文字列を探し出すゲームです。
一般的なCTFについてはうさぎ小屋さんの記事CpawCTFなどがよくまとまっています。
ですが、今回の合宿参加者のほとんどが学部1,2年であったため、「セキュリティに関する知識を試すこと」よりも、「協力して同じ問題を解くことで親睦を深める」ことを目標としています。
そのため出題される問題は一般的なCTFとはかなり異なることをご留意ください。

合宿概要

日程:2018/9/17~2018/9/19 二泊三日

宿泊地:おんやど恵(最高でした)

CTF概要

名前:OCTF2018

日程:2018/9/18 17:30~2018/09/19 16:30

ルール
・3チーム対抗戦
・flagの形式はoctf{XXXXX}
・夜は寝ること(23:00~07:00はスコアサーバーへの回答を禁止している)

作問について

そもそもCTFを合宿でやりたいと思ったきっかけの記事がこちらです。
最高の記事なので皆さん見てください。
こういうCTFができたらいいなあというのが始まりです。

作問が始まったのは6月始めでした。
あんまり覚えてませんが、僕も忙しかったのに僕より忙しい幹事長が最初に作問を始めたのが印象的でした。

大体目標としていたのは1人10問でした。
30問あれば各チーム1人1問以上は解けるのではないかという算段です。
結局3人で40問、僕は1人で19問作ったのですが、それぞれの問題の難易度を考慮してこれぐらいの問題数がちょうど良かったのではないかと思いました。
もうちょっと少なくても良かったかな?

難易度については幹事長が今回作問するときの目安として挙げていたのをコピペしておきます。

解き方はなんとなくわかるけど、ちゃんと考え始めると少し悩む問題を目指して作ってる感がある

会計は唯一セキュリティの研究室にいるので、セキュリティ的問題を作らないといけないみたいなムードがありました。
会計の問題は唯一CTFの過去問に似せて作った問題があります。

僕は何も気にせず自分が作りたいと思った問題をお構いなしに作りました。

今回は普通の問題の他に、最終問題として3人それぞれが1問ずつ担当して超高得点問題を作りました。
幹事長は1000点、会計は800点、僕は600点を担当し、すべてのflagは新宿にある3つのコインロッカーの中にそれぞれ隠しました。
最終問題には、「この問題に正解した場合、以降のフラグ提出は受け付けません」という注意書きがあります。
またコインロッカーは1チーム1つまでしか開けてはいけないというルールを付与しました。

サーバーについて

CTFdをAWS上で動かしました。
サーバーについては全部僕がやりました。
最初はgunicornでCTFdを動かすだけで簡単じゃんとか思っていたのですが、phpの問題をたくさん作ってしまったがために、Apacheでリバースプロキシを張ったりしなくてはならなくなり、初めての経験だったので非常にしんどかったです。

反省点としては、オートスケールにしなかったことと、httpsにしなかったことです。
この辺は時間がなくて放置していたのですが、実際に動かしたときに後輩から指摘されたので素直に反省します。

実際にCTFをやってどうだったか

公開した直後の幹事団の盛り上がりの様は本当にここに載せられないことが残念なくらい異常なハイテンションでした。
かなりの時間を掛けて準備したものを目の前で楽しんでもらえている状況は非常に興奮しました。

ほとんどの人がピクロスを知らないとか、Processingに関する問題は予想以上にサクッと解かれるとか、なぜか暗号にめっちゃ強い人がいるとか、始まってから驚くことはたくさんありました。
ピクロスを知っている人が学部1年に一人だけいて、その人が自チームのピクロス問を一人で解いてたのが印象的でした。
ピクロス問は「情報技術に疎くても解ける問題を」というコンセプトで幹事長が作った問題だったので、学部1年が活躍している様子は個人的にとてもうれしかったです。
暗号問題は実は全部僕が作っていたので、一番難しい暗号問題を初日に解かれてしまった僕は膝から崩れ落ちました。
その他にも僕の作問ミスが発覚したりして非常に申し訳なかったです。

上は初日が終わった段階でのスコアです。
初日を終えた段階で思った以上に多くの問題が解かれてしまっていて、問題数が足りなくなりそうだと思った僕はまた問題を作り始めます。

翌朝、幹事長に5時半に起こしてもらった僕は、高速で作れる問題を高速で3問追加します。
7時からスコアサーバーを動かし始めるのですが、7時に起きてる人はほぼいませんでした。
学部1年は海を見に行ったりしてたので、サーバーを動かすのはもっと遅くからでも良かったと思いました。

朝食を終えてから、僕は「Casquette Search」という問題のためにこっそり外出します。
この問題は、キャスケットという帽子をかぶった僕を探してくれという意味で、問題を解くと出てくる地図には近所のショッピングセンターの位置が表示されます。
問題が解放されるとすぐにそのショッピングセンターの位置は特定されるのですが、誰もそこに向かおうとしないために、僕はそこで12時までの2時間ほど待ちぼうけを食らうことになります。
椅子が固くてつらかったです。

宿の会議室は11時までの貸し出しだったそうですが、CTFは16時半まで続きます。
下は朝から11時までのスコアの変動です。

ここからメンバーは解散して、各々で問題を解いていくことになります。
「Casquette Search」の解放と同時に最終問題も全問解放されて、どのチームも少しずつ新宿に帰らないといけないことが分かってきています。

ここからがPCの電池残量と戦うCTFの始まりだったのです。

どのチームも最終問題の中で最初にロッカーの位置が分かったのは会計の作った800点の問題でした。
幹事長の作った1000点問題は、14*14のピクロスを9つ解いて組み合わせるとQRコードでロッカーの位置が分かるというもので、ピクロスを解くのに相当な時間がかかるため、どのチームもひとまずどのロッカーも開けないで1000点問題を目指すことにしていたようです。
この時点でのグラフを下に載せておきます。
点数が下がっているのは、ヒントの開示を行なったことによるものです。

各チーム1人以上新宿に到着したころです。
HumilityチームとTrustチームは800点のロッカーの鍵を持っていることをお互いに知っていて、1000点のロッカーの鍵を待っている状態でした。
しかし、Respectチーム(グラフの緑)がここで800点のロッカーを解放します。

この時点でRespectチームは1000点のロッカーと600点のロッカーを開ける権利を失うのですが、同時にHumilityチームとTrustチームも800点のロッカーを開けることができなくなりました。
Humilityチームは学部1年が一人で、Trustチームは学部1年が三人がかりで1000点問題のピクロスを解いていました。

ここからの攻防はとてもアツい展開でした。
TrustチームはHumilityチームの解いていない高難易度問題を次々に解決し、徐々にHumilityチームとの差を縮めていました。
大体あと400点ほどで同点というところまで追いついたのです。
そのころ僕と幹事長は新宿で腰を下ろせる喫茶店を探し歩いていました。

ここでHumilityチームに1000点問題のピクロスの画像が送られてきます。

その画像は正しいQRコードになっていて、それを見た僕と幹事長はコインロッカーの解放される瞬間を目撃すべく走ってその場所に向かいました。
コインロッカーの前では既に数人のHumilityチームがコインロッカーを開けようと順番を待っているところでした。
ドキドキしながら遠巻きに見つめる僕と幹事長の前で、コインロッカーは見事に開き、Humilityチームは最終問題のflagを手に入れたのでした。

そこからもTrustチームの追い上げは続きます。
しかし解放できる最終問題が600点しか残っていないことは知らされていないため、誰も600点問題に手を付けておらず、僕らから見たら絶望的な状況でした。
しかしどのチームも終了時間ギリギリまで問題に取り組み、とても素晴らしい勝負を見せてくれました。

タイムアップ直前でRespectチームとHumilityチームが最終問題を提出し、OCTF2018は幕を閉じました。

終了時点のスコアはこんな感じでした。

とても良い夏の思い出になりました。

僕が作問した全問題の解説は別記事に書きました

この記事が気に入ったらサポートをしてみませんか?