PHP特性

一、过滤函数缺陷绕过

常见函数
==与===【==只对比值,===对比值和类型,用==,+1、1abc也是1,“2e3”==2000是true,因为2e3是科学计数法有效形式,会被正确转换为数字2000】
md5【无法对数组直接加密对比,输数组会变null;如果两个字符串都是 0e 开头且后面全是数字,PHP会把他们当作科学计数法(0 的多少次方 = 0)0e123456 == 0e999999输出true】
intval【用于获取变量和整数值。简单截断致精度丢失,非空数组返回1,空数组返回0,字符串部分解析(123abc当作123),空值当0,null当0,科学计数法截断(2e3当作2),进制转换问题(不认识0x/0b前缀,把0x1A当0),base设置为0会根据格式算进制】
strpos【寻找字符串位置(区分大小写),利用换行(%0a)绕过】
in_array【去数组里找有没有指定值。参数里有个strict,如果设置为TRUE,则函数会检查数组值的类型是否相同,也就是说设置为TRUE相当于===,不设置相当于==】
preg_match【执行正则表达式,string类型。输数组就会过滤失效】【正则匹配,/i设置不区分大小写,/m是换行匹配,/s是字符串视为单行匹配,/u是按utf-8匹配】
str_replace【字符替换。问题:无法迭代。输sselectelect,出select】

二、CTF考点与代码审计
1.第一个检测是匹配正则表达式。输入0-9都会被检测,匹配到会跳出。
第二个检测是intval。
需要第一个是false第二个是true。
preg_match碰到数组时过滤就会失效,intval对非空数组会返回1
输入:?num[]=1
image

2.第一个检测:===看有没有字符串4476
第二个检测:用intval,base设为0会自动检测进制
第一个要false第二个要true才能显示flag
可以把4476转成16或8进制输入
image

3.第一个检测:正则表达式,带大小写检测和换行检测
第二个检测:正则表达式大小写检测
第一个检测需为true,要匹配到php
第二个检测需为false,不能匹配到大小写php
输入:?cmd=%0aphp
image

4.第一个:不能被测出来是4476
第二个:需要测出来是4476
根据intval截断,可以输入4476.1
image

5.第一个:不能==4476
第二个:不能被匹配到有大小写a-z字母
第三个:要==4476
还是用4476.1

image

6.第一个:不能===4476
第二个:不能有大小写a-z
第三个:位置检测,需要为false,即结果要为0。!strpos(),那里面就要测到0的位置不能在开头。因为开头下标为0,php里0为false,非0为true。这里必须让字符串中包含一个 "0",而且这个 "0" 不能在第 0 位。
第四个:intval需要测到===4476返回true

不能用16进制,有0x开头,带字母,会被第二个if检测到
8进制是0开头,第三个检测到会是true
不能是4476.1,第三个检测要有0

输入“ 010574”,8进制,下标0的位置为空格,可以解决第三个if的检测
或者4476.0,有0并且不在第0位
image

7.第一个:不能==4476
第二个:不能匹配到大小写a-z字母和“.”
第三个:字符串里需要有0并且不在第0位
第四个:intval带进制计算。===带类型匹配

因为带“.”检测,所以不能4476.0
输入“ 010574”
image

8.用的是==,要想办法输入flag.php,但是不能被检测到
输入:./flag
image

9.判断两个值不等于,并要让md5值===
md5判断数组会直接null
*注意题中用的post
输入a[]=1&b[]=2
image

posted @ 2026-06-13 11:34  CCLluvia  阅读(10)  评论(0)    收藏  举报