PHP 属于弱类型语言, PHP 不必声明该变量的数据类型,PHP 会根据变量的值自动把变量的值转换为所需的数据类型,但在这个自动转换过程中可能存在安全问题。
常见可能导致弱类型漏洞的有:1)== 2)switch() 3)in_array() 4)array_search() 5)is_number() 6)strcmp() 7)Magic Hashes
1) 比较运算符==与===
http://php.net/manual/zh/types.comparisons.php
Loose comparisons with == 松散比较 ==
Strict comparisons with === 严格比较 ===
在松散比较时,PHP会将类型进行强制转换。一个数字和一个字符串进行比较,PHP会把字符串转换成数字再进行比较。PHP转换规则:若字符串以数字开头,则取开头数字作为转换结果,若无则输出0。 两个字符串比较,如果两个都是数字形式,则同时转换为数字进行比较。
1 | $a == $b 等于 TRUE,如果类型转换后 $a 等于 $b。 |
示例1
1 | <?php |
实例-DedeCMS(20180109)任意用户密码重置
http://blog.nsfocus.net/dedecms-20180109/ DedeCMS最新版(20180109)任意用户密码修改
2) switch()
http://us1.php.net/manual/zh/control-structures.switch.php
switch/case 是松散比较(loose comparison)。当switch case是数字类型时,switch会先将其中的参数转换为int类型
示例1
1 | <?php |
实例-HDWIKI鸡肋SQL注入
https://www.secpulse.com/archives/30532.html HDWIKI鸡肋SQL注入(PHP弱类型实例)
3) in_array()
http://php.net/manual/en/function.in-array.php
in_array ( mixed $needle , array $haystack [, bool $strict = FALSE ] ) : bool
in_array 检查数组中是否存在某个值。在数组haystack中搜索needle是否存在,如果没有设置 strict为true时 则使用松散比较。
示例1
1 | <?php |
实例-免费开源相册Piwigo<= v2.7.1 SQL注入
https://www.freebuf.com/articles/web/55075.html 免费开源相册Piwigo<= v2.7.1 SQL注入漏洞分析
4) array_search()
array_search ( mixed $needle , array $haystack [, bool $strict = false ] ) : mixed
array_search — 在数组中搜索给定的值,如果成功则返回首个相应的键名,否则返回 FALSE。如果没有设置 strict为true时 则使用松散比较。
示例1
1 | <?php |
5) is_number()
is_numeric ( mixed $var ) : bool
is_numeric 检测变量是否为数字或数字字符串。如果 var 是数字和数字字符串则返回 TRUE,否则返回 FALSE。
而如果该值是0x十六进制格式,同样会返回TRUE,就可能存在二次注入等问题。
示例1
1 | <?php |
实例-phpyun注入漏洞
http://www.anquan.us/static/bugs/wooyun-2015-0122884.html
6) strcmp()
http://php.net/manual/zh/function.strcmp.php
strcmp ( string $str1 , string $str2 ) : int
strcmp 字符串比较。如果 str1 小于 str2 返回 < 0; 如果 str1 大于 str2 返回 > 0;如果两者相等,返回 0
在PHP >=5.3版本中,strcmp($_GET[‘pass’], $password) == 0,当GET请求xxx.php?pass[]=xxx 时,由于类型不符合,发生错误,但还是判断其相等 返回0
示例1
1 | <?php |
7) Magic Hashes
https://www.whitehatsec.com/blog/magic-hashes/
PHP中当利用!=或==进行比较时,会把以0e开头的值视作为科学计数法,所以无论0e后面是什么,0的多少次方还是0
所以当两个不同的密码经过哈希以后,如果其哈希值恰好都是以0e开头的,那么PHP会认为他们相同,都是0
MD5或者其他哈希算法值是以0e开头的 其实不多
示例1
1 | <?php |
实例-wordpress- cookie伪造漏洞(CVE -2014- 0166)
https://www.freebuf.com/news/67007.html
参考:
https://www.freebuf.com/articles/web/166543.html PHP弱类型引发的漏洞实例
http://vinc.top/2017/04/04/php%E5%BC%B1%E7%B1%BB%E5%9E%8B%E5%AE%89%E5%85%A8%E9%97%AE%E9%A2%98%E6%B1%87%E6%80%BB/ PHP弱类型安全问题汇总
http://blog.topsec.com.cn/?p=2137 php代码审计之弱类型引发的灾难