想着也做了几个PHP题了,那就开这个题吧(每天做哪道真的不仅是玄学,也是心情),然而好像今天这个也没这么简单。
1、首先打开网页就是一个have fun,关于这个我也有一些了解了吧,反正主页什么都没有就看源代码然后看请求,果然在请求中找到hint。

2、按照hint打开那个txt,直接是源码。

3、从源码中找线索吧。
鉴于我是一个小白,那就从头开始看吧。一点一点看,一点一点解释。
(1)
源码:
ini_set("display_error", false);
error_reporting(0);
函数解释:
ini_set():用来设置php.ini的值,在函数执行的时候生效,脚本结束后,设置失效
error_reporting(0):关闭错误报告
(2)
源码:
if(!isset($_POST['number'])){
header("hint:6c525af4059b4fe7d8c33a.txt");
die("have a fun!!");
}
函数解释:
isset():检测变量是否设置。
① 若变量不存在则返回FALSE
② 若变量存在且其值为NULL,也返回FALSE
③ 若变量存在且值不为NULL,则返回TURE
$_POST:用于收集来自 method="post" 的表单中的值。
header() :向客户端发送原始的 HTTP 报头
die() :输出一条消息,并退出当前脚本,是exit()函数的别名。
该段函数即为若number不存在或不含有值,则向客户端发送hint报头,同时输出"have fun"并退出脚本。
(3)
源码:
foreach([$_POST] as $global_var) {
foreach($global_var as $key => $value) {
$value = trim($value);
is_string($value) && $req[$key] = addslashes($value);
}
}
函数解释:
foreach(array_name as $value){statement;}
array_name是要遍历的数组名,每次循环中,array_name数组的当前元素的值被赋给$value,并且数组内部的下标向下移一步,也就是下次循环回得到下一个元素。
foreach(array_name as $key => $value){statement;}
多了个$key,也就是除了把当前元素的值赋给$value外,当前元素的键值也会在每次循环中被赋给变量$key。键值可以是下标值,也可以是字符串。
trim() :移除字符串两侧的空白字符或其他预定义字符。
is_string() :用于检测变量是否是字符串,如果指定变量为字符串,则返回 TRUE,否则返回 FALSE。
addslashes() :返回在预定义字符之前添加反斜杠的字符串
该段的意思为post的参数的值需要是一个字符串,这样才会放入$req数组中
(4)
源码:
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;
}
函数解释:
strval():用于获取变量的字符串值
该段的意思就是判断number字符串的值是否是一个回文数,回文则false。
(5)
最后的重要源码:
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;
}
}
}
函数解释:
is_numeric() :用于检测变量是否为数字或数字字符串,如果指定的变量是数字和数字字符串则返回 TRUE,否则返回 FALSE
$_REQUEST: 用于收集 HTML 表单提交的数据。默认情况下包含了 $_GET,$_POST 和 $_COOKIE 的数组
intval() :用于获取变量的整数值。
strval() :获取变量的字符串值。
strrev() :反转字符串。
这一段的要求就是,number不能是数字,可转换成整数,不能是回文数。但是反转后的要与原来的值相同。
4、解题
(1)由上面的几个限制想到可以构造溢出,这样可以既不回文,并且反转后的值溢出后还是会返回最大值。32位机最大值2^31-1=2147483647,反转后为7463847412,但是已经溢出,因此会自动变成2147483647,构造相等。
(2)第二个思想可以直接使用-0,这也是一种溢出方式。
(3)为了不被判断为值,在后面加上%00或%20,因为strval()会忽略这两个的值。
5、使用hackerBar传参数
结果:


小结:看了这么多PHP函数,嗯,我真的不会PHP,PHP函数漏洞挺多的呀(笑哭)。
网友评论