5/4 - 5/6という日程で開催された。undef1nedで参加して11位。私はGilroyでしか貢献できていないが…
リンク:
[Exploitation 100] Gilroy (39 solves)
(URL)
ソースコードはなし。
どのようなアプリか
与えられたURLにアクセスして、チームごとに割り当てられたチケットを入力する。これでundef1ned向けの環境が用意されるっぽい。チームごとの管理メニューは次の通りで、今回攻撃する対象であるフォーラムへのリンクや、このフォーラムのDBを初期化するリンクがある。
フォーラムは次のような雰囲気。なかなか凝っている。
ページの下部には Administered by: …
という項目があり、jasper 8892396092
というユーザが管理者であることがわかる。このユーザとしてログインするか、もしくは新たに管理者であるユーザを作ればよいのだろうか。
適当なユーザで登録・ログインしてみる。group
という項目がユーザの権限というか、ロールを意味しているのだろうけれども、これは normal
となっている。なお、jasper 8892396092
の group
は admin
だ。
フォーラムで新たなスレッドを立てたり、スレッドに対して返信したりもできる。なお、スレッドを立てる際にGIF画像を選んでタグとすることもできるが、BAN ME
など特定のタグを指定するとBANされてしまう。BANされるとユーザの group
が banned
となり、スレッドを建てられなくなってしまう。
group
を好きな値にする
まず、管理者であるユーザを乗っ取る方法はないか考える。スレッドや返信でXSSができないかと考えたが、<s>test</s>
のようなタイトル・内容で投稿しても、特殊な文字がエスケープされてしまう。特定のタグを使用するとBANされるけれども、このとき管理者が内容のチェックのために巡回してくるのでは、またその際の管理者の画面ではXSSが発生しているのではと考えたが、残念ながらそんなことはなかった。
SQLiが起こっていそうな雰囲気もない。管理者のパスワードのクラックも考えたが、さすがにもっとまともな解法であってほしいと考え、試すのは後回しにした。管理者であるユーザの乗っ取りは一旦諦めて、新たに管理者であるユーザを増やす方法はないか考える。
Mass Assignmentのように、本来フロントエンド側では存在していないパラメータを増やすことで、バックエンド側で受け付けてくれるのではないかと考えた。ユーザ登録時に <input name="group" type="hidden" hidden="" value="hoge">
と group
というパラメータを増やしてみる。すると、作成されたユーザの group
が空欄となった。本来 normal
が入るべきところ、変な値に書き換えることができているらしい。
group
というカラムに直接 normal
や admin
のような文字列が入っているのではなく、それらに対応する数値が入っているのではないかと考える。<input name="group" type="hidden" hidden="" value="0">
に変えると banned
という、本来はBANされたユーザに付与される group
になっていた。
<input name="group" type="hidden" hidden="" value="2">
では、次のように "An admin already exists" というエラーメッセージが表示された。2
は admin
に対応するらしいが、すでに jasper 8892396092
という admin
が存在しているために登録できないようだ。
管理者になる
ここからどうするか。まず jasper 8892396092
を管理者の座から引きずり下ろすことはできないかと考える。スレッドの投稿時に先程と同じ要領で投稿者のIDを書き換えることで、jasper 8892396092
になりすますことができ、またこのときにBANされるタグを使用することで、jasper 8892396092
をBANさせる(つまり、group
を admin
から banned
に変更させる)ことができるのではないかと考えた。しかしながら、poster
, author
, uid
, userid
, user_id
, …と思いついたパラメータ名を試したものの、どれもダメだった。
わざわざフォーラムのDBを初期化できるようになっていることが気になる。DBの初期化後にしばらく管理者がいない時間がもしあれば、その間にrace conditionによって、先程の方法で jasper 8892396092
より先に管理者になれるのではないかと考えた。しかしながら、何度か試しても不発だった。
ユーザ登録時の group
の値の検証と、その後のログイン等での検証とで、どの値を admin
とするかという処理が異なるのではないかと考える。つまり、登録時には admin
ではないとされるものの、それ以降の処理では admin
とされるような値があるのではないかと考えた。<input name="group" type="hidden" hidden="" value="0002">
と 0002
という値を group
に突っ込んでみたところ、管理者になることができた。
Admin
というリンクがトップページに増えている。これをクリックするとフラグが得られた。