代码分析
<?php
@$k1=$_GET['key1'];
@$k2=$_GET['key2'];
if(@file_get_contents($k1)==="Hello hacker!"){
echo 'welcome! Hacker!<br>';
if(md5($k2)>666666*666666)
{
$flag='11111111111111111111';
@$k3=$_GET['key3'];
@$k4=$_GET['key4'];
if(intval($k3)<666)
{
if($k3==666)
{
echo 'Come on, flag is coming<br>';
if($k4>0)
{
if(intval($k3+$k4)<666)
echo $flag;
}
}
}else{
exit();
}
}else{
exit();
}
}else{
exit();
}
?>
key1的值要等于Hello hacker!,这里用php://input绕过
MD5(key2)的值要大于666666*666666,注意,如果MD5中包含英文字符,就会暂停
如下:
123456a789789123123==123456,就不能大于666666*666666,写个python脚本。最后得出结果0e306373
intval(key3)的值要小于666,并且key3==666
这里有两种思路:
1.intval()函数,会将英文字母后的数字都省略。比如1e1000==1
那么我就可以构造
6.66e2==666
intval(6.66e2)==6
2.数字比较四舍五入
当传入665.9999999时,intval(665.999999)==665
而665.9999999==666成立
key4>0,并且和key3相加后,传入intval函数后的值<666
这里就存在一个整数溢出漏洞,传入的数组键名超过PHP最大数字时,就会溢出为0
这里key4+key3,只要key4数字够大,溢出后,值为0,就满足了key4>0,intval(key4+key3)<666