Challenge2题目代码
<?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>';
}
?>
题目的逻辑
这个题目的条件比较单一,所以还是比较简单的一道题目
首先,要用get的方法传入一个time的值,要求这个time要大于60*60*24**30*2
并且小于60 * 60 * 24 * 30 * 3
5184000<time<7776000
然后sleep函数进行延时。显然,第一个条件是我们自己传入的,问题就出在,sleep延时时间太久,我们不可能等他那么久。只需要绕过sleep就可以得到flag
绕过sleep
is_numeric()支持普通数字型字符串、科学记数法型字符串、部分支持十六进制0x型字符串。而强制类型转换int,不能正确转换的类型有十六进制型字符串、科学计数法型字符串(部分)。
也就是说,当传入?time=7e6,由于int无法转科学计数法,会把它当做7处理,这样首先7e6满足 5184000<time<7776000 ,然后进入sleep延迟,在int不能转换科学计数法的条件下,延迟七秒得到flag。
考点
考察php弱类型与函数is_numeric的特性。
从逻辑上看,本题接收time参数,先使用is_numeric判断time是否为数字,再要求7776000>time>5184000,若这些都满足则sleep((int)time)。可以看到如果满足time大小要求的话则无法等待如此长的sleep时间。
我们知道is_numeric() 函数可以支持识别科学计数法与十六进制,而int不支持。那么根据php弱类型,如果是一个科学计数法形式2e10
在强制int转换后,就变成了2(当成字符串识别,截取第一个字母前的数字)。那么我们就可以构造一个处于规定大小之间的科学计数法就行了,如下?time=7e6