#研究对象
PHP代码漏洞(代码问题)
#知识点:
1、过滤函数缺陷绕过
2、CTF 考点与代码审计
一、原理-缺陷函数-使用讲解-本地
内置函数:
大部分是比较函数(过滤时使用的函数)
(1)、==与=== :
参考:
PHP 浅谈 == 和=== 中,数字和字符串比较的问题。_php 数字==字符串-CSDN博客
a.==:只数值比较,判断不能成为唯一性
数字和字符串进行比较时,当这个字符串是一个无法转换为数字的字符串,它就会被强制转化为数字,结果总是为0?
如a=0;b='admin'——a==b——》True
而a=1;b='1admin'——b里的admin无法转换为数字所以为0,又和1组合最后b的值为1
所以a==b
b.===:数值和类型都比较,具有唯一性
(2)、md5 :
a.使用==的缺陷
代码逻辑是:当name和password收入的值不同时,进入第二个条件:name的md5加密后的数==比较passwordmd5加密后的数,如果相等,则输出flag
输入name=QNKCDZO和password=240610708
解析
QNKCDZO以MD5加密:0e830400451993494058024219903391
240610708以MD5加密:0e462097431906509019562988736854
又已知是用”==”进行的比较,所以就绕过了
b.使用===的解析:
MD5数组判断不了数组,会返回null
===唯一性比较,所以我们使用数组的方式
name[]=1&password[]=2
代码会收到两个null,故判断正确。输出flag
(3)、intval :
获取数值的整数型(默认十进制。)
如果base为0,则通过字符串的格式进行检测
输入的字符串如以0开头,则会被转换为八进制;
????????????如以0x开头,则以十六进制转换;
(4)、strpos :strpos(string,find,start)
string是被检查的字符串,find是要被搜索的字符串,start是开始检索的位置,从0开始
查找字符串第一次出现的位置,区分大小写
可以通过换行进行绕过:%0a666
%0a:表示换行
也可以在有必要的条件下使用 数组 返回null
(5)、in_array :
搜索数组中的特定值:第三个参数,可选,如果设为True,则函数检查搜索的数据与数组的值的类型是否相同(类似===)
第三个参数作为缺陷:
(6)、preg_match :
正则表达式:执行匹配数据,第一个参数:只能匹配字符串
代码逻辑:获取到一个num值,匹配num值中是否有0-9的字符,有就die并输出nonono,反之出来,进入下一个条件:num为整数即可
缺陷:有函数性质可得,第一个参数只接受字符串,所以输入一个数组即可
(7)、str_replace :Sql过滤
将第一参数,转换为第二参数值;无法迭代循环。即只能一次性过滤
缺陷:
大小写和双写
二、实践-CTFShow-PHP 特性-89 关卡
1.
由题得输入num[]=1的形式即可
2.
第一个判断不能为4476
第二个为取整之后判断需要为4476
得知intval函数的base为0,所以需要进制转换区触发flag
输入八进制:010574
输入十六进制:0x117c
3.
查看相关preg_match里的参数/^php$/im:前面内容不管,只要是内容有php,$/im:代表/i(区分大小写)、/m(是否换行匹配)
代码逻辑就是:第一个是带了/m的也就是要查是否有换行;第二个是不带的,而我们是要进else拿flag的,所以
输入cmd=%0aphp
4.
这题和上面的区别就是这里是==
所以要去输出flag的话
输出4476djakljskl——都可以主要不要进第一个if
5.
这题就是将num中有英文的进行过滤了
所以可以
输出4467.1
6.
这题加了个strpos,是寻找字符串的第一个匹配字符,而且最后一个条件中是===,故要考虑值和类型完全相等的状况,又因为,它用了preg_match和strpos,使八进制和十六进制不能用;
可以用:4476.0
?????????????? 4476.1
???????空格010574
7.
这题的preg_match多了个过滤.
所以输出 空格010574
8.
这题就是==,输入flag.php的文件,不让它等于flag.php,进else里,将输入值打印;
为了让文件能够完美的输出来,可以用路径在代替
输入:./flag.php
如果这个操作系统为windows,Linux就不行
也可以:flag.php.
9.
===类型和数值都相等,函数使MD5,所以用数组,同时还是POST接收
输入:A[]=1&b[]=2
三、实践-代码审计-过滤缺陷-文件读取
源码中的replace发现可以进行绕过
所以由于这个是个对象,去看谁把它给调用了
同时要考虑源文件中的if条件,进行访问
得知它是以图像的形式,所以正常的界面是访问不到的,因此我们使用bp
在原文件中加上echo $dir;进行安全测试
读取到网站的管理员账号和密码
补:路径中的/ \都是可以的