妄想まとめ

研究とかWebセキュとか時事ネタとか。 @kazu1130_h

SECCON名古屋 コンプガチャ writeup

SECCON名古屋行ってきました。

多分大阪でも出たと思うんですが、Web100のコンプガチャのwriteup書きます。

f:id:kazu1130_h:20131216002319p:plain


つってもあれですね、Burpのログふっ飛ばしちゃったんで、色々察して下さい☆

てか、僕のツイートの後にwakatonoさんが呟いていた……気付かなかった……


id:10 Web 100pt コンプガチャ

f:id:kazu1130_h:20131216002252p:plain

チャンピオンを倒してフラグをゲットせよ


見た時点では札幌で出たスロットマシーン系かと思ってました。
一応writeup読んでたので、PHPでhttpクエリを楽に飛ばせる関数作ってたんですが、まぁ使う機会はありませんでした。


とりあえずURLがRESTにある/battle/user/1みたいな記述になってるのとPOSTされる値がdata[_Token][key]=1ac4432ef…… みたいな形式になってるのが見えたので、Mass Assignmentだろうなと踏んで、パラメータ改竄による勝利を目標にしました。


この手のフレームワークっぽいものを使った問題だと、SQLとかXSSは少ない気がします。ORマッパーを狙うのはあるかもしれませんが、まだ見たこと無いのでとりあえずスルー。


Mass AssignmentはGithubで見つかった一件で有名ですね。その辺の話は、そらはーのブログに詳しく載っています。(github の mass assignment 脆弱性が突かれた件


ざっくり説明すると、

<form method="POST">
  <input type="text" name="data[name]" size="10">
  <input type="text" name="data[bio]" size="30">
  <input type="submit" value="Change">
</form>

というフォームがあった時に、

<?php

#---略---#

$user->update(array("name"=>$_POST["data"]["name"]
                    "bio"=>$_POST["data"]["bio"]
              ));

#---略---#

?>

とすべき所を、

<?php

#---略---#

$user->update($_POST["data"]);

#---略---#

?>

と、してしまった場合に起こります。
update出来る物がname,bioだけなら良いのですが、例えば別の場所でidやpasswordやlankをupdateするために、何にでも対応できる万能なupdateにしたとすると、burpとかでdata[id]=hogeといったものを突っ込むことで勝手に色々値が書き換えられてしまいます。

githubの件ではこれで日付やら公開鍵やらをごにょごにょしたっぽいです。


で、フローとしては、

  1. 書き換えるパラメータと値の特定
  2. 書き換える場所の特定
  3. 書き換え
  4. バトル
  5. キタ━━(゚∀゚)⌒Y⌒(。A。)⌒Y⌒(゚∀゚)⌒Y⌒(。A。)⌒Y⌒(゚∀゚)━━!!

こんな感じになるのかな、と考えました。ほかにも、強制的に勝った事にするパターンなんかも考えてました。


で、色々やった結果、書き換えるパラメータと値はやぎはしゅが見つけた、"勝負する"を選んだ時にいける画面で降って来るJSONから特定しました。JSONの中にはpasswordとかwinとか、色々思わせぶりな要素もあったのですが、先に方針を決めていたのでスルーしました。

書き換えたのはparamsだかpowerだかの要素です。これだけ値が99999とかになっていて、これを基準に勝敗を決めているのでは、と考えたためです。


場所に関しては少し迷いました。このフレームワーク(?)では殆どのPOSTにdata[_Token][fields]=1e64ac…… というものがついており、これがランダムに変わる上、POST時にdata[battle][win]=1 とかやろうとするとforbiddenを返してきます。なので、このCSRF対策とパラメータ改竄対策っぽいものをすり抜けられ、かつMass Assignmentで書き換えられる場所を探す必要がありました。

探し回った挙句、挑戦者の名前を変える所を使いました。ここだけはdata[]という形式でなく、name=hogehogeという普通の形式でPOSTしていました。このため、改竄対策をすり抜けられると考えました。
また、書き換え対象のデータは自ユーザのものなので、自ユーザのデータがupdateされていなければなりません。
このフォームはユーザデータをupdateしているという条件も満たしています。



で、場所とパラメータと値が特定できたので、名前変更と同時にparamsに9999999999くらいの数字を叩き込んで勝負したら、flagを吐いてくれました。



冷静に考えるとフレームワークの処理っぽくないのにMass Assignmentがあるのは気持ち悪いですね。だって、バックで動いているコードは多分これですよ?

$user->update($_POST);

うわー、って感じですよね。


感想としては、

とか

とか。僕の場合はマイナー脆弱性Web屋としての、ですね。


あとパスワードマネージャーの曲がちょいちょい流れててテンションあがりました。あの曲聞くと不思議な力が働いて集中出来ますw




まぁそんなこんなで無事に優勝しました。




後半の追い上げとか運営のイジメとか、色々つらいことがありましたが、全部やぎはしゅが打ち倒してくれました。



皆さんお疲れ様でした!
本戦でこわい人達にボコされてきます!!!!