PHP 弱类型实战
1、简介
PHP 弱类型是 PHP 自身的一种特性,它能根据某个变量的上下文语境来定义其类型, 而无须开发者对变量类型显式定义或转换。例如,
PHP 会把(string)"1"转换为(int)"1",故最终执行结果为 2 。 弱类型特性在给开发者带来方便的同时也带来了问题,在比较运算方面尤为突出,如在strict comparison(===) 模式下,各类变量比较结果如下表所示,
而在应用得比较多的 loose comparison(==) 模式下,
其中,有几处比较结果值得注意,如: [kbd]NULL == 0 [/kbd] 和 [kbd]NULL == "" [/kbd],除了在对两个不同类型的变量进行比较运算时会进行隐式转换,有些情况下还会对相同类型变量进行隐式转换,如,
"0e1111" == "0e1234567" md5("240610708") == md5("QNKCDZO") sha1("aaroZmOk") == sha1("aaK1STfY")
由于上述所有 string 型变量都是以[kbd]"0e"[/kbd]开头,PHP 会将其类型隐式转换为 float 型,而,
0e1111 = 0*10^1111 = 0,0e1234567 = 0*10^1234567 = 0,
故认为
"0e1111" == "0e1234567"
[title] 2、PHP 弱类型在 CTF 中的应用 [/title]
查阅官方手册,
并没有我们想要的结果,考虑改变[kbd]$_GET[‘password’][/kbd]变量类型,传入参数写成[kbd]?password[]=[/kbd]即可让[kbd]$_GET['password'][/kbd]的类型为 [kbd]array[/kbd],最后传给 strcmp函数,导致其返回值为 NULL,上文提到,在 loose comparison模 式下,NULL == 0,故最终成果获取$flag值。
- b) 国内某CTF
该题目结合了多个 PHP 弱类型特性,如,令 aaa=1a 即可使$aaa==”1”为 false,又由于,
故还能进入 switch 语句中的 case 1 分支。
这里还要注意 array_search 函数也存在弱类型问题,
默认情况下,第三个参数$strict 为 false,故如下脚本执行结果均不为 bool(false),
存在类似问题的函数还有 in_array,
[title] 3、PHP 弱类型引发的软件漏洞 [/title]
- a) CVE-2017-9090
只需要让$_SESSION['captcha']['code'] === NULL,再让$_POST['captcha'] ==="",即可让 strtolower($_POST['captcha']) == strtolower($_SESSION['captcha']['code']),具体利用,只需要直接向 reg.php 发送 POST 请求,保证之前不访问验证码图片 URL 即可,
- b) CVE-2017-9091
同理,
修复方案,可添加判断 isset($_SESSION['captcha']['code']) == 1 来防止绕过,