PHP代码审计(绕过过滤的空白字符)

讨论一道代码审计题
PHP代码审计(绕过过滤的空白字符)_第1张图片

这里打开网页并查看源代码并没有发现有用的信息

PHP代码审计(绕过过滤的空白字符)_第2张图片

查看他的HTTP头发现hint里有26966dc52e85af40f59b4fe73d8c323a.txt这个文件

打开获得源代码



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

ini_set("display_error", false); //为一个配置选项设置值
error_reporting(0); //关闭所有PHP错误报告

if(!isset($_GET['number'])){
   header("hint:26966dc52e85af40f59b4fe73d8c323a.txt"); //HTTP头显示hint 26966dc52e85af40f59b4fe73d8c323a.txt

   die("have a fun!!"); //die — 等同于 exit()

}

foreach([$_GET, $_POST] as $global_var) {  //foreach 语法结构提供了遍历数组的简单方式 
    foreach($global_var as $key => $value) { 
        $value = trim($value);  //trim — 去除字符串首尾处的空白字符(或者其他字符)
        is_string($value) && $req[$key] = addslashes($value); // is_string — 检测变量是否是字符串,addslashes — 使用反斜线引用字符串
    } 
} 


function is_palindrome_number($number) { 
    $number = strval($number); //strval — 获取变量的字符串值
    $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'])) //is_numeric — 检测变量是否为数字或数字字符串 
{

   $info="sorry, you cann't input a number!";

}
elseif($req['number']!=strval(intval($req['number']))) //intval — 获取变量的整数值
{

     $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;

经过分析提交的数需要满足三个条件才能拿到flag:

1.is_numeric($_REQUEST['number'])$req['number']!=strval(intval($req['number'])is_numeric函数判断是否为数字 这两句要求提交的数不能是数字包括小数

2.if(intval($req["number"])!=$intval(strrev($req["number"])))这句的要求为该数的反转的整数值应该等于它本身的整数值即是一个回文数

3.is_palindrome_number($req["number"]))这句要求提交的数不是一个回文数

从要求的条件我们可以构造一个绕过第一个条件和第三个条件即可

is_numeric函数在开始判断前,会先跳过所有空白字符可是题目获取$req[‘number’]的时候明明使用trim过滤了空白字符这时候我们可以引入\f(也就是%0c)在数字前面,来绕过最后那个is_palindrome_number函数,而对于前面的数字判断,因为intval和is_numeric都会忽略这个字符,所以不会影响。

所以我们构造payload=URL?%00%0c131即可绕过上面的条件获得flag

你可能感兴趣的:(PHP代码审计(绕过过滤的空白字符))