TDUCTF 2015の運営をした話

TDUCTF 2015の運営をした話

みなさんご参加ありがとうございます。 存じ上げている方もたくさんいらっしゃると思いますが、先月末の日曜日にTDUCTF 2015なるものが開催されました。

TDUCTF 2015 - connpass

前回開催が3月末にあったのですが、所要で参加できないことがわかり、悔しさからネットワーク系のCTF問題を作って提供しました。

そのとき運営陣の@nomuken氏からの「次回は問題作成だけではなく運営陣に加わっていっしょに盛り上げよう」との提案を受け、 今回TDUCTF 2015にて運営側に立つこととなりました。

さて、具体的に運営として何をしてきたかの記録を以下に述べますが、後半には問題のネタバレなどを含んでおります。ご注意ください。

目次

Open 目次

  1. フロントエンドアプリケーションの作成
  2. 問題作成
    1. Keygenerator
    2. devnull
    3. 「名前が変えられいるってことで間違いないな」
    4. Portscan
    5. Lucky 7
    6. moneyscript
    7. moneyscript!!!
  3. 開催について

フロントエンドアプリケーションの作成

TDU CTF 2014 Satellite in ConoHaが無事終了し、次回開催に向けての話が始まりだした時に運営の方々の仲間に入り、どのようにして準備していくかなどの議論をはじめました。 その議論の最初の議題は毎度フルスクラッチなスコアサーバーをどうしようかというものでした。 常設CTFや有志で行われてるオンサイトCTFでイケてるスコアサーバーを見かけないのを悲しく思い、Web開発全然得意じゃないのにも関わらず、

「俺がイケてるCTFスコアサーバー作るよ」

などと言ってしまいました。

すんなりと「お、じゃあお願いするね」と言われて開発することになったのですが、イケてるスコアサーバーはWebフロントエンド部分のことを指しており、 サーバーサイドは別で他のメンバーが開発する、分業となりました。

さて、困った。作ると言い出したものの最近のWebのトレンド知らないしTwitter Bootstrap・jQueryアレルギーだしどうしたものか、と。

まだ開催まで時間あるしとりあえずトレンド調査だけしておこうと思い、いろいろ調べるだけ調べて放置していました。

時は流れ、TDUCTF 2015開催2週間前。

Slackに流れる「フロントエンドの進捗どうですか?」の文字列。 手元のソースコードリポジトリでgit logをしてみたところ、

fatal: bad default revision 'HEAD'

アカン。

その日から睡眠時間を削り、圧倒的進捗率を叩き出すべく腱鞘炎になりながらもコードを書き続けました。

コミットはゼロでも頭の中に構想は練ってあったので、あとはキーボードを叩きまくるだけという状態になっていたものの、 時間が足りない上に睡眠不足でタイポするわで結構大変でした。

トレンド調査で、React+Fluxの構造を軸に、見た目はSemantic UI 2で整え、Electronで単一アプリケーション化するのがモダンでイケてる感じであるとわかったので、これらを用いて組み立てていくことにしました。 Electronでアプリケーション化したのは、「今までにないイケてるCTFスコアサーバー」の形を実現する目的に加えて、「マルチブラウザ対応に追われる時間をゼロにする」目的もありました。結果として、Internet Explorer(CTF参加者に利用者はいるのだろうか?)などのへの対応のためにバッドノウハウを使わなくて済みました。

途中Flux部分にしっくりくるものがなく、Reduxに変更するまでに時間を要したものの、2週間ぶっ通しの突貫工事でなんとか、開催までに”形にする”ことができ、参加者に楽しんでいたくことができたと思います。

開催までは非公開で管理していたのですが、オープンソースで公開するとの話があったので、現在はGitHubにて公開しています。

lepus-ctf/lepus-frontend · GitHub

詳しい開発秘話はしないので、苦労は上記リポジトリのコミットログから察してください。

問題作成

CTFの主軸となる問題作成に関しての話です。 ネタバレが含まれるので問題を解きたい人はお気をつけを。

CTFの運営として参加しているので、問題の作成はほぼ必須なのですが、なにせフロントエンドアプリケーションの作成に追われていて、 「案はあるけど作ってる暇がない」ということとなってしまい、少ししか用意できませんでした。 問題案などはストックできてるので次回開催時に登場する予定です。

用意した問題は一部を除いて以下のサイトで公開しています。

ctf.mzyy94.com

問題の作成意図と簡単な想定解法を紹介します。 あと、TDUCTF 2015は初心者歓迎を掲げて開催してたので、プロ向けの問題はあまりありません。

Keygenerator

http://ctf.mzyy94.com/q/TDUCTF2015-BIN200/

問題文: 実行してフラッグをゲットせよ!

この問題は、与えられた実行ファイルを実行しろというものです。 libprintkey.soという自作共有ライブラリとkey_generatorという実行アプリケーションが渡されるのですが、 普通にアプリケーションを実行したりデバッグしてもフラグは得られません。

作成意図としては、「共有ライブラリも単体実行可能」という点に気づいて、 問題文の「実行して」のとおりに共有ライブラリに実行可能フラグを立てて、 ./libprintkey.soとすれば、フラグが出力されるようになっていました。

gdbなどでkey_generatorをデバッグしてた方から、「あるべきところにフラグがないがどういうことなのか?」という質問がありましたが、 すいません、そっちじゃなかったんです。

単純に実行してフラグを得られるため初期の想定では100点問題になるとしていたのですが、 配点会議でライブラリの単体実行するポイントに気づかない人も多いかもしれないとのことで、200点に引き上げられました。

devnull

http://ctf.mzyy94.com/q/TDUCTF2015-BIN250/

問題文: Usage: ./devnull > /dev/null

実行すると、標準出力を/dev/nullにリダイレクトしてくれとUsageが出てきて、 そのとおりに実行すると、/dev/nullにフラグが出力されるというものです。

リダイレクト先をパスで判定しているので、/dev/nullを適当なブロックファイルに差し替えるか、 gdbでブレイクポイントを仕掛けたり、ltraceとかで処理を追って、出力される部分を覗き見できればフラグが得られます。

gdbの使い方に慣れてほしいという願いを込めて作っていたので、想定していた解法は以下のとおりです。

$ gdb ./devnull
(gdb) b printf
(gdb) r > /dev/null
(gdb) i r
(gdb) x/s $rsi

「名前が変えられいるってことで間違いないな」

http://ctf.mzyy94.com/q/TDUCTF2015-MISC200/

問題文: password

問題には拡張子がjpgのファイルが付属しています(JPEGファイルとは言っていない)。

CTFに必要なググり力を問うための問題で、問題タイトルを検索ワードにググると、 ほこ×たてのハッキング対決に関する記事がいくつかヒットします。 ほこ×たて内では 「名前が変えられいるってことで間違いないな」は「TrueCryptで暗号化されている」のことを指しているという記事が見つかるので、 添付のファイルをTrueCryptを用いてパスワードにpasswordを指定してマウントすると、フラグが出てきます。

Portscan

http://ctf.mzyy94.com/q/TDUCTF2015-NW500/

問題文: ポートスキャンが仕掛けられた!ん?何かメッセージがついてきているぞ?

UDPポートスキャンを観測したpcapファイルが渡されます。 UDPのペイロードに1バイトずつメッセージがついてきてるのでそれを抽出してあげるとフラグが取得できる問題です。

この問題は、WiresharkのFollow UDP Streamですぐに答えが出るようではひねりがないと思い、 tcpdumpやtsharkのオプションを覗いたり他のパケット解析ツールを使ってほしいという想いを込めて作成しました。 なので、Wiresharkで解くことはほとんど不可能です。

想定していた解答方法は以下のとおりです。 最初は100点くらいの配点にしようとしていたのですが、配点会議で「これはわからん」と言われ急遽500点まで引き上げられました。

printf $(tcpdump -r secretmsg.pcap -x 'udp' | grep 0x0010 | perl -pe's/^.*(..)00 0000\n$/\\x\1/')

Lucky 7

この問題はサーバーにアクセスするタイプのネットワーク問題なのでオンサイトでしか用意しておらず、現在は公開していません。 問題内容は、netcatでアクセスすると以下のような表示が返ってくるものです。

Challenge!
2187123 != 77777777

左辺にある数字が77777777と等しくなるようにアクセスするとフラグが降ってくるのではないかとピンとくる人もいれば、 ランダムに変化するからBruteforceで解こうする人もいたりと、サーバーを監視していてなるほどと感じることが多かったです。 この左辺の数字は、サーバー側がChallenge!を返す際のAcknowledge Numberになっており、ここが77777777になっていないためにエラーが返されているのです。 Wiresharkなどで監視しながらアクセスしていたひとは、この関連性がわかったとおもいます。

Sequential Numberをいじれるhping3やScapyに触れてもらおうという願いを込めて作成しました。 解法としてはそれらを用いて、3-way handshakeが終了した時点のSequential Number(= サーバーがChallenge!を返す際のAcknowledge Number)が77777777になるようにコネクションを張り始めるようにすれば、フラグが返ってくるというものでした。

moneyscript

http://ctf.mzyy94.com/q/TDUCTF2015-MISC400/

問題文: 6a29585444557b426974636f696e21426974636f696e21426974636f696e217d

moneyscriptシリーズの1問目です。こちらは簡単な方です。 moneyscriptのmoneyが指すのはBitcoinで、このシリーズの問題はBitcoin Scriptを実行して答えを得る問題となっています。 1問目は優しめに作ってあり、適当にデコードすればフラグが得られるよになっていますが、Bitcoin Scriptとは何かを理解してほしく作成しました。

Googleで検索するとBitcoin ScriptのWikiがヒットします。

Script - Bitcoin Wiki

このWikiにしたがって問題文のBitcoin Scriptが意味するところを先頭から照らしていくと、

  • 0x6a = OP_RETURN
  • 0x29 = 41バイト確保

それ以降は文字コードの16新表記となっています。

なので、適当にデコードするだけでフラグが出てきてしまいますが、Bitcoin Scriptの仕組みを知ってもらえたらとおもい、作成しました。

moneyscript!!!

http://ctf.mzyy94.com/q/TDUCTF2015-MISC600/

問題文は上記リンクから閲覧ください。

こちらは難しい方のBitcoin Script問題です。 先ほどのWikiにアクセスできていれば、照らしあわせて脳内で実行すればいいのですが、 少々骨の折れるものなので、Bitcoin Scriptを扱えるアプリケーションを使う必要が出てきます。

任意のアプリケーションを使って解いてもらえればいいのですが、 Node.jsのモジュールに、bitcoreというモジュールがあるので、それを用いて以下のように実行するなどして、フラグを取得できます。

var bitcore = require('bitcore');
var Script = bitcore.Script;
var code = '4c0155828f635e76937367595294687b736b7c6c938f618fa76b4c0222ea6c';

var buffer = new Buffer(code, 'hex');
var interpreter = Script.Interpreter();

interpreter.script = new Script(buffer);
interpreter.evaluate();

var first_stack = interpreter.stack.pop();
var hex_string = first_stack.toJSON().data.map(function(x) {
	return x.toString(16);
})

var flag = 'TDU{' + hex_string.join('') + '}';

console.log(flag);

開催について

フロントエンドアプリケーションの作成がギリギリだったがために、RESTサーバーのテストが十分にできず、運営陣には多くの迷惑をかけてしまいました。 また、フロントエンドアプリケーション側もテストが追いつかず、バグだらけで配布してしまったがために、当日は問題の添付ファイルが破損していたり、 カウントダウンが正常に機能しないなどのバグを発生させてしまい、参加者各位にも大変に迷惑をかけてしまいました。 その節は申し訳ありませんでした。

TDUCTF 2015終了後、反省会をオンラインで開催していた頃に「TDUCTF」という名称を変更しようという話が立ち上がり、 よくわらかないテンションでドメインから何から整え新名称に改称しました。

ということなので、今後はTDUCTFあらため、LepusCTFをよろしくお願いします。

Related Posts

SECCON 2014 横浜大会NW予選 Write-up

SECCON 2014 横浜大会NW予選 Write-up

SECCON 2014 横浜大会に参加してきました。 NW,BIN,WEBと3部門の予選がありましたが、ネットワーク大好き♡なのでNWにチャレンジしました。ネットワーク部門は10問ある問題を解いて...

read more
SECCON2014 Online英語版予選 Write-up

SECCON2014 Online英語版予選 Write-up

昨日12月6日午前9時(日本時間)から12月7日午後5時までの32時間耐久CTFが行われたので参加してみました。 あまり活躍できずでしたがチャレンジしたもののまとめを記します。...

read more

ネットエージェント最終面接問題 Write-up その1

恒例のネットエージェントのいきなり最終面接問題が3月末に公開されました。2016年度 新卒採用|ネットエージェント株式会社ネットニュースサイトにも取り上げられ( 「解けたらいきなり最終面接」 ...

read more

ネットエージェント最終面接問題 Write-up その2

ネットニュースサイトにも取り上げられ、盛り上がりを見せていたネットエージェントのいきなり最終面接mondaiのWrite-upその2です。「解けたらいきなり最終面接」 ネットエージェント、今年も新...

read more

ネットエージェント最終面接問題 Write-up その3

あのネットエージェントのいきなり最終面接問題を解いたのでWrite-upを書きました。2016年度 新卒採用|ネットエージェント株式会社これまでのmondaiはLinuxやOS Xがあれば解く...

read more

ネットエージェント最終面接問題 Write-up エクストリームCTF編

ネットエージェントのいきなり最終面接問題を解いたのでWrite-upです。2016年度 新卒採用|ネットエージェント株式会社これまでmondai1からmondai9までは、mondaiとOS ...

read more
DEFCON CTF 23予選 Write-up (解説付き(すこし))

DEFCON CTF 23予選 Write-up (解説付き(すこし))

今年のDEFCON CTFの予選が5月16日午前9時から48時間開催されていました。今回はチーム********としての参加ではなく、Team Enuに派遣される形で参加してきました。今年は、比較...

read more