题目地址:http://ctf5.shiyanbar.com/web/PHP/index.php
抓包在header中发现提示
访问得到源码
1 <?php 2 ?3 ?4 $info = ""; ?5 $req = []; 6 $flag="xxxxxxxxxx"; 7 ?8 ini_set("display_error", false); ?9 error_reporting(0); 10 11 12 if(!isset($_POST[‘number‘])){13 ???header("hint:6c525af4059b4fe7d8c33a.txt");14 15 ???die("have a fun!!"); 16 }17 18 foreach([$_POST] as $global_var) { 19 ????foreach($global_var as $key => $value) { 20 ????????$value = trim($value); 21 ????????is_string($value) && $req[$key] = addslashes($value); 22 ????} 23 } 24 25 26 function is_palindrome_number($number) { 27 ????$number = strval($number); 28 ????$i = 0; 29 ????$j = strlen($number) - 1; 30 ????while($i < $j) { 31 ????????if($number[$i] !== $number[$j]) { 32 ????????????return false; 33 ????????} 34 ????????$i++; 35 ????????$j--; 36 ????} 37 ????return true; 38 } 39 40 41 if(is_numeric($_REQUEST[‘number‘])){42 ????43 ???$info="sorry, you cann‘t input a number!";44 45 }elseif($req[‘number‘]!=strval(intval($req[‘number‘]))){46 ??????47 ?????$info = "number must be equal to it‘s integer!! "; ?48 49 }else{50 51 ?????$value1 = intval($req["number"]);52 ?????$value2 = intval(strrev($req["number"])); ?53 54 ?????if($value1!=$value2){55 ??????????$info="no, this is not a palindrome number!";56 ?????}else{57 ??????????58 ??????????if(is_palindrome_number($req["number"])){59 ??????????????$info = "nice! {$value1} is a palindrome number!"; 60 ??????????}else{61 ?????????????$info=$flag;62 ??????????}63 ?????}64 65 }66 67 echo $info;
通读源码,总结出flag需要以下条件
1.POST提交一个number值
2.number不能提交纯数字,包括16进制(0x22aa)和科学计数法形式(2e11)
( if(is_numeric($_REQUEST[‘number‘])) )
3.对number取整再转化为字符串后要和原提交的字符串相等
( $req[‘number‘] 要等于 strval(intval($req[‘number‘]) )
4.对number取整要等于 对number逆序 后取整的值
( $value1 = intval($req["number"]); 要等于 $value2 = intval(strrev($req["number"])); )
5.原number字符串不能是回文数
(
if(is_palindrome_number($req["number"])){
$info = "nice! {$value1} is a palindrome number!";
}else{
$info=$flag;
}
回文就是正序和逆序的字符串相等
不是回文,$info才会等于$flag;,后面会输出$info。
)
2,3似乎矛盾,但可以用00字节绕过,对123\00取整后是123,而把 "123\00" 和 "123" 比较的话,两者会相等。
4,5看起来也是矛盾的,但是intval()函数有最大值的,不同系统下不同,我在本地测试范围是-2147483648 到 2147483647,所以intval(999999999999)=2147483647,那么以下等式成立:intval(2147483647)=intval(7463847412)=2147483647,而7463847412便是2147483647的逆序文本,而且2147483647不是回文数。
综上,
实验吧——你真的会PHP吗?(intval范围 php中\00的利用)
原文地址:https://www.cnblogs.com/leixiao-/p/9781135.html