画像は PHP STRING COMPARISON VULNERABILITIES に載っているやつです。
配列や3引数以上与えると NULL
が返ってくる。
var_dump(strcmp("a", "a")); // int(0)var_dump(strcmp("a", "b")); // int(-1)var_dump(strcmp("a", "b", "c")); // NULLvar_dump(strcmp([], "a")); // NULL
そのため ==
で比較してたりするとバイパスできてしまう。(strcmp
は2つの文字列が等しい場合 0
を返すため、NULL == 0
が成立する)
// 問題のあるコードif (strcmp("a", "b", "c") == 0) {echo "bypassed (arity 3)";}// 問題無いコードif (strcmp("a", "b", "c") === 0) {echo "bypassed (arity 3)";}
検証コード
与えられたクエリパラメータ key=val
を用いて、変数 key に val を代入する。
その際、既存の変数を上書きできてしまう点に注意。
以下のコードは一見問題なさそうに見えるが、?hashed_key=xxx
というパラメータが与えられた場合、hashed_key
の既存の値が xxx
になってしまう。つまり、任意の値に書き換えることができる。
$hashed_key = '79abe9e217c2532193f910434453b2b9521a94c25ddc2e34f55947dea77d70ff';$parsed = parse_url($_SERVER['REQUEST_URI'])$parsed_query = parse_str($parsed["query"]);$hashed_input = hash('sha256', $_GET["key"]);if($hashed_input !== $hashed_key){die("GTFO!");}echo file_get_contents("/flag");
パラメータ・フラグメントに @
から始まるホスト名を指定すると、なぜか上書きできてしまう。
報告 | Fix |
5.6.26 | 5.6.28 |
php > echo parse_url("http://example.com:80#@google.com/")["host"];google.comphp > echo parse_url("http://example.com:80?@google.com/")["host"];google.com