一道代码审计题
题目链接:http://ctf5.shiyanbar.com/web/PHP/index.php
进入题目,显示have a fun! 查看源码,没什么东西。那么bp抓包看一下
有个hint,打开看到源码
foreach([$_POST] as $global_var) { foreach($global_var as $key => $value) { $value = trim($value); is_string($value) && $req[$key] = addslashes($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; } 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($_REQUEST['number']);$req['number']!=strval(intval($req['number'])函数判断是否为数字 这两句要求提交的数不能是数字包括小数
if(intval($req["number"])=intval(strrev($req["number"])))这句的要求为该数的反序列的整数值应该等于它本身的整数值即是一个回文数
is_palindrome_number($req["number"])这句要求提交的数不是一个回文数
我们可以利用intval函数的限制:那就是Intval最大的值取决于操作系统。
32位系统最大带符号的 integer 范围是 -2147483648 到 2147483647。举例,在这样的系统上, intval(‘1000000000000’) 会返回 2147483647。构造payload:url?2147483647%00绕过,在浏览器上没有反应,拿bp post
is_numeric函数在开始判断前,会先跳过所有空白字符,可是题目获取$req[‘number’]的时候明明使用trim过滤了空白字符,这时候我们可以引入\f(也就是%0c)在数字前面,来绕过最后那个is_palindrome_number函数,而对于前面的数字判断,因为intval和is_numeric都会忽略这个字符
所以我们可以另构造url?number=%00%0c121绕过