WeChall - PHP 0818

Challenge

PHP type juggling 挑战。源码要求输入一个 "magic number",不能包含数字 1-9,但必须等于 3735929054。

Solution

源码关键逻辑:

1
2
3
4
5
6
7
8
9
10
11
function noother_says_correct($number) {
$one = ord('1');
$nine = ord('9');
for ($i = 0; $i < strlen($number); $i++) {
$digit = ord($number[$i]);
if (($digit >= $one) && ($digit <= $nine)) {
return false; // 禁止数字 1-9
}
}
return $number == "3735929054"; // loose comparison
}

数字 0 是允许的(只检查 1-9)。3735929054 的十六进制是 0xdeadc0de,不包含 1-9。

PHP 的 loose comparison (==) 遇到 0x 前缀的字符串时,PHP 7.x 及更早版本会将其按十六进制解析为整数。所以 "0xdeadc0de" == "3735929054"3735929054 == 3735929054true

这个技巧在 PHP 8.0+ 已被修复(hex string 不再被当作 numeric string),但 WeChall 仍运行在旧版 PHP 上。

1
2
$ python3 -c "print(0xdeadc0de)"
3735929054

提交入口在 php0818.php,POST 字段为 number(不是 answer,也不需要 CSRF token)。

0xdeadc0de