0x01 题目
<?php
show_source(__FILE__);
$flag = "xxxx";
if(isset($_GET['time'])){
if(!is_numeric($_GET['time'])){
echo 'The time must be number.';
}else if($_GET['time'] < 60 * 60 * 24 * 30 * 2){
echo 'This time is too short.';
}else if($_GET['time'] > 60 * 60 * 24 * 30 * 3){
echo 'This time is too long.';
}else{
sleep((int)$_GET['time']);
echo $flag;
}
echo '<hr>';
}
?>
0x02 解题
首先分析代码,这里GET得到time参数,进行is_numeric()判断,如果是数字,则进行大小判断,要求time参数在5184000(包括)~7776000(包括)之间,如果成立,则等待time秒,最后得到flag。
首先,这题肯定不是老老实实的输入符合条件的time数值,因为就算输对了这个等待时间也忒长了。。。那么注意到这里有个比较关键的函数是is_numeric()和后面的int强制类型转换了。
is_numeric()函数查阅php手册知道它接受一个数字或者数字型字符串,而从GET获取的参数是字符串,那么后面的强制类型转换就是字符串转换为int类型的数字。
查阅资料得到:is_numeric()支持普通数字型字符串、科学记数法型字符串、部分支持十六进制0x型字符串。而强制类型转换int,不能正确转换的类型有十六进制型字符串、科学计数法型字符串(部分)。
因此可以输入十六进制和科学计数法来进行绕过。本地测试一下:
<?php
show_source(__FILE__);
if(is_numeric($_GET['time'])){
$hhh = (int)$_GET['time'];
echo $hhh;
}else{
echo "input a number";
}
?>
经测试发现当我们输入十六进制和0e开头的科学计数法的时候都输出了0,所以应该是当字符串转换到int类型的时候,会从第一个非数字的地方进行截取,只用数字部分,所以答案就是
?time=0x4f1a00