16th-day

 · 2019-8-15 · 次阅读


41.你真的会PHP吗(http://ctf5.shiyanbar.com/web/PHP/index.php)
  进入页面后,只有一个have fun.F12看一下,在网络的响应头中发现了一个Hint:6c525af4059b4fe7d8c33a.txt打开这个txt看一下发现一大串php代码,一道代码审计类题目。若果没有post设置Number就在头文件中给出hint提示并且现实hava a fun。
  接下来的:
foreach([$_POST] as $global_var) {
foreach($global_var as $key => $value) {
$value = trim($value);
is_string($value) && $req[$key] = addslashes($value);
}
}
这个是个循环遍历赋值的一个函数,先是用post方式传参给global_var里面,第二个仍然是赋值,这个函数仅用于数组,第二个是采用全局数组的方式给Key赋值并赋上键。value变量的值经过trim去掉空格和换行符。最后的代码意思是判断value是否是string类型与上key的请求值=转义后的value。这句代码不是很懂待会儿联系一起看哈。
  紧接着是:
function is_palindrome_number($number) {
$number = strval($number);
$i = 0;
$j = strlen($number) - 1;
while($i < $j) {
if($number[$i] !== $number[$j]) {
return false;
}
$i++;
$j–;
}
return true;
}
这是一个判断是否是回文的函数,$number=其字符串值,$j=number的长度减1,如果i<j,并且如果i!=j就返回false.否则是i++,j–.继续下一段代码:
if(is_numeric($_REQUEST[‘number’])){

$info=”sorry, you cann’t input a number!”;

}elseif($req[‘number’]!=strval(intval($req[‘number’]))){

 $info = "number must be equal to it's integer!! ";  

}else{

 $value1 = intval($req["number"]);
 $value2 = intval(strrev($req["number"]));  

 if($value1!=$value2){
      $info="no, this is not a palindrome number!";
 }else{

      if(is_palindrome_number($req["number"])){
          $info = "nice! {$value1} is a palindrome number!"; 
      }else{
         $info=$flag;
      }
 }

}

echo $info;
如果request方式传入的Number是数字的话就提示you can’t input a number。而如果不是数字请求的number不等于字符类型的整型Number,就提示”number must be equal to it’s integer!!”.如果这个满足了就让value1为整型的Number,value2等于整型的反转Number.但于此同时如果value1!=value2会提示这不是一个回文数字,如果它是一个会问数字就提示是一个会问数字,如果Number不是回文数字就给出flag.
  总结一下number需要满足的条件:
1.number不能是一个数字型的
2.它的值必须等于整型的它的值的字符型
3.整型的number值必须等于反转整型的它的值
4.number不能是一个回文
由上4个条件可以看出,1,2两个条件相互矛盾。3,4两个条件相互矛盾。
现在开始构造特殊,构造特别一般会想到科学记数法,这里采用0e-0%00.它满足1,2条件也满足3,4条件,这里绕过的机制是%00加入后不会被认为是整型,并且strval会忽略掉%00.由于不能是回文因而添加了-0.
这道题还有第二种解法:利用Intaval的溢出,它的最大值取决于操作系统
32 位系统最大带符号的 integer 范围是 -2147483648 到 2147483647。举例,在这样的系统上, intval(‘1000000000000’) 会返回 2147483647。64 位系统上,最大带符号的 integer 值是 9223372036854775807。通过f12可以看到服务器的操作系统是32位的因而直接构造2147483747就可以满足2,3条件再加上(%00,%20即可满足剩余条件)
在其他人的博客上发现了更简单的构造number=-0%00或-0%20都可以。
关于操作系统溢出的我试验过好像不行,不知道是哪出了问题。
  实验吧的题很明显一下提升了个档次就算是最初级的题都比较有难度需要知道大量的php函数并且理解非常清楚,对于字符型整型回文这些数字的技巧也要灵活的运用才能成功解题,自己对于这方面还有待提升。