过滤函数缺陷绕过
== 与 ===
- 
== 赋值,弱类型对比
 - 
=== 对比,类型也会对比
 
本地示例演示:
==的情况:
代码:
<?php
header("Content-Type:text/html;charset=utf-8");
$flag='You can get the flag!';
//1、== ===缺陷绕过 == 弱类型对比 ===还会比较类型
$a=1;
if($a==$_GET['x']){
 echo $flag;
}
?>
这种属于==的情况,在参数中输入+1 1.0 1a 这三种方式都可以输出flag
===的情况:
代码:
<?php
header("Content-Type:text/html;charset=utf-8");
$flag='You can get the flag!';
//1、== ===缺陷绕过 == 弱类型对比 ===还会比较类型
$a='1';
if($a===$_GET['y']){
 echo $flag;
}
?>
这种情况输入参数为1能获取flag
md5
md5()属于md5加密函数
因为处理hash字符串时,PHP会将每一个以 0E开头的哈希值解释为0,那么只要传入的不同字符串经过哈希以后是以 0E开头的,那么PHP会认为它们相同
基本的原理是这样的,但更严谨的字符串格式是,0e 开头,同时后面都是数字,不能包含其他字符的字符串,md5 值才会相等(== 的结果为 True,但 === 的结果为 False)
参考文章:https://www.cnblogs.com/ainsliaea/p/15126218.html
本地代码示例演示:
代码:
<?php
header("Content-Type:text/html;charset=utf-8");
$flag='You can get the flag!';
if($_GET['name'] != $_GET['password']){
    if(MD5($_GET['name']) == MD5($_GET['password'])){
        echo $flag;
    }else{
         echo '?';
    }  
}
?>
这种情况有两种方式绕过:
- 
echo MD5(‘QNKCDZO’);
echo MD5(‘240610708’);
 - 
利用数组绕过:name[]=1&password[]=2
 
intval
intval()函数的作用是获取变量的整数
本地代码示例演示:
代码:
<?php
header("Content-Type:text/html;charset=utf-8");
$flag='You can get the flag!';
$i='666';
$ii=$_GET['n'];
if(intval($ii==$i,0)){
 echo $flag;
}
?>
参数输入0x29a进行绕过

strpos
strpos()函数查找字符串在另一个字符串汇中第一次出现的位置(区分大小写)
本地代码示例演示:
代码:
<?php
header("Content-Type:text/html;charset=utf-8");
$flag='You can get the flag!';
$i='666';
$ii=$_GET['h'];
if(strpos($ii,$i,"0")){
 echo $flag;
}
?>
输入参数h=%0a666进行绕过

in_array
从数组里搜索特定词注:strict 可选,如果该参数设置未TRUE,则in_array()函数检查搜索的数据组的值类型是否相同,也就是没有true,就是相当于==
本地代码示例演示:
代码:
<?php
header("Content-Type:text/html;charset=utf-8");
$flag='You can get the flag!';
$whitelist = [1,2,3];
$page=$_GET['i'];
if (in_array($page, $whitelist)) {
 echo $flag;
}
?>

preg_match
执行匹配正则表达式可以利用数组绕过
本地代码示例演示:
代码:
<?php
header("Content-Type:text/html;charset=utf-8");
$flag='You can get the flag!';
if(isset($_GET['num'])){
	$num = $_GET['num'];
	if(preg_match("/[0-9]/", $num)){
		die("no no no!");
	}
	if(intval($num)){
		echo $flag;
	}
}
?>
利用数组进行绕过

这个报错属于代码没有处理,但不要紧,理解就行
isset() 函数用于检测变量是否已设置并且非 NULL
str_replace
过滤字符串,把字符串替换成另一个字符串存在一个问题:无法迭代循环,只能一次过滤
本地代码示例演示:
代码:
<?php
header("Content-Type:text/html;charset=utf-8");
$sql=$_GET['s'];
$sql=str_replace('select','',$sql);
echo $sql;
?>
这种常用于sql注入双写绕过

小结
- 
== 与 ===
- 不比较类型
 - 比较类型
 - md5
 
 - 
intval
取整数,进制或小数等绕过
 - 
strops
查看字符串,换行绕过
 - 
in_array
第三个参数设置安全
 - 
preg_match
- 数组绕过
 - 不带M正则表达,可用换行
 
 - 
str_replace
无递归,双写绕过
 
实践-CTFShow-PHP 特性-89 关卡
web89
题目的关键代码:
<?php
include("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;
    }
}
?>
这一关可以利用数组绕过

web90
题目的关键代码:
<?php
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);
    }
}
?>
这一关利用进制绕过

web91
题目的关键代码:
<?php
show_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';
}
>    
/^php$/im中的m是指换行,这一关利用换行绕过

web92
题目的关键代码:
<?php
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);
    }
}
?>
这一关可以利用进制绕过,输入参数num=4476.1也能绕过,两种方式都可以

web93
题目的关键代码:
<?php
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);
    }
}
?>
这一关用上一关的方式同样能绕过
web94
题目的关键代码:
<?php
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;
    }
}
?>
这一关用换行或者空格都可以绕过
?num=%0a010574 或 ?num=%20010574
这也可以使用参数浮点型绕过 num=4476.0
web95
题目的关键代码:
<?php
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;
    }
}
?>
这一关用换行或者空格都可以绕过
?num=%0a010574 或 ?num=%20010574
web96
题目的关键代码:
<?php
highlight_file(__FILE__);
if(isset($_GET['u'])){
    if($_GET['u']=='flag.php'){
        die("no no no");
    }else{
        highlight_file($_GET['u']);
    }
}
?>
这一关可以用num=./flag.php绕过
./flag.php指读取当前目录的flag.php
web97
题目的关键代码:
<?php
include("flag.php");
highlight_file(__FILE__);
if (isset($_POST['a']) and isset($_POST['b'])) {
if ($_POST['a'] != $_POST['b'])
if (md5($_POST['a']) === md5($_POST['b']))
echo $flag;
else
print 'Wrong.';
}
?>
这一关可以利用数组绕过 a[]=1&b[]=2
注意:要用post方式提交参数

免责声明:本文章涉及的知识和技能仅用于学习研究,如有用于非法途径或未被授权的真实网络环境,所造成的后果及连带责任自行承担,与本文作者无关,倡导把安全知识和技能用于正当、正规、正义的途径。