PHP函数漏洞学习
0x00 前言
记一下php函数的一些缺陷,比如弱类型与强类型的比较,一些函数引发的安全问题,以及如何绕过等等,很有深意。
0x01 ==与===的区别
1、在PHP中===表示全等运算符,而==表示等于运算符;
2、如果等于运算符两边的值相等,则返回true,而如果全等运算符两边的值相等但类型不等,则返回false。
也就是说==仅比较两个变量的值,===不仅比较值,还会比较类型。
==弱对比 ===强类型对比
0x02 MD5、SHA1函数缺陷(Hash比较缺陷)绕过
<?php
if($_GET['name'] != $_GET['password']){
if(MD5($_GET['name']) == MD5($_GET['password'])){
echo $flag;
}
echo '?';
}
//如果是"==",可以构造出MD5值为0e开头的字符串,这样的话弱类型比较时就会认为是科学技术法,因此可以绕过。
//echo MD5('QNKCDZO');
//echo MD5('240610708');
//如果是"===",PHP自身的特性使得可以提交一个数组,而md5函数传入数组的返回值都是NULL,这样就可以绕过强类型比较,这样可以进行数组绕过。
//name[]=1&password[]=2
md5加密后0e开头的字符串
QNKCDZO
0e830400451993494058024219903391
s878926199a
0e545993274517709034328855841020
s155964671a
0e342768416822451524974117254469
s214587387a
0e848240448830537924465865611904
s214587387a
0e848240448830537924465865611904
s878926199a
0e545993274517709034328855841020
s1091221200a
0e940624217856561557816327384675
s1885207154a
0e509367213418206700842008763514
s1502113478a
0e861580163291561247404381396064
s1885207154a
0e509367213418206700842008763514
s1836677006a
0e481036490867661113260034900752
s155964671a
0e342768416822451524974117254469
s1184209335a
0e072485820392773389523109082030
s1665632922a
0e731198061491163073197128363787
s1502113478a
0e861580163291561247404381396064
s1836677006a
0e481036490867661113260034900752
s1091221200a
0e940624217856561557816327384675
s155964671a
0e342768416822451524974117254469
s1502113478a
0e861580163291561247404381396064
s155964671a
0e342768416822451524974117254469
s1665632922a
0e731198061491163073197128363787
s155964671a
0e342768416822451524974117254469
s1091221200a
0e940624217856561557816327384675
s1836677006a
0e481036490867661113260034900752
s1885207154a
0e509367213418206700842008763514
s532378020a
0e220463095855511507588041205815
s878926199a
0e545993274517709034328855841020
s1091221200a
0e940624217856561557816327384675
s214587387a
0e848240448830537924465865611904
s1502113478a
0e861580163291561247404381396064
s1091221200a
0e940624217856561557816327384675
s1665632922a
0e731198061491163073197128363787
s1885207154a
0e509367213418206700842008763514
s1836677006a
0e481036490867661113260034900752
s1665632922a
0e731198061491163073197128363787
s878926199a
0e545993274517709034328855841020
sha1加密的
sha1('aaroZmOk')
sha1('aaK1STfy')
sha1('aaO8zKZF')
sha1('aa3OFF9m')
还有MD5和双MD5以后的值都是0e开头的字符串
CbDLytmyGm2xQyaLNhWn
770hQgrBOjrcqftrlaZk
7r4lGXCH2Ksu2JNT3BYM
加解密都是0e开头的字符串
0e215962017
0x03 intval缺陷绕过
intval — 获取变量的整数值
value:要转换成 integer 的数量值
base:转化所使用的进制
intval(mixed $value, int $base = 10): int
通过使用指定的进制 base
转换(默认是十进制),返回变量 value
的 int 数值。 intval() 不能用于 object,否则会产生 E_NOTICE
错误并返回 1。
intval函数有个特性:”直到遇上数字或正负符号才开始做转换,再遇到非数字或字符串结束时(\0)结束转换”,在某些应用程序里由于对intval函数这个特性认识不够,错误的使用导致绕过一些安全判断导致安全漏洞.此外有些题目还利用intval函数四舍五入的特性来绕过判断!
数组绕过
四舍五入(小数)绕过
intval函数遇到小数点时会进行四舍五入,可以绕过一些限制。
字母绕过
intval()函数如果$base为0则$var中存在字母的话遇到字母就停止读取,但是e这个字母比较特殊,可以在PHP中不是科学计数法。所以为了绕过前面的==4476,我们就可以构造4476e123 其实不需要是e其他的字母也可以。
异或绕过
取反绕过
二进制绕过
0x04 strpos()函数绕过
strpos — 查找字符串首次出现的位置
haystack:在该字符串中进行查找。
返回值
返回 needle 存在于 haystack 字符串起始的位置(独立于 offset)。同时注意字符串位置是从0开始,而不是从1开始的。如果没找到 needle,将返回 false。
strpos(string $haystack, mixed $needle, int $offset = 0): int
数组绕过
strpos 如果传入数组,会返回NULL
换行绕过
strpos 我们可以利用换行进行绕过(%0a)
0x05 in_array函数缺陷
in_array — 检查数组中是否存在某个值
in_array 函数默认采用 宽松 比较,即不比较类型,只比较值是否相等。
needle: 待搜索的值。(如果 needle
是字符串,则比较是区分大小写的。)
haystack:带搜索的数组。
strict:如果第三个参数 strict
的值为 true 则 in_array() 函数还会检查 needle 的类型是否和 haystack
中的相同。
in_array(mixed $needle, array $haystack, bool $strict = false): bool
也就是说在 $haystack 中搜索 $needle ,如果第三个参数 $strict 的值为 TRUE ,则 in_array() 函数会进行强检查,检查 $needle 的类型是否和 $haystack 中的相同。如果找到 $haystack ,则返回 TRUE,否则返回 FALSE。
也就是说,in_array()函数检测上传文件时候,如果未将第三个参数设置为true,从而导致攻击者构造文件名绕过服务端的检测。
0x06 preg_match()函数缺陷
当被匹配的数据为数组的时候回返回false值。
0x07 Preg_replace()函数缺陷
Preg_replcae在存在/e模式的时候会产生代码执行漏洞
0x08 str_replace()函数缺陷
0x09 isset()函数缺陷
isset()函数只检查变量是否存在,不检查值。
0x10 strcmp函数缺陷
strcmp函数无法比较数组,可以使用数组绕过。
0x11 file_get_contents() 函数缺陷
file_get_contents() 函数把整个文件读入一个字符串中,如果文件不存在,则函数返回flase(0)。
0x12 is_numeric()函数缺陷
is_numeric() 函数用于检测变量是否为数字或数字字符串。
Is_numeric函数在对末尾含有%20的整数进行判断时会返回false。
0x13 ereg()函数缺陷
Ereg函数用来对字符串中指定的字符进行匹配,返回True或False值。
当字符串中存在%00的时候,ereg将不会匹配%00后面的字符串,进行截断,从而进行绕过。
0x14 Call_user_func()函数缺陷
函数将第一个参数作为调用的函数,其余参数为函数的传入参数,当两个值为可控内容时会产生命令执行漏洞。
0x15 assert()函数(php<7)
将字符串以php代码来执行。
最后收藏一个代码审计的练习的git项目:红日安全代码审计