Eyes, JAPAN Blog > wechall:Time to Reset

wechall:Time to Reset

beko

この記事は1年以上前に書かれたもので、内容が古い可能性がありますのでご注意ください。

佐藤です。今回はwechallの問題をやりましたがなかなか面倒で最後まで答えが出せてません。しかし、脆弱性は理解したので書きます。

20150428014047

上記のように、メールアドレスを入れてリセットするとトークンがもらえます。自分のメールでやってみました。

20150428014420

今回はの問題は、[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);
?>

実行結果は、

20150428022509
乱数となっていますね。では時間を固定するとどうでしょう?

<?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);
?>
20150428023854

いくつか同じトークンが生成されていることがお分かりでしょうか。
randの範囲も100から10に縮めています。10分の1の確率でトークンが衝突します。
つまり、今回のwebアプリケーション(問題)は時間が固定されていれば約100分の1であたることになります。
問題に戻ります。
メールアドレスを送ったとき、そのときの時間と100分の1でトークンが生成されてるとしたらトークンが判明してしまうと思いませんか!?
で、多分ここからブルートフォースだと思います。
生成した時間よりシードを作成しそこから100通りのトークンがどれかになるはずです。
スクリプトができ次第編集します。

Comments are closed.