Galaxy Lab

focus on information security

PHP 弱类型实战

1、简介  

PHP 弱类型是 PHP 自身的一种特性,它能根据某个变量的上下文语境来定义其类型,  而无须开发者对变量类型显式定义或转换。例如,

《PHP 弱类型实战》

PHP 会把(string)"1"转换为(int)"1",故最终执行结果为 2 。 弱类型特性在给开发者带来方便的同时也带来了问题,在比较运算方面尤为突出,如在 strict comparison(===) 模式下,各类变量比较结果如下表所示,

《PHP 弱类型实战》

而在应用得比较多的 loose comparison(==) 模式下,

《PHP 弱类型实战》

其中,有几处比较结果值得注意,如: NULL == 0  NULL == ""  ,除了在对两个不同类型的变量进行比较运算时会进行隐式转换,有些情况下还会对相同类型变量进行隐式转换,如,

"0e1111" == "0e1234567" 

md5("240610708") == md5("QNKCDZO")  

sha1("aaroZmOk") == sha1("aaK1STfY")

由于上述所有 string 型变量都是以"0e"开头,PHP 会将其类型隐式转换为 float 型,而,

0e1111 = 0*10^1111 = 0,0e1234567 = 0*10^1234567 = 0,

故认为

"0e1111" == "0e1234567"

2、PHP 弱类型在 CTF 中的应用  

  1. a) Boston Key Party CTF 2015 – Northeastern Univ  《PHP 弱类型实战》

查阅官方手册,

《PHP 弱类型实战》

《PHP 弱类型实战》

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

  1. b) 国内某CTF

《PHP 弱类型实战》

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

《PHP 弱类型实战》

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

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

《PHP 弱类型实战》《PHP 弱类型实战》《PHP 弱类型实战》

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

《PHP 弱类型实战》 《PHP 弱类型实战》

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

《PHP 弱类型实战》《PHP 弱类型实战》

3、PHP 弱类型引发的软件漏洞  

  1. a) CVE-2017-9090

《PHP 弱类型实战》《PHP 弱类型实战》

只需要让$_SESSION[‘captcha’][‘code’] === NULL,再让$_POST[‘captcha’] ===””,即可让 strtolower($_POST[‘captcha’]) == strtolower($_SESSION[‘captcha’][‘code’]),具体利用,只需要直接向 reg.php 发送 POST 请求,保证之前不访问验证码图片 URL 即可,  《PHP 弱类型实战》

  1. b) CVE-2017-9091

《PHP 弱类型实战》 《PHP 弱类型实战》

同理,

《PHP 弱类型实战》

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

《PHP 弱类型实战》