at posts/single.html

[security]SECCON 2013 北海道大会(CTF札幌予選) writeup

SECCON 2013の北海道大会に参加した。初めてのCTFだった。結果は10チーム中4位だった。

SECCON 2013 北海道大会(CTF札幌予選)

問題は全部で10問(図は9問だけどあとで問題14が追加された)。1位のチーム (dodododo) はうち7問を正解しているので、総合力が重要だよなぁ。

SECCON 2013 北海道大会(CTF札幌予選)

得意分野であるWebの「スロットマシーン」は最初に解けたので、WriteUpを書くよ。

スロットマシーン

お題はスロットマシーンで$10,000,000をゲットすること。所持金は$100からスタート。アクセスするとスロットマシーンが表示される。

SECCON: スロットマシーン

掛け金 (bet) を入力して start をクリックするとスロットが回り出す。stopをクリックするとスロットが止まる。2つの数字が揃うと掛け金の2倍が返ってくる。3つの数字が揃うと5倍、777だと10倍になる。

最初の関門は掛け金の上限。 bet は最大 $9 までしか入力できない。 maxlength="1" が指定されている。HTMLを書き換えると bet の上限を無制限にできた。

次に攻撃できる箇所を調べる。Firefoxの Web 開発 → ネットワークを有効にしてスロットを回して、リクエストとレスポンスを解析する。

startをクリックした時の通信。Ajaxでリクエストが飛んでいる。レスポンスはJSON。

リクエスト: 
http://10.0.2.4/slot.cgi?action=spin&bet=1&hash=2757ed8a5789b272bf36707bcebb30c2ea5a01391ccda4ab67ad4feeeb444eb1

レスポンス:
{ status: OK,
  result: 481,
  return: 0
}

次にstopをクリックする。スロットの結果は 481 。この時の通信。

リクエスト: 
http://10.0.2.4/slot.cgi?action=finish&hash=2757ed8a5789b272bf36707bcebb30c2ea5a01391ccda4ab67ad4feeeb444eb1


レスポンス:
{ amount: 99,
  status: OK
}

ここまでで分かったこと。

  • startとstopで同じhashが使われている。hashの値は毎回変わる。
  • startの時点で結果が決まっている
  • stopをクリックすると、持ち金が返ってくる ($1賭けて外れたので持ち金は$99)

start の時点で結果が決まっているので、 start だけ実行して結果が外れだったら stop せずにリロードしてみる。その結果、 stop をクリックしなかったら掛け金が減らないことが分かった。ここまで分かると、攻略法が見えてくる。

  • 全額 bet する
  • スロットを回して、結果が外れだったらブラウザをリロード (掛け金は減らない)
  • 結果が当たりだったら stop をクリックして勝ちを確定

ここで、スクリプト化できるかを試す。でも、課題が2つ。

  1. リクエストに付与される hash の生成ルールが分からない
    • 毎回同じハッシュを付与すると、勝ちが確定しても持ち金が増えない
    • ハッシュは JavaScript で生成しているっぽいが、難読化されているのでロジックが分からない
  2. stopのリクエストをWebブラウザから直接送るとエラー (status: NG) が返ってくる
    • HTTPヘッダに X-Requested-With: XMLHttpRequest を付与すれば回避できる

1つ目の課題(hashの生成ルール)が分からなかったので、スマートな解法を諦めてWebブラウザを使って力技で持ち金を増やすことにした。

  1. bet の maxlength を書き換えて持ち金全額を賭けられるようにする
  2. start をクリック。レスポンスを見て勝ち負けを判定。
  3. 負けだったらWebブラウザをリロードしてなかったことに。
  4. 勝ちだったらstopボタンをクリックして勝ちを確定。

1/10の確率で勝てて、勝つと持ち金が倍になる。$100からはじめて$10,000,000になるまで、ひたすら手動で繰り返す。ここで自動化できないところで、自分の力の無さを実感するも、結果を重視。途中で1回、ハズレなのにstopボタンをクリックしてしまい持ち金が0になってしまうも、30分くらいで目標金額を達成。flagが表示された。

SECCON: スロットマシーン

力技なのが釈然としない(他チームはJavaScriptの難読化を解除して、hashの生成ロジックを解析していた)けど、1問でも解けたからいいや。

出身地チャート (エラーコードを探せ)

最後に追加された問題14。これもWeb問題。アクセスすると、質問が表示される。6問回答すると、「あなたの出身地は○○です」と表示される。こちらもリクエストは2つ。

最初のリクエスト:
http://10.0.2.5/calc.php

ここから設問に答える。

設問終了後のリクエスト:
http://10.0.2.5/calc.php
name=%E3%81%BE%E3%81%A1%E3%82%85&q1=10&q2=no&q3=1&q4=yes&q5=other&q6=yes

普通に遊んでいても、キーワードが返ってこない。問題文が「エラーコードを探せ」。

ふと存在しないファイルを指定してみると、 404 エラーとともにこんなリクエストが返ってきた。

______kfou6s______

これで答えを投入しても、結果は外れ。でも、問題の方向性が分かってきた。他のステータスコードを返せばいいのか。ncコマンドを使って試す。

root@kali:~# nc 10.0.2.5 80
GET /404 HTTP/1.0

HTTP/1.1 404 Not Found
Date: Sat, 30 Nov 2013 13:01:25 GMT
Server: Apache/2.4.7 (Unix) PHP/5.5.6
Content-Length: 18
Connection: close
Content-Type: text/html; charset=iso-8859-1

______kfou6s______

root@kali:~# nc 10.0.2.5 80
PUT / HTTP/1.0

HTTP/1.1 405 Method Not Allowed
Date: Sat, 30 Nov 2013 13:12:34 GMT
Server: Apache/2.4.7 (Unix) PHP/5.5.6
Allow: TRACE
Content-Length: 18
Connection: close
Content-Type: text/html; charset=iso-8859-1

____________f0nor6

404エラーと405エラーで flag の一部が返ってきた。あと1つのエラーを見つけられずにタイムアップ。答え合わせによると、 .htaccess や .htpasswd へリクエストすると 403 とともに flag が返ってきたらしい。

まとめ

はじめてのCTFだったけど、ちょうどいい手応えと、ちょうどいい悔しさだった。セキュリティといっても、マクロの視点(Webシステムのセキュリティ)とミクロの視点(バイナリ解析、ネットワークキャプチャ)の両方が必要。Web以外は手も足もでなかったので、次に向けて幅を広げたい。

運営の皆様、ありがとうございました。

関連する日記