開発
wechall:Time to Reset
beko
佐藤です。今回はwechallの問題をやりましたがなかなか面倒で最後まで答えが出せてません。しかし、脆弱性は理解したので書きます。
上記のように、メールアドレスを入れてリセットするとトークンがもらえます。自分のメールでやってみました。
今回はの問題は、[email protected] のユーザーのトークンを奪えということです。
このアプリのソースコードも公開されているので見てみました。
どうやらトークンの生成に脆弱性があるようです。
function ttr_random($len, $alpha='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789') { $alphalen = strlen($alpha) - 1; $key = ''; for($i = 0; $i < $len; $i++) { $key .= $alpha[rand(0, $alphalen)]; } return $key; }
要求があった個数だけランダムにアルファベット数字が帰ります。
28行目でこれらのrandのシード値が生成されています。
srand(time()+rand(0, 100));
これらをまとめると、
<?php srand(time()+rand(0, 100)); function ttr_random($len, $alpha='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789') { $alphalen = strlen($alpha) - 1; $key = ''; for($i = 0; $i < $len; $i++) { $key .= $alpha[rand(0, $alphalen)]; } return $key; } echo ttr_random(16); ?>
実行結果は、
<?php srand(12345678+rand(0,10)); function ttr_random($len, $alpha='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789') { $alphalen = strlen($alpha) - 1; $key = ''; for($i = 0; $i < $len; $i++) { $key .= $alpha[rand(0, $alphalen)]; } return $key; } echo ttr_random(16); ?>
いくつか同じトークンが生成されていることがお分かりでしょうか。
randの範囲も100から10に縮めています。10分の1の確率でトークンが衝突します。
つまり、今回のwebアプリケーション(問題)は時間が固定されていれば約100分の1であたることになります。
問題に戻ります。
メールアドレスを送ったとき、そのときの時間と100分の1でトークンが生成されてるとしたらトークンが判明してしまうと思いませんか!?
で、多分ここからブルートフォースだと思います。
生成した時間よりシードを作成しそこから100通りのトークンがどれかになるはずです。
スクリプトができ次第編集します。