はまやんはまやんはまやん

hamayanhamayan's blog

Clown Show [BsidesBOS CTF]

Clown Show
The Freak Show is coming back one last time and giving out a free ticket to anyone who can give a 'good answer'! Can you get a ticket?

調査

シンプルなサイト。
名前と答えを送ると結果が帰ってくる。

  • ソースコード特に気になる所なし
  • トップページ/index.phpであり、ここにPOSTしてる
  • 簡単な', "チェックも問題なし
  • robots.txtを見ると、/src.phpがDisallowされている

src.phpの中身

$good_answer = '0';
$name = $_REQUEST['name'];
$answer = $_REQUEST['answer'];
$time = $_REQUEST['time'];
$digits = strlen(strval($time));
$flag = 'flag{this_aint_it_mate}';

if (isset($name) && isset($answer)) {
    if (strlen($answer) < 10) {
        echo '<p style="color:red;font-size:30px;">Your answer should be at least 10 characters long!!</p>';
    }
    else {
        if (isset($time) && is_numeric($time) && $digits >= 10) {
            $key = hash('sha256', $name . $answer . $time);
        } 

        else {
            $key = hash('sha256',$name . $answer . time());
        }

        if (substr($key, 5, 25) == $good_answer) {
            echo '<p style="color:blue;font-size:30px;">Good answer! Here\'s your ticket ID:</p>' . $flag;
        } else {
            echo '<p style="color:red;font-size:30px;">Bad answer mate, try again!</p>';
        }
    }
}

flagを表示させるには、ざっくり言うと「name+answer+time」のsha256したものの5文字目から25文字分を取ってきて0になればいい。
ん?結構MagicHashにならないか?
そんな簡単な問題か?…ん?あれ?

Writeup

CTFtime.org / BsidesBOS CTF / Clown Show
あれ?方針一緒だぞ?

解法

ああ、少し勘違いしていた。
substr($key, 5, 25) == '0'がtrueになるには、
XXXXX0eNNNNNNNNNNNNNNNNNNNNNNNXXXXXXXXX....
となる必要がある。Nは0-9のいずれか。
Xの部分は別になんでもいいので、25文字分は全通りで1625通り。
そのうちOKなのは、1023通りなので、
1023/1625*100をしてみると、0.0000078%くらいの確率。
単純計算106回くらい試行すれば発見できる。
まあ、頑張ればという感じか…

サボってWriteupのタプルを試すと、フラグ回収
flag{w00t_W0ot_juggl1n6_1s_2_3z}