php弱类型
Nov 8, 2017 09:55 · 184 words · 1 minute read
php弱类型比较在ctf平台上很常见,这次总结了一下。但感觉还是不全,以后遇到再补吧。。
php弱类型
精华
0==任何字符串
概述
php就是一门弱类型语言。弱类型就是不需要声明变量的类型,php会根据变量的值自动把变量转换为正确的数据类型。强类型的编辑语言在使用变量前必须声明变量的数据类型。
原理
- php中有两种比较的符号\==和===
- ===在进行比较的时候会先判断两种字符串的类型是否相等,再比较。
- == 在进行比较的时候,会先将字符串的类型转换为相同,再比较。
比如在拿数字和字符串比较的时候,字符串就会被转换为数字类型,然后进行比较。
例:
1 <?php
2 var_dump("admin"==0); //true
3 var_dump("1admin"==1); //true
4 var_dump("admin1"==1) //false
5 var_dump("admin1"==0) //true
6 var_dump("0e123456"=="0e4456789"); //true
7 ?>
然而,php是如何将一个字符串转化为数值的呢,我们继续查看php手册
当一个字符串被当作一个数值来取值,其结果和类型如下:如果该字符串没有包含 ‘.’,’e’ 或 ‘E’ 并且其数字值在整型的范围之内(由 PHP_INT_MAX 所定义),该字符串将被当成 integer 来取值。其它所有情况下都被作为 float 来取值。该字符串的开始部分决定了它的值。如果该字符串以合法的数值开始,则使用该数值。否则其值为 0(零)。合法数值由可选的正负号,后面跟着一个或多个数字(可能有小数点),再跟着可选的指数部分。指数部分由 ‘e’ 或 ‘E’ 后面跟着一个或多个数字构成。
总结
如果一个字符串为 “合法数字+e+合法数字”类型,将会解释为科学计数法的浮点数
如果一个字符串为 “合法数字+ 不可解释为合法数字的字符串”类型,将会被转换为该合法数字的值,后面的字符串将会被丢弃
如果一个字符串为“不可解释为合法数字的字符串+任意”类型,则被转换为0! 为0…为0
示例1:利用转为数字后相等的漏洞
<?php
if (isset($_GET['v1']) && isset($_GET['v2'])) {
$logined = true;
$v1 = $_GET['v1'];
$v2 = $_GET['v2'];
if (!ctype_alpha($v1)) {$logined = false;}
if (!is_numeric($v2) ) {$logined = false;}
if (md5($v1) != md5($v2)) {$logined = false;}
if ($logined){
// continuue to do other things
} else {
echo "login failed"
}
}
?
示例2:strcmp函数漏洞
定义
int strcmp ( string $str1 , string $str2 )
参数 str1第一个字符串。str2第二个字符串。如果 str1 小于 str2 返回 < 0; 如果 str1 大于 str2 返回 > 0;如果两者相等,返回 0。
源码
<?php
$password="*";
$a = array();
if (strcmp($a, $password) == 0) {
echo "Right!!!login success";
exit();
} else {
echo "Wrong password..";
}
?>
结果输出 Right!!!login success。
参考(http://www.freebuf.com/articles/web/129607.html)
遇到的弱类型比较函数
strcmp()
strcmp() 函数比较一个数组和一个字符串的时候会返回NULL。
md5()
md5()比较0e开头的字符串都相等
array_search()
array_search()在没有选择第三个参数时,是一个弱类型比较, 0==任意字符串
is_array()
is_array()和 array_search()函数的问题是一样的
preg_match和preg_match_all
preg_match 和preg_match_all 函数的参数如果是数组的话则返回false,这样就可以绕过正则的过滤。
小技巧
数组
许多处理字符串的函数如果函数接收到的参数是数组的话,会返回NULL。例如strcmp,strlen,md5等,但是preg_match和preg_match_all函数的参数如果是数组的话则返回false,这样就可以绕过正则的过滤。
科学计数法
9e9