目录
//1、== ===缺陷绕过 & == 弱类型对比 ===还会比较类型
//4、对于strpos()函数,我们可以利用换行进行绕过(%0a)
CTF案例演示Ctf-web入门-php特性-89关卡-97关卡
知识点:
1、过滤函数缺陷绕过:使用各种方法绕过php一些函数的功能
2、CTF考点
详细:
==:等于
===:全等于(包括数据类型)
md5:md5加密
intval:将变量转化为整数,可以通过不同的变量实现值得相等
strpos:在php里查看字符串第一次出现的位置,可以利用换行(&0a)绕过
in_array:判断数据是否在数组里,如果第三个参数没有则无法判断数据类型
preg_match:执行正则表达式,只对字符串有效,数组无效。
str_replace:过滤代码,可以对字符串中的数据进行替换,只能过滤一次
//1、== ===缺陷绕过 & == 弱类型对比 ===还会比较类型
==:会对数据进行比较,但是不会对数据的类型进行比较,所以并不是很严谨。并且会对数据进行进行强制的转换。
举例:以下代码的结果都为true。
解释:
如果比较一个整数和字符串,则字符串会被转换为整数。如果比较两个数字字符串,则作为整数比较。
特别注意,字符串转换为整数时,是从左到右,直到遇到非数字字符为止。也就是说 '123abc456' 会被转换成 123,而不是 123456。另外字符串开始的空格会被忽略,比如 ' 234abc' 转换为 234。
<?php
var_dump(' 123fg456'==123);
var_dump('some string' == 0);
var_dump(123.0 == '123d456');
var_dump(0 == "a");
var_dump("1" == "01");
var_dump("1" == "1e0");
?>
查看下方代码就可以通过上面的方式进行绕过。 只给各位演示两种,其他的可以自己尝试。
$a=1;
$flag='墨竹';
if($a==$_GET['x']){
echo $flag;
}
===:不仅会对数据进行比较,还会对数据的类型进行比较。相对==而言非常的严谨。
<?php
$flag='mozhu';
$a='1';
if($a===$_GET['y']){
echo $flag;
}else{
echo '我是一个严谨的比较';
}
?>
//2、MD5函数缺陷绕过 ==弱对比 ===强类型对比
0e绕过==:观察下面代码,name值与password的值不能相等,但是MD5的加密值却要相等。
思路:通过0e进行绕过,如果是弱类型比较,0e开头的字符串在科学计数法中会被当做0,那么只要加密后的MD5值为0e开头,无论后面是什么数据都会当做0和0的比较,从而进行绕过。
$flag='墨竹';
if($_GET['name'] != $_GET['password']){
if(MD5($_GET['name']) == MD5($_GET['password'])){
echo $flag;
}else{
echo '?';
}
通过输入下方的账号和密码后,加密后的账号和密码比较就为0==0,可以进行有效地绕过
MD5加解密:https://cmd5.com/
md5('QNKCDZO') | md5(240610708) |
0e830400451993494058024219903391 | 0e462097431906509019562988736854 |
md5加密后为0e的有:QNKCDZO,240610708,s878926199a,s155964671a,s214587387a,s214587387a,s878926199a,s1091221200a等
数组绕过===:下方代码与==代码不同的地方就是MD5加密后的值时===比较,这就代表比较数据的是同时还比较类型。
思路:利用数组,将数组里面的值写入不一样时,肯定可以绕过第一个比较。MD5对数组的加密为null,那么无论数组的内容是什么MD5加密后都为null,这样不管类型还是值都相等。
$flag='墨竹';
if($_GET['name'] != $_GET['password']){
if(MD5($_GET['name']) ===MD5($_GET['password'])){
echo $flag;
}else{
echo '?';
}
}
绕过代码:name[]=1&password[]=2
//3、intval缺陷绕过
intval函数默认会将里面的数据转换成十进制整数,当base等于0时就根据数据的前缀进行进制转换。
0:转换为八进制 0x:转换为十六进制
$flag='mozhu';
$i='16';
$ii=$_GET['n'];
if(intval($ii==$i,$base=0)){
echo $flag;
}
那么在后续的一些判断中如果不存在$base,可以直接利用==的特性进行绕过。如:+16,16.0等等
如果存在$base只能通过进制转换绕过其他的判断。
//4、对于strpos()函数,我们可以利用换行进行绕过(%0a)
strpos:第一个参数为搜索的字符串。第二个参数为要查找的字符串。第三个参数为从哪个位置开始查找。
$flag='mozhu';
$i='love';
$ii=$_GET['h'];
if(strpos($i,$ii,"0")){
echo $flag;
}
正常输入字符串o,可以正常查找到
当利用%0a 时并没有flag,证明成功绕过。
//5、in_array第三个参数安全
in_array:第一个参数代表要在数组中搜索的值。第二个参数代表要搜索的数组。
第三个参数如果不是true就代表不会监测数据类型,就等于是==,容易绕过
如果不判断数据类型,那么1.0 +1 1e 1x等皆==1
$flag='mozhu';
$whitelist = ['1',2,3];
$page=$_GET['i'];
if (in_array($page, $whitelist,TRUE)) {
echo "yes";
}
$flag='mozhu';
$whitelist = ['1',2,3];
$page=$_GET['i'];
if (in_array($page, $whitelist)) {
echo "yes";
}
//6、preg_match
思路:只能处理字符串,如果不按规定传一个字符串,通常是传一个数组进去,这样就会报错
$flag='mozhu';
if(isset($_GET['num'])){
$num = $_GET['num'];
if(preg_match("/[0-9]/", $num)){
die("no no no!");
}
if(intval($num)){
echo $flag;
}
}
输入正常数据时被正常过滤
当输入数组进行绕过时,可以直接获取flag
//7、str_replace无法迭代过滤
str_replace:第一个参数为要被替换字符。第二个参数被替换成的数据。第三个参数为被搜索的字符串。
思路:只能过滤一次,那就可以多写点被过滤的字符
$sql=$_GET['s'];
$sql=str_replace('select','',$sql);
echo $sql;
尝试传参select1,发现结果只为1,代表select被过滤
如果参数为多个过滤字符的叠加,那么只会被过滤其中一个。
CTF案例演示Ctf-web入门-php特性-89关卡-97关卡
Ctf-web入门-php特性-89关卡
代码分析:该关难度非常容易,只有一个正则表达式进行数字过滤。
解题思路:直接利用数组绕过即可
直接利用数组获取flag,数组的内容可以任意。
Ctf-web入门-php特性-90关卡
代码分析:该关就是让num值不全等于4476,但是通过intval要全等于4476
思路:突破点就在intval这个函数,它可以将字符串直接转换为整数。当第一个参数为数字的字符串,第二个参数为数值型时,intval会将第一个参数改为整形,然后减去第二个参数。
直接输入4476.1即可,当然.2,.3都可以,看心情
Ctf-web入门-php特性-91关卡
代码分析:该关存在两个正则表示都是过滤php这个关键字,^php$代表以php开头或者结尾。i和m代表区分大小写和全局搜索。
思路:突破点肯定就在两个正则不同的地方就是m,m代表全局搜索。那么就可以利用换行,因为第一个过滤全局搜索php,所以换行没用,if就为真执行下一个正则。下一个正则没有m直接换行绕过执行else获取flag。
使用%0a换行
Ctf-web入门-php特性-92关卡
代码分析:该关和90关一样,除了使用小数外换个解题方式。可以尝试使用进制转换
思路:让num的值的八进制为4476,八进制为4476的值肯定不是4476,在intval会自动转回十进制进行比较
进制转换工具:https://c.runoob.com/front-end/58/
num=010574
Ctf-web入门-php特性-93关卡
代码分析:该关依旧可以用小数进行绕过,不过可以换的稍微高级点的。
思路:可以利用八进制数绕过==4476的判断,然后正则的判断直接忽略即可,因为参数中不存在字母,最后通过intval函数转换为十进制获取flag。
num=010574
Ctf-web入门-php特性-94关卡
代码分析:该关首先num值不能全等于4476,并且利用正则过滤了字母,所以十六进制不行。还多出了一个strpos过滤了0,导致八进制也不行。
思路:直接利用换行绕过strpos的过滤。
num=%0a010574 或者 num=%20010574
Ctf-web入门-php特性-95关卡
代码分析:该关的就比95关多了一个 . 的过滤,其他没有任何变化。
思路:与94关一样
num=%0a010574 或者 num=%20010574
Ctf-web入门-php特性-96关卡
代码分析:这关代码非常好分析,就是让u不等于flag.php,因为u就是输出的文件名,所以u必须等于flag.php的条件下才能获取flag。
思路:用 ./ 让u等于当前路径的flag.php,./ 代表当前路径,那么 ./flag.php!=flag.php
u=./flag.php
Ctf-web入门-php特性-97关卡
代码分析:该关让利用post传参,a和b的值不相等,但是MD5加密后的值相等
思路:利用数组进行绕过,因为数组的MD5值都是null
a[]=1&b[]=2
总结:
php函数讲解和CTF的例题讲到这里,有哪些不对或者出问题的地方,欢迎各位大佬留言纠错。