前言
#知识点:
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']){ //name 和password不相等
if(MD5($_GET['name'])==MD5($_GET['password'])){//name和password的MD5加密相对
echo$flag;
}
echo'?';
}
//==
//echo MD5('QNKCDZO'); //MD5前一位相等,那么在用== 比较的时候 ,就会判断相等
//echo MD5('240610708');
//===
//name[]=1&password[]=2 // === 无法判断数组 所以name[] 和password[] 都是null
//3、intval缺陷绕过
intval() 函数通过使用指定的进制 base 转换(默认是十进制),返回变量 var 的 integer 数值。 intval() 不能用于 object,否则会产生 E_NOTICE 错误并返回 1。一般在过滤中将参数强制转化成整数(? id =1 and )
$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//八进制666
//4、对于strpos()函数,我们可以利用换行进行绕过(%0a)
strpos() f函数查找字符串在另一字符串中第一次出现的位置(区分大小写)。
$i='666';
$ii=$_GET['h'];
if(strpos($i,$ii,"0")){
echo$flag;
}
//?num=%0a666
//5、in_array第三个参数安全
in_array() 函数搜索数组中是否存在指定的值。 有的话则输出指定文本。(默认是弱类型比较)
$whitelist=[1,2,3];
$page=$_GET['i'];
if(in_array($page,$whitelist)){
echo"yes";
}
//?i=1exdad +1 1.0 (都可以绕过,因为他这么没比较类型)
//6、preg_match只能处理字符串,如果不按规定传一个字符串,通常是传一个数组进去,这样就会报错
preg_match 函数用于执行一个正则表达式匹配。//判断是否存在指定的数据
if(isset($_GET['num'])){ //判断是不是数据
$num=$_GET['num'];
if(preg_match("/[0-9]/",$num)){//判断 $num 有没有0-9 有的话输出nonono
die("no no no!");
}
if(intval($num)){//判断是不是数字型
echo$flag;
}
}
既不让你有0-9 ,又让你必须是数字型。
//?num[]=1
//7、str_replace无法迭代过滤
$sql=$_GET['s'];
$sql=str_replace('select','',$sql);//sql过滤 过滤 select
echo$sql;
//?s=sselectelect
?>
- 原理-缺陷函数-使用讲解-本地
- 实践-CTFShow-PHP特性-89关卡
== 和=== 的区别
在php中 == 判断时 当数字与字符串作比较时,系统会先将字符串转化为数字,再与数字进行比较。
1.当字符串中 以 数字开头 +字符串+数字或字符(字符串)+... 格式与数字进行 == 判断时,
会取第一次出现字符(字符串)前的数字作为转换值。
2.当字符串中 以 字符(字符串)开头 +数字+数字或字符(字符串)+... 格式与数字进行 == 判断时, 不能转换为数字,被强制转换为0 。
实践-代码审计-过滤缺陷-文件读取
str_replace
这里用str_replace 函数 过滤了"../" "./"
然后用substr函数 判断是有http (== 弱类型比较)
有的话,则输出$dir。
一种绕过思路是 用..\替代../的绝对路径
http\..\..\config\config_db.php
一种思路则是用双写绕过
....//http/.....//\config\config_db.php
in_array
in_array没设置第三个参数true 两个等于的判断 不判断类型
in_array($rate,$conf['rate_items']))
$conf['rate_items'] = array(0,1,2,3,4,5);
$rate= 1,1 and 注入语句 //