https://www.freebuf.com/articles/web/166543.html
****\*本文作者:补丁君,本文属 FreeBuf 原创奖励计划,未经许可禁止转载。**
**
**我们知道PHP 是一门弱类型语言,不必向 PHP 声明该变量的数据类型,PHP 会根据变量的值,自动把变量的值转换为正确的数据类型,但在这个转换过程中就有可能引发一些安全问题。**
## 类型转换
1、会先进行类型转换,再进行对比
2、会先比较类型,如果类型不同直接返回false,参考如下
[![PHP弱类型引发的漏洞实例](https://image.3001.net/images/20180327/15221416445161.png!small)](https://image.3001.net/images/20180327/15221416445161.png)
## **注意:**
1 . 当一个字符串被当作一个数值来取值,其结果和类型如下:如果该字符串没有包含’.',’e',’E'并且其数值值在整形的范围之内,该字符串被当作int来取值。其他所有情况下都被作为float来取值,该字符串的开始部分决定了它的值,如果该字符串以合法的数值开始,则使用该数值,否则其值为0。
[![PHP弱类型引发的漏洞实例](https://image.3001.net/images/20180327/15221417688043.png!small)](https://image.3001.net/images/20180327/15221417688043.png)
2. 在进行比较运算时,如果遇到了0e这类字符串,PHP会将它解析为科学计数法。
[![PHP弱类型引发的漏洞实例](https://image.3001.net/images/20180327/15221420506541.png!small)](https://image.3001.net/images/20180327/15221420506541.png)
3. 在进行比较运算时,如果遇到了0x这类字符串,PHP会将它解析为十六进制。
[![PHP弱类型引发的漏洞实例](https://image.3001.net/images/20180327/15221421324442.png!small)](https://image.3001.net/images/20180327/15221421324442.png)
### 实例:DedeCMS(20180109)任意用户密码重置
[![PHP弱类型引发的漏洞实例](https://image.3001.net/images/20180327/15221439536788.png!small)](https://image.3001.net/images/20180327/15221439536788.png)
在找回密码时,当$dopost = safequestion时,通过传入的member\_id查询出对应id用户的安全问题和答案信息,当我们传入的问题和答案不为空,而且等于之前设置的问题和答案,就进入sn()函数。
这里如果用户设置了问题和答案,我们并不知道问题和答案是什么,就无法进入sn()函数。但是如果此用户没有设置问题和答案呢?此时系统默认问题0″,答案是空。0.、0.1、0e1、利用PHP弱类型即可绕过if判断
直接发送如下请求即可获取重置密码的链接:
[http://localhost/DedeCMS-V5.7-UTF8-SP2/member/resetpassword.php?dopost=safequestion&safequestion=0e1&safeanwser=&id=1](http://localhost/DedeCMS-V5.7-UTF8-SP2/member/resetpassword.php?dopost=safequestion&safequestion=0e1&safeanwser=&id=1)
[![PHP弱类型引发的漏洞实例](https://image.3001.net/images/20180327/15221440954951.png!small)](https://image.3001.net/images/20180327/15221440954951.png)
然后获取的重置面链接为:(只有没有设置安全问题的用户才能重置)
[http://localhost/DedeCMS-V5.7-UTF8-SP2/member/resetpassword.php?dopost=getpasswd&id=1&key=D2kIQomh](http://localhost/DedeCMS-V5.7-UTF8-SP2/member/resetpassword.php?dopost=getpasswd&id=1&key=D2kIQomh)
[![PHP弱类型引发的漏洞实例](https://image.3001.net/images/20180327/15221441465469.png!small)](https://image.3001.net/images/20180327/15221441465469.png)
## 函数松散性
### switch()
如果switch是数字类型的case的判断时,switch会将其中的参数转换为int类型。
[![PHP弱类型引发的漏洞实例](https://image.3001.net/images/20180327/15221608721016.png!small)](https://image.3001.net/images/20180327/15221608721016.png)
### [实例:HDwikiSQL注入](http://wooyun.org/bugs/wooyun-2015-089892)
**[![PHP弱类型引发的漏洞实例](https://image.3001.net/images/20180327/15221610846290.png!small)](https://image.3001.net/images/20180327/15221610846290.png)
**
实际执行的语句:
[![PHP弱类型引发的漏洞实例](https://image.3001.net/images/20180327/15221611579350.png!small)](https://image.3001.net/images/20180327/15221611579350.png)
### in\_array()
in\_array(search,array,type): 如果给定的值 search 存在于数组 array 中则返回 true(**类似于==**)。如果第三个参数设置为 true,函数只有在元素存在于数组中且数据类型与给定值相同时才返回 true(**类似于===**)。如果没有在数组中找到参数,函数返回 false。
[![PHP弱类型引发的漏洞实例](https://image.3001.net/images/20180327/15221613159048.png!small)](https://image.3001.net/images/20180327/15221613159048.png)
### [实例:Piwigo SQL注入](http://www.freebuf.com/articles/web/55075.html)
### is\_number()
is\_numeric在做判断时候,如果攻击者把payload改成十六进制0x…,is\_numeric会先对十六进制做类型判断,十六进制被判断为数字型为真,就进入了条件语句,如果再把这个代入进入sql语句进入mysql数据库,mysql数据库会对hex进行解析成字符串存入到数据库中,如果这个字段再被取出来二次利用,就可能造成二次注入漏洞。
[![PHP弱类型引发的漏洞实例](https://image.3001.net/images/20180327/15221616069445.png!small)](https://image.3001.net/images/20180327/15221616069445.png)
### [实例:PHPYun二次注入](http://wooyun.org/bugs/wooyun-2015-0122884)
[![PHP弱类型引发的漏洞实例](https://image.3001.net/images/20180327/15221623968204.png!small)](https://image.3001.net/images/20180327/15221623968204.png)
### strcmp()
strcmp(string1,string2):比较括号内的两个字符串string1和string2,当他们两个相等时,返回0;string1的大于string2时,返回>0;小于时返回<0。在5.3及以后的php版本中,当strcmp()括号内是一个数组与字符串比较时,也会返回0。
[![图片 13.png](https://image.3001.net/images/20180327/15221618243084.png!small)](https://image.3001.net/images/20180327/15221618243084.png)
### md5()
string md5 ( string $str \[, bool $raw\_output = false \] )
md5()需要是一个string类型的参数。但是当你传递一个array时,md5()不会报错,只是会无法正确地求出array的md5值,返回null,这样就会导致任意2个array的md5值都会相等。
[![PHP弱类型引发的漏洞实例](https://image.3001.net/images/20180327/15221619168753.png!small)](https://image.3001.net/images/20180327/15221619168753.png)
以上就是常见的利用PHP弱类型产生的一些安全问题,在CTF、PHP代码审计中也会遇到这种利用弱类型来绕过逻辑判断,进而引发更大问题的漏洞。希望这个小结能帮助到大家,谢谢~~
## 参考
> [http://php.net/manual/zh/types.comparisons.php](http://php.net/manual/zh/types.comparisons.php)
>
> [http://wooyun.org/bugs/wooyun-2015-089892](http://wooyun.org/bugs/wooyun-2015-089892)
>
> [http://wooyun.org/bugs/wooyun-2015-0122884](http://wooyun.org/bugs/wooyun-2015-0122884)
>
> [http://blog.nsfocus.net/dedecms-20180109/](http://blog.nsfocus.net/dedecms-20180109/)
>
> [https://blog.formsec.cn/2018/02/05/php-weak-type/](https://blog.formsec.cn/2018/02/05/php-weak-type/)
>
> [https://www.cnblogs.com/Mrsm1th/p/6745532.html](https://www.cnblogs.com/Mrsm1th/p/6745532.html)
>
> [http://www.jsdaima.com/blog/117.html](http://www.jsdaima.com/blog/117.html)
>
> [http://www.freebuf.com/articles/web/55075.html](http://www.freebuf.com/articles/web/55075.html)
**\*本文作者:补丁君,本文属 FreeBuf 原创奖励计划,未经许可禁止转载。**