弱比较
在PHP语言中若字符串以数字开头,则取开头数字作为转换结果,若无则输出0
例如:
1 | 1==1mayi ##会返回true |
为了避免这种漏洞我们可以用全等“===”来进行数据的比较,比较的是变量值与类型只有都相等才会返回true。
md5()和sha1()
- md5()是不能处理数组的,md5(数组)会返回null,两个null相等绕过。sha1()也是同理。
- 同时PHP在处理哈希字符串时,会利用”!=”或”==”来对哈希值进行比较,它把每一个以”0E”开头的哈希值都解释为0,所以如果两个不同的密码经过哈希以后,其哈希值都是以”0E”开头的,那么PHP将会认为他们相同,都是0。
常见的payload有:1
2
3
4md5(s878926199a)
0e545993274517709034328855841020
md5(s155964671a)
0e342768416822451524974117254469
转换
php会自动进行转换,比如16进制,科学计数法等,有时网站对某些数字做了限制,可以考虑试试这个点绕过。
如:
1 | 0x11 == 17 ; ## 会返回true |
strcmp()
注:这一个漏洞适用于5.3之前版本的php
1 | int strcmp ( string $str1 , string $str2 ) |
实际上,当这个函数接受到了不符合的类型,这个函数将发生错误,但是在5.3之前的php中,显示了报错的警告信息后,将return NULL!
那么我们传入一个数组,它会返回NULL,而判断使用了==,而NULL==0是bool(true),这样就成功绕过。
ereg()
ereg()函数用指定的模式搜索一个字符串中指定的字符串,如果匹配成功返回true,否则,则返回false。
1 | if(isset($_GET['num'])){ |
代码分析:只有当输入数字和字母的时候,输入正确,如果输入包含符号的就会提示不正确。
漏洞利用:
- 输入123%00’(我们想要的数据也被传了进去)
注:这里的%00是需要urldecode才可以截断的,这是url终止符,且%00长度是1不是3。 - 碰到参数是数组的返回为null。
实现原理:
因为返回为null,null != FALSE,所以匹配正确
is_numeric()
函数用于检测变量是否为数字或数字字符串。如果指定的变量是数字和数字字符串则返回 TRUE,否则返回FALSE.
- 这个函数不仅能够检测十进制,同时还认为十六进制也是合法的。于是就可以构造十六进制的语句(想要执行的语句,转换为16进制传入)进行绕过此函数。可以用来绕过sql注入里的过滤
- 当有两个is_numeric判断并用and连接时,and后面的is_numeric可以绕过
如:1
2
3
4
5
6
7
8
9
10$a="123";
$b="1adf";
$c=is_numeric($a) and is_numeric($b);
var_dump(is_numeric($a)); //ture
var_dump(is_numeric($b)); //flase
var_dump($c); //$b可以不是数字,同样返回true
$test1=true and false;
$test2=false and ture;
var_dump($test1); //返回true
var_dump($test2); //返回false
switch()
当switch没有break时可以继续往下执行。
这里也有自动转换,比如$switch_bug = a,会当0执行,=1a,会当1执行……
array_search()
用到了PHP弱类型的一个特性,当一个整形和一个其他类型行比较的时候,会先把其他类型intval再比。
当检索中带入字符串,比如”sky”,会intval(‘sky’)==0,从而致使数字数组也可以查询成功