PHP头条
热点:

你真的会php吗?,php


今天来讨论一道php代码审计的题,这是一道实验吧的题,链接: http://ctf5.shiyanbar.com/web/PHP/index.php 。
首先我们点开链接,并且查看源代码,

发现什么都没有,这时候我们想,我们想源码可能在服务器端,我们用burpsuit抓个包,发给Reapeater。

从服务器响应的文件,我们可以发现以下对我们有用的信息。
1.服务器的系统是32位的系统。
2.响应的文件是6c525af4059b4fe7d8c33a.txt
接下来我们访问一下6c525af4059b4fe7d8c33a.txt文件,进行代码审计。

<?php


$info = ""; 
$req = [];
$flag="xxxxxxxxxx";

ini_set("display_error", false); 
error_reporting(0); 


if(!isset($_POST['number'])){
   header("hint:6c525af4059b4fe7d8c33a.txt");

   die("have a fun!!"); 
}
//遍历
foreach([$_POST] as $global_var) { 
    foreach($global_var as $key => $value) { 
        $value = trim($value); //trim() 函数移除字符串两侧的空白字符或其他预定义字符。
        is_string($value) && $req[$key] = addslashes($value); 
    } 
} 
//global $var是外部$var的同名引用或者指针。
//函数
function is_palindrome_number($number) { 
    $number = strval($number); //本函数可将数组及类之外的变量类型转换成字符串类型。
    $i = 0; 
    $j = strlen($number) - 1;//strlen() 函数返回字符串的长度 
    while($i < $j) { 
        if($number[$i] !== $number[$j]) { 
            return false; 
        } 
        $i++; 
        $j--; 
    } 
    return true; 
} 

//判断是否为数值型
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"])); //strrev() 函数反转字符串。 

     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;

经过审计我们可以发现如果我们要拿到flag,POST的number需要满足以下条件:
1.不为空,且不能是一个数值型数字,包括小数。(由is_numeric函数判断)
2.不能是一个回文数。(is_palindrome_number判断)
3.该数的反转的整数值应该和它本身的整数值相等。即:

intval($req["number"])=intval(strrev($req["number"]))

回文数就是类似于121这样的数。从上面可以看出2,3条件似乎是冲突滴!

下面给出两种解法:

1.利用intval函数溢出绕过

Intval函数获取变量整数值。
函数介绍清点这里
Intval最大的值取决于操作系统。 32 位系统最大带符号的 integer 范围是 -2147483648 到 2147483647。举例,在这样的系统上, intval(‘1000000000000’) 会返回 2147483647。64 位系统上,最大带符号的 integer 值是 9223372036854775807。

通过上面我们知道服务器的操作系统是32位的,所以我们构造2147483647就可以同时满足2,3条件。通过把空字符可以绕过is_numeric的判断(如%00,%20),所以我们构造以下poc,number=2147483647%00 和number=2147483647%20都可。

对于第一个条件,我们需要构造是让我们的poc被函数判断为非数值,但又不影响它值的构造,理所当然想到空格字符和空字符。

而经过测试我发现is_numeric函数对于空字符%00,无论是%00放在前后都可以判断为非数值,而%20空格字符只能放在数值后。所以,查看函数发现该函数对对于第一个空格字符会跳过空格字符判断,接着后面的判断!!

2.用科学计数法构造0=0

因为要求不能为回文数,但又要满足intval($req["number"])=intval(strrev($req["number"])),所以我们采用科学计数法构造poc为number=0e-0%00,这样的话我们就可以绕过。

不积硅步无以至千里,希望大家在进步的阶梯里不断前行!

www.phpzy.comtrue/php/18464.htmlTechArticle你真的会php吗?,php 今天来讨论一道php代码审计的题,这是一道实验吧的题,链接: http://ctf5.shiyanbar.com/web/PHP/index.php 。 首先我们点开链接,并且查看源代码, 发现什么都没有,这...

相关文章

    暂无相关文章

PHP之友评论

今天推荐