知识点总结
一: 正则1. 正则可以用数组绕过 如892. 正则 如果不是多行匹配可以用%0a绕过二: intvalintval ( mixed $var [, int $base = 10 ] ) : intNote:如果 base 是 0,通过检测 var 的格式来决定使用的进制:如果字符串包括了 "0x" (或 "0X") 的前缀,使用 16 进制 (hex);否则,如果字符串以 "0" 开始,使用 8 进制(octal);否则,将使用 10 进制 (decimal)。绕过方法主要有 科学计数法,进制转换,浮点数,还有数据类型转换的时候会自动去除空格
89 正则数组绕过
源码
<?phpinclude("flag.php");highlight_file(__FILE__);if(isset($_GET['num'])){$num = $_GET['num'];if(preg_match("/[0-9]/", $num)){die("no no no!");}if(intval($num)){echo $flag;}}
正则匹配了所有的数字,可以利用数组绕过
正则的返回
返回完整匹配次数(可能是0),或者如果发生错误返回FALSE。
数组会返回报错,且程序会正常进行
90 intval绕过
源码
<?phpinclude("flag.php");highlight_file(__FILE__);if(isset($_GET['num'])){$num = $_GET['num'];if($num==="4476"){die("no no no!");}if(intval($num,0)===4476){echo $flag;}else{echo intval($num,0);}}?>
官方文档
intval ( mixed $var [, int $base = 10 ] ) : intNote:如果 base 是 0,通过检测 var 的格式来决定使用的进制:如果字符串包括了 "0x" (或 "0X") 的前缀,使用 16 进制 (hex);否则,如果字符串以 "0" 开始,使用 8 进制(octal);否则,将使用 10 进制 (decimal)。
91 正则%0a绕过
源码
<?phpshow_source(__FILE__);include('flag.php');$a=$_GET['cmd'];if(preg_match('/^php$/im', $a)){if(preg_match('/^php$/i', $a)){echo 'hacker';}else{echo $flag;}}else{echo 'nonononono';}
这题第一个正则是不区分大小写和多行模式 第二个不是多行模式
直接传入?cmd=a%0aphp
92 科学计数法 intval绕过
源码
include("flag.php");highlight_file(__FILE__);if(isset($_GET['num'])){$num = $_GET['num'];if($num==4476){die("no no no!");}if(intval($num,0)==4476){echo $flag;}else{echo intval($num,0);}}
和前面的有点不同,前面的第一个if是和’4476’强比较第二个是经过intval转换和int 4476进行强比较
可以用4476a绕过
但是这里因为第一个是和4476弱比较,所以传入4476a是等于4476的,4476a被强制转换为整型
这里可以传入4476.1,就可以绕过第一个比较,经过invtal4476.1变为4476就ok了
但是这道题的预期其实是4476e0,因为4476e1
<?phpecho (int)'4476e2'; //447600echo "\r\n";echo intval('4476e2',0);//4476因为是字符串所以科学计数法没用,直接把e看成普通字母echo "\r\n";var_dump('4476e2'==4476);//bool:false?>
93 进制转换 intval绕过
源码
include("flag.php");highlight_file(__FILE__);if(isset($_GET['num'])){$num = $_GET['num'];if($num==4476){die("no no no!");}if(preg_match("/[a-z]/i", $num)){die("no no no!");}if(intval($num,0)==4476){echo $flag;}else{echo intval($num,0);}}
过滤了字母,上一道题的预期接4476e2就没用了,4476.1照样可以用
这里要讲的是进制绕过
传入010574,第一个if的时候很弱比较很明显不等于,第三个if判断的时候,因为字符串以0开头就是八进制会转换为八进制数字,成功绕过
94 浮点数 加intval绕过
源码
include("flag.php");highlight_file(__FILE__);if(isset($_GET['num'])){$num = $_GET['num'];if($num==="4476"){die("no no no!");}if(preg_match("/[a-z]/i", $num)){die("no no no!");}if(!strpos($num, "0")){die("no no no!");}if(intval($num,0)===4476){echo $flag;}}
过滤了开头为0的数字,而且一定要数字中有0,不然还会再第三个if中die了,直接传入4476.0
95 数据类型转换自动去除空格
源码
include("flag.php");highlight_file(__FILE__);if(isset($_GET['num'])){$num = $_GET['num'];if($num==4476){die("no no no!");}if(preg_match("/[a-z]|\./i", $num)){die("no no no!!");}if(!strpos($num, "0")){die("no no no!!!");}if(intval($num,0)===4476){echo $flag;}}
过滤了小数点,过滤了进制转换,emm没想到 看了大师傅的文章是空格加进制转换,真的没想到 010574,php在类型转换的时候会过滤掉字符串前面的空格…
