你真的会PHP吗?
首先刚进网页就是一个have fun 看了源码没有什么提示,也没有输入框,那就打开F12看看
有提示 6c525af4059b4fe7d8c33a.txt
访问 http://ctf5.shiyanbar.com/web/PHP/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); 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; } } }
这里关键的4个条件 满足了才可以flag 整理下
条件一: (第一层if)提交的number不能是数字
条件二:(第二层if) 输入的数和他整数的返回值相等
条件三:(第三层if) 需要value1和value2相等,value2是反序的value1,所以就是要求是回文数
条件四:(第四层if) 用is_palindrome_number()这个函数检测 number,需要number不是回文数
整理了下条件 。很多矛盾的地方,,题目就是让我们利用函数的漏洞去做。
1.对于is_numeric()函数,可以用%00绕过,%00可以放在开头或结尾,%20只能放在最后。 这样条件一和条件二就绕过了。
2.而三、四条件,可以很多种方法
a) intval() 处理浮点数得时候直接返回整数,所以我们直接构造 number=0.00%00
这样得话就可以满足第三个条件满足,因为0得反序也是0
第四个条件是前后每一位去对比,不相等才输出flag,因为0.00%00 从左第二位和倒数第二束是不同的,所以条件四也满足
类似这个0.00%00 得原理还有 ’-0%00‘
b)还可以使用科学计数法
number=0e00%00