弱比较 在PHP语言中若字符串以数字开头,则取开头数字作为转换结果,若无则输出0 例如:
1 2 1==1mayi ##会返回true 0==mayi077 ##会返回ture
为了避免这种漏洞我们可以用全等“===”来进行数据的比较,比较的是变量值与类型只有都相等才会返回true。
md5()和sha1()
md5()是不能处理数组的 ,md5(数组)会返回null,两个null相等绕过。sha1()也是同理。
同时PHP在处理哈希字符串时,会利用”!=”或”==”来对哈希值进行比较,它把每一个以”0E”开头的哈希值都解释为0,所以如果两个不同的密码经过哈希以后,其哈希值都是以”0E”开头的,那么PHP将会认为他们相同,都是0。 常见的payload有:1 2 3 4 md5(s878926199a) 0e545993274517709034328855841020 md5(s155964671a) 0e342768416822451524974117254469
转换 php会自动进行转换,比如16进制,科学计数法等,有时网站对某些数字做了限制,可以考虑试试这个点绕过。 如:
1 2 3 4 0x11 == 17 ; ## 会返回true 0x11 === 17 ; ## 返回true $a=1.2E3==1200; ## 返回ture $a=1.2E3===1200; ## 返回false
strcmp() 注:这一个漏洞适用于5.3之前版本的php
1 2 3 4 5 int strcmp ( string $str1 , string $str2 ) 参数 str1第一个字符串。str2第二个字符串。 如果 str1 小于 str2 返回 < 0; 如果 str1 大于 str2 返回 >0; 如果两者相等,返回 0。
实际上,当这个函数接受到了不符合的类型,这个函数将发生错误,但是在5.3之前的php中,显示了报错的警告信息后,将return NULL ! 那么我们传入一个数组,它会返回NULL,而判断使用了==,而NULL==0是bool(true),这样就成功绕过。
ereg() ereg()函数用指定的模式搜索一个字符串中指定的字符串,如果匹配成功返回true,否则,则返回false。
1 2 3 4 5 6 7 if(isset($_GET['num'])){ if(ereg('^[a-zA-Z0-9]+$', $_GET['num']) === FALSE){ echo "请输入符合要求的"; }else{ echo "您输入的符合要求"; } }
代码分析 :只有当输入数字和字母的时候,输入正确,如果输入包含符号的就会提示不正确。 漏洞利用:
输入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,从而致使数字数组也可以查询成功