43

PHP弱类型安全

 5 years ago
source link: https://blog.csdn.net/m0_38015368/article/details/88774358?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

PHP 弱类型安全主要是由两部分组成:

  • 变量是弱类型,比较时会自动转换
  • PHP 内置函数对于传入参数的松散处理

比较时的自动转换

PHP 中在使用 == 比较 不同类型变量 时会存在变量转换。如:

$a = null, $b = false; # true
$a = '', $b = null;    # true

# 数字比较时,会提取字符串中的第一个数字及其相邻数字
intval('abcd') == 0;
intval('8uo89j') == 8;

# 十六进制转换
"0x1e240"=="123456"		# true
"0x1e240"==123456		# true
"0x1e240"=="1e240"		# false

# hash 比较时, 出现0e\d+ 字符串转换为科学计数法后相同
"0e132456789" == "0e7124511451155" # true
"0e123456abc" == "0e1dddada"	   # false
"0e1abc" == "0"                    # true

代码中应该避免类似如下情况:

if(intval($a) > 1000) {
    mysql_query("select * from news where id=".$a)
}
# 如果 a = 1001 union select...

内置函数的参数的松散性

内置函数的松散性说的是: 调用函数时传递给函数的参数是函数不接受的数据类型。

md5() 函数的定义是: string md5 (string $str [, bool $raw_output = false ] ) md5() 函数 中的需要是一个string类型的参数。但是当传递一个 array 时, md5() 函数不会报错,但会无法正确地求出 array 的 md5 值,这样就会导致任意 2 个 array 的 md5 值都会相等。也可以使得求出的md5 值为0e\d+ 形式

md5(array('a', 'b', c)) == null         # true
md5(array('a', 'b') == md5(array(1,2,3) # true
md5('240610708') == md5('QNKCDZO')      # true

strcmp()

strcmp() 函数的定义是 int strcmp ( string $str1 , string $str2 ) ,如果 str1 小于 str2 返回 < 0; 如果 str1 大于 str2 返回 > 0;如果两者相等,返回 0。但当传入非字符串类型的数据的时,函数将发生错误 并返回0

<?php
    $password = "***************";
    if(isset($_GET['password'])){
        if (strcmp($_POST['password'], $password) == 0) {
            echo "Right!!!login success";
        } else {
            echo "Wrong password..";
        }
    }
?>

# 传入 “password[]=” 即可。

注:仅适用于 5.3 之前 PHP 版本

switch()

如果 switch 是数字类型的 case 的判断时, switch 将会其中的参数转换为 int 类型。如:

$i ="2abc";
switch ($i) {
case 0:
case 1:
case 2:
    echo "i is less than 3 but not negative";
    break;
case 3:
    echo "i is 3";
}

# 会输出 i is less than 3 but not negative

in_array()

in_array() 的定义是 bool in_array ( mixed $needle , array $haystack [, bool $strict = FALSE ] ) ,如果strict参数没有提供,那么 in_array 就会使用松散比较来判断 $needle 是否在 $haystack 中。当 $strict 的值为 true 时, in_array() 会比较 $needls 的类型和 $haystack 中的类型是否相同。如下:

$array = [0, 1, 2, '3'];
in_array('abc', $array); # true
in_array('1bc', $array); # true

array_search 函数有类似问题。

# SKCTF
<?php
if(isset($_GET['v1']) && isset($_GET['v2']) && isset($_GET['v3'])){
    $v1 = $_GET['v1'];
    $v2 = $_GET['v2'];
    $v3 = $_GET['v3'];
    if($v1 != $v2 && md5($v1) == md5($v2)){
        if(!strcmp($v3, $flag)){
            echo $flag;
        }
    }
}
?>

有两种思路,解决 md5($v1) == md5($v2) :

  • $v1$v2 md5 操作之后是 0e\d+ 形式
  • $v1$v2 是数组。

因此 payload:

?v1=s878926199a&v2=s155964671a&v3[]=
?v1[]=1&v2[]=2&v3[]=

参考:


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK