某PHP CTF题目学习

题目来源于:https://twitter.com/OctagonNetworks/status/1665408800646389761

参考如下:

1686016830415.png

源码如下:

<?php
require "flag.php";

$input = $_GEt['input'];
$input = str_replace(".", "", $input);

function check_input($value) {

if (strlen($value) > "3") {
if ($value < "1" && $value > "0.99") {
if(strlen($value) <= "4") {
return 1;
}
}
}
}

if(check_input($input)) {
print("You win! Flag is: ". $flag);
} else {
print("Wrong input!");
}
?>

在下面的评论中其实已经给出了具体的答案:?input=00\.9

首先,先看源码。主要难点在于函数check_input中,代码要求传入的值长度为4 ,但要小于字符串"1"并且大于字符串"0.99"

在 PHP 中,字符串比较是根据字符的 ASCII 值进行比较的。当比较字符串时,PHP 会逐个比较字符串中的字符,并根据 ASCII 值的大小确定它们的顺序。

ASCII 表中,数字字符的 ASCII 值是按照其对应的数值顺序排列的。因此,比较字符串 "00\9""1" 时,先比较第一个字符 "0""1",由于 "0"ASCII 值为 48,而 "1"ASCII 值为 49,所以 "0""1" 小。

另一方面,比较字符串 "00\9""0.99" 时,先比较第一个字符 "0""0",它们的 ASCII 值相同。然后比较下一个字符 "0"".",由于 "."ASCII 值为 46,而 "0"ASCII 值为 48,所以 ".""0" 大。

因此,根据字符串的比较规则,"00\9"ASCII 值上小于 "1",但大于 "0.99"

但是在查询相关资料时,发现

1686019209039.png

也就是说如下代码输出是相等的:

<?php
if ("\400" === "\000") {
echo "相等" . "<br>";
}
?>

1686019288140.png

这是因为在 PHP 中,八进制转义字符的范围是 \000\377(即 0 到 255 的八进制表示)。由于八进制转义字符 "\400" 导致了溢出,此时与"\000" 相等了,

同理"\401"\001是相等的。