php弱类型

Nov 8, 2017 09:55 · 184 words · 1 minute read PHP ctf

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()在没有选择第三个参数时,是一个弱类型比较, 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

tweet Share