昨年の9月にオンライン予選が開催された,SECCON CTF 2014の決勝戦に参加してきました.
昨年はチーム”竹田氏”という名前で決勝戦に出場していたチームの一人と入れ替わり,チーム”Mr. Takeda”として参加しました.
英語表記になったのは,今年からマルチバイトはだめと言われたためで大意はありません.懇親会等でも”たけだし”と呼ばれたので漢字表記のほうが定着しているようです.
国内だけの大会だったはずが,世界大会になり,さらには世界的なハッキングコンテストが開催されるDEFCONの出場権がついてくることになったため,有名な海外のチームもやってきて超難関な決勝戦になってしまいました.Twitterでは,「国内野球大会かと思って参加したら、突然優勝賞品にワールドシリーズ出場権が追加されて、参加チームにヤンキースをはじめ世界の超一流プロチームが集まっていて、ふと隣を見るとイチローがアップを始めていた」と例えられていました(笑)
今回の目標は半分冗談で1桁の順位と決めていたのですが,24チーム中 9位の成績を収めることができ,メンバー一同騒然となる,総合的にはとてもうれしい結果を残すことができました.

SECCON CTF 2014 決勝戦スコア
6台のサーバが用意されており,攻撃に成功するとフラグと呼ばれる文字列が手に入ります.これをスコアサーバに送信することで,ひとつあたり100点が加算されます.
また,各サーバに定期的に更新される自分のチームのDefence Keywordを書き込むと,5分ごとに得点が入るルールがあります.
残念ながら,本題のフラグは一つも取ることができなかったのですが,他のメンバーが解いている間にDefence Keywordをなんとかしてそのタイミングにサーバに書き込むことを続けていました.
これにより,3+α個のフラグに相当する得点ができたので,なんとかチームに貢献できてよかったです.
予選ではないDefence Keywordを賭けた他のチームとの攻防戦はとても楽しかったです.
SECCONの詳細は後で加筆することにして,問題のWriteUpを先に書いておきます.
サーバ壱
Redmineのデザインそっくりな”Secmine”というユーザー登録が必要な架空のサイトについての問題でした.

Secmine 登録ページ
メニューから,管理者に対して任意のURLを開かせることができる脆弱性がありましたので,クロスドメインの問題を避けながらなんとかセッションか,その他の情報を管理者から奪取すればよさそうというところで頓挫.
このサーバでは,チームで登録したアカウント数のランキング上位に5分ごとに得点できる状態になっていたのですが,単位時間あたりに登録が可能な回数が制限されているため,一番最初に気づいたチームが独占状態で,参戦するのはやめました.

Secmine アカウント数ランキング
サーバ弐
以下のような種類があるCAPTCHAがついた掲示板でした.

掲示板
CAPTCHAには,
- 単純に文字列
- 四則演算
- 図形の位置をマウスで合わせる
- 一部が欠けた図形の位置をマウスで合わせる
- 文字列の位置をマウスで合わせる
というパターンがありました.

CAPTCHA パターン
ここで,ランキングというページを見ると,5分間に投稿された回数がアクセス元IPアドレス別にランキングされており,1位を取ると管理ページにアクセスする権利が得られ,無事一つのフラグをゲット.

掲示板管理ページ
ちなみに,このページで表示されるCAPTCHAのタイプやその他のパラメータを調整することができ,他のチームの邪魔をすることもできます.
もう一つどこかに攻撃できる点があるはずなんですが,ここで頓挫.
このサーバでは,最新数件が含まれる”History”に自分のチームのDefence Keywordが本文として書き込まれていると5分ごと得点が入るのでなんとかしてCAPTCHAを自動化してたくさん投稿する作戦を立てました.
“文字列”,”四則演算”,”図形”の3パターンだけを自動化すると絞り込んで,Pythonでノイズを除去し2値化,オープンソースのtesseract-ocrでデコード,四則演算の場合には計算した結果を送信.円の場合には左上の座標を算出し送信し,無事自動化しました.ところが,画像処理が挟まるためすごくおそい….5分間で数百回が限度でした.

CAPTCHA ノイズ除去
その後他のチームが5分間に数千という回数の投稿をしてきたので,脆弱性をついてCAPTCHAをスキップする作戦に変更.
調査をしてみると,”cap_token”というCookieがあり,それと答えが1対1に対応する上に,何度でも通ってしまう脆弱性が見つかりました.これを突いて,CSRFトークンと,固定の答えだけを1度目のだけ画像解析を使い,2度目以降は同じ答えを使い回すことで大幅に速度を向上させました.
ここまでくると,Pythonを使わずにbashとcurlコマンド(+α)だけで実装すればさらなる高速化が期待できると考えたので,シェルスクリプトを作成.チーム全員に配布し各人100プロセス以上並列に起動させて,もはやDDoS状態でした.

掲示板投稿ランキング
私たちのチームは192.168.4.0/24なのですが,ここに載ってるタイミングで1万リクエスト以上成功しています.
この時点で,チームの現在のDefense Keywordをスコアサーバから取得する必要があるのですが,このページ,WebSocketでできてるんです.
なので取得が面倒くさい.そこで,PythonでWebSocketクライアントを書いて,取得した最新のDefence KeywordをHTTPで配信するサーバを立てました.
これにより,他のメンバーはDefense Keywordをcurl等でGETするだけで利用できます.この設計が後々サーバ伍ですごく役に立つことに.
サーバ参
オーバーフローの脆弱性があるプロセスが用意されており,ROP(Return-Oriented Programming)の手法を用いて攻撃する問題.
@aki33524が解いたのでWriteUpにリンク張ります.
サーバ四
mips, h8300, m32r, mn10300, rxのアーキテクチャで動作する脆弱性のあるプロセスに対し攻撃をかける問題.逆アセンブルしてコードを読むと,オーバーフローが起きる問題を見つけたのですが,攻撃コードを考える時間がなくて断念.
サーバ伍
よくわからないHTTPサーバが動いてる.どうやら4台あるよう.@misodengakuがひとつフラグをゲットしたので,WriteUpにリンク張ります.
二つ目以降のフラグが手に入らなかったのですが,どうやらこの問題はWebの問題ではなくて,TCP/IPの問題だったそうで,不正なIPヘッダのダミーのパケットが返って来るために通信できないポートがあったそうな.
そのダミーパケットをうまく選別して,iptablesでDROPさせればつながるポートがあるらしい.だれかWriteUp書いたらリンクはります.
ネットワークの問題って気付けば解けたのに!これが個人的にはすごく悔しいです.
Webの問題に見せかけるのずるい…
このサーバでは,トップページに自分のDefence Keywordを書いておけば,5分ごとに得点できました.
パスワードがかかっていないSubversion-WebDAVが動いているのを発見したので,ファイルをすべて消して,自分のDefence Keywordのファイル名のファイルだけを作成しサーバにコミットするスクリプトを無限ループで実行.
ここにDefence Keywordが書き込めていたのは,準優勝のHITCONとうちだけだったようです.
ここで,サーバ弐のときに準備しておいたキーワード配信サーバが役に立ちました.
サーバ六
様々な方法で暗号化された文字列を元に戻す問題.@__mathが説いたのでWriteUpにリンク張ります.
このサーバでは本題とは別に,Pythonで書いた暗号・復号プログラムを投稿し,最も短いコードかつ,誰にも解かれていないスクリプトを投稿できているチームに5分ごとに得点が入る構造になっていました.
最初のうちは @__math がまともに投稿して,何度か得点していたのですが,これ以上は難しいという短さまで到達.得点が加算されるタイミングを分析して,INPUT=OUTPUTという全く暗号化していないけれども最も短いコードをその瞬間に投げることで,何度か得点することができました.
追記
NHKにしっかり映ってた
