【PHP特性-变量覆盖】函数的使用不当、配置不当、代码逻辑漏洞

举报
黑色地带(崛起) 发表于 2023/02/19 16:48:56 2023/02/19
【摘要】 【PHP特性-变量覆盖】函数的使用不当、配置不当、代码逻辑漏洞

【PHP特性-变量覆盖】函数的使用不当、配置不当、代码逻辑漏洞

 目录

一、总述

发现方法:

产生原因:

利用:

使用场景:

二、extract函数

语法:

示例:

三、parse_str函数

语法:

示例:

四、import_request_variables函数

语法:

示例:

五、配置不当

前提:

示例:

六、代码逻辑漏洞

$$导致的变量覆盖

示例:




一、总述

发现方法:

代码审计


产生原因:

函数的使用不当、配置不当、代码逻辑漏洞


利用:

通过前端传入的值去覆盖程序中的局部变量或全局变量,从而达到变量覆盖


使用场景:

$$ 使用不当

extract() 、parse_str() 函数使用不当

import_request_variables() 使用不当,开启了全局变量注册(PHP 4 >= 4.1.0, PHP 5 < 5.4.0)

……




二、extract函数

语法:

extract(array,extract_rules,prefix)

参数 描述
array 必需。规定要使用的数组。
extract_rules

可选。extract() 函数将检查每个键名是否为合法的变量名,同时也检查和符号表中已存在的变量名是否冲突。对不合法和冲突的键名的处理将根据此参数决定。

可能的值:

  • EXTR_OVERWRITE - 默认。如果有冲突,则覆盖已有的变量。
  • EXTR_SKIP - 如果有冲突,不覆盖已有的变量。
  • EXTR_PREFIX_SAME - 如果有冲突,在变量名前加上前缀 prefix
  • EXTR_PREFIX_ALL - 给所有变量名加上前缀 prefix
  • EXTR_PREFIX_INVALID - 仅在不合法或数字变量名前加上前缀 prefix
  • EXTR_IF_EXISTS - 仅在当前符号表中已有同名变量时,覆盖它们的值。其它的都不处理。
  • EXTR_PREFIX_IF_EXISTS - 仅在当前符号表中已有同名变量时,建立附加了前缀的变量名,其它的都不处理。
  • EXTR_REFS - 将变量作为引用提取。导入的变量仍然引用了数组参数的值。
prefix

可选。请注意 prefix 仅在 extract_type 的值是 EXTR_PREFIX_SAME,EXTR_PREFIX_ALL,EXTR_PREFIX_INVALID 或 EXTR_PREFIX_IF_EXISTS 时需要。如果附加了前缀后的结果不是合法的变量名,将不会导入到符号表中。

前缀和数组键名之间会自动加上一个下划线。


示例:

<?php
        $a = false;
        extract($_GET);
        if ($a) {
        echo "flag{...}";
        } else {
        echo "……";
        }
?>

extract函数将GET传入的数据转换为变量名和变量的值
输入?a=1可将$a的值变为true----->获得flag




三、parse_str函数

语法:

parse_str(string,array)

参数 描述
string 必需。规定要解析的字符串。
array 可选。规定存储变量的数组的名称。该参数指示变量将被存储到数组中。

未设置 array 参数,由该函数设置的变量将覆盖已存在的同名变量

parse_str函数的作用是解析字符串并注册成变量

在注册变量之前不会验证当前变量是否存在,直接覆盖掉已有变量

也就是把输入的字符串变成变量


示例:

<?php
        $a = false;
        parse_str($_SERVER['QUERY_STRING']);
        if ($a) {
        echo "flag{...}";
        } else {
        echo "……";
        }
?>


输入?a=1



四、import_request_variables函数

语法:

bool import_request_variables ( string $types [, string $prefix ] )

参数 描述
$types 指定需要导入的变量,可以用字母 G、P 和 C 分别表示 GET、POST 和 Cookie,这些字母不区分大小写,所以你可以使用 g 、 p 和 c 的任何组合。POST 包含了通过 POST 方法上传的文件信息。注意这些字母的顺序,当使用 gp 时,POST 变量将使用相同的名字覆盖 GET 变量。任何 GPC 以外的字母都将被忽略
$prefix 变量名的前缀,置于所有被导入到全局作用域的变量之前。所以如果你有个名为 userid 的 GET 变量,同时提供了 pref_ 作为前缀,那么你将获得一个名为 $pref_userid 的全局变量。虽然 prefix 参数是可选的,但如果不指定前缀,或者指定一个空字符串作为前缀,你将获得一个 E_NOTICE 级别的错误


PHP 4 >= 4.1.0, PHP 5 < 5.4.0


示例:

<?php
        $a = false;
        import_request_variables('G');
        if ($a) {
        echo "flag{...}";
        } else {
        echo "……";
        }
?>


排在前面的会覆盖排在后面的字符传入参数的值,若为“GP”,且GET和POST同时传入了a参数,则POST传入的a会被忽略





五、配置不当

前提:

当PHP配置register_globals=ON时,利用register_globals的特性,复现全局变量覆盖漏洞


示例:

<?php
        if ($a) {
        echo "flag{...}";
        } else {
        echo "……";
        }
?>


用户传入参数auth=1即可进入if语句块

如果在if语句前初始化$a变量,就不会触发了



六、代码逻辑漏洞

$$导致的变量覆盖

$$(可变变量)

一个变量的变量名可以动态的设置和使用

这个可变变量获取了一个普通变量的值作为这个可变变量的变量名


<?php
$a="hello";

        //赋值

$$a="everybody";

        //使a变量的值作为变量名

echo "$a ${$a}";

        //输出:hello everybody

echo "$a $hello";

        //同样输出:hello everybody
?>


示例:

<?php
        $a = false;
        foreach($_GET as $key => $value){
        $$key = $value;
        }
        if ($a) {
        echo "flag{...}";
        } else {
        echo "……";
        }
?>


通过foreach循环遍历数组(如,$_GET、$_POST等),这里将GET传入的参数注册为变量,用户输入“?auth=1”就又成功绕过了判断,获得了flag

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。