php

php,第1张

<?php $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; } } }

正好代码的注释比较多,一句一句审计一下

代码审计

!isset如果不存在GET请求的number值,就在返回包中的header添加hint 代码结束,返回have_fun

foreach将传入的GET和POST请求遍历赋值给$global_var

然后将$global_var的值变为键值对应的形式,有点类似于python中的字典?

trim($value) 去除字符串首尾处的空白字符(或者其他字符)

is_string检查value是否为字符串,&&,如果是字符串的话就通过addslashes给字符串加反斜线

这一步相当于把传入的数据清洗了一遍

is_palindrome_number验证回文数字的意思

如果不是回文的话,直接返回false

判断: 1.传入的number如果是数字=>返回sorry, you cann‘t input a number! 2.传入的number如果不能被自身整除,返回number must be equal to it‘s integer!!

也就是说,传入的number不但要求不是数字,还要求它本身能被自己整除

感觉是个悖论,不是么

判断: 1.要求这个字符串是自己本身的反转

2.要求传入的数值是回文

解题

要求:

1.条件is_numeric($_REQUEST[‘number‘])为假,这个绕过的方法很多使用%00开头就行,也可以再POST一个number参数把GET中的覆盖掉也可以,所以这一步很简单。 2.要求 $req[‘number‘]==strval(intval($req[‘number‘])) 3.要求intval($req[‘number‘]) == intval(strrev($req[‘number‘])) 4.is_palindrome_number()返回False,这个条件只要在一个回文数比如191前面加一个字符即可实现得到flag

函数对空白字符的特性 is_numeric函数在开始判断前,会先跳过所有空白字符。

也就是说,is_numeirc(” \r\n \t 1.2″)是会返回true的。同理,intval(” \r\n \t 12″),也会正常返回12。

可以引入\f(也就是%0c)在数字前面,来绕过最后那个is_palindrome_number函数,而对于前面的数字判断,因为intval和is_numeric都会忽略这个字符(因为\f也是空白字符),所以不会影响。

payload:

%00%0c191

php_bugs学习 02 绕过过滤的空白字符

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/1006650.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-22
下一篇 2022-05-22

发表评论

登录后才能评论

评论列表(0条)

保存