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]

  1. a) Boston Key Party CTF 2015 - Northeastern Univ  

查阅官方手册,

并没有我们想要的结果,考虑改变[kbd]$_GET[‘password’][/kbd]变量类型,传入参数写成[kbd]?password[]=[/kbd]即可让[kbd]$_GET['password'][/kbd]的类型为 [kbd]array[/kbd],最后传给 strcmp函数,导致其返回值为 NULL,上文提到,在 loose comparison模 式下,NULL == 0,故最终成果获取$flag值。

  1. b) 国内某CTF

该题目结合了多个 PHP 弱类型特性,如,令 aaa=1a 即可使$aaa==”1”为 false,又由于,

故还能进入 switch 语句中的 case 1 分支。

这里还要注意 array_search 函数也存在弱类型问题,

默认情况下,第三个参数$strict 为 false,故如下脚本执行结果均不为 bool(false),

存在类似问题的函数还有 in_array,

[title] 3、PHP 弱类型引发的软件漏洞  [/title]

  1. a) CVE-2017-9090

只需要让$_SESSION['captcha']['code'] === NULL,再让$_POST['captcha'] ==="",即可让 strtolower($_POST['captcha']) == strtolower($_SESSION['captcha']['code']),具体利用,只需要直接向 reg.php 发送 POST 请求,保证之前不访问验证码图片 URL 即可,  

  1. b) CVE-2017-9091

同理,

修复方案,可添加判断 isset($_SESSION['captcha']['code']) == 1 来防止绕过,

 

本文原创,作者:Galaxy,其版权均为Galaxy Lab所有。如需转载,请注明出处:http://galaxylab.pingan.com.cn/php-%e5%bc%b1%e7%b1%bb%e5%9e%8b%e5%ae%9e%e6%88%98/

抱歉,评论已关闭!