变量覆盖漏洞原理和代码解析

变量覆盖漏洞的概念
变量覆盖漏洞是指攻击者使用 自定义的变量去覆盖源代码中的变量 ,从而改变代码逻辑,实现攻击目的的一种漏洞。通常来说,单独 的变量覆盖漏洞很难有利用价值,但是在与 其他应用代码或漏洞 结合后,可能会有很大的影响。
变量覆盖漏洞相关的函数
变量覆盖漏洞大多数由函数使用不当导致,经常引发变量覆盖漏洞的函数有:
extract()
parse_str()
import_request_variables()
$$( 可变变量 )
register_globals=On PHP5.4 之后正式移除此功能)
变量覆盖漏洞原理和代码解析
extract()
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 :
可选。如果 extract_rules 参数的值是 EXTR_PREFIX_SAME
EXTR_PREFIX_ALL EXTR_PREFIX_INVALID EXTR_PREFIX_IF_EXISTS ,则
prefix 是必需的。 该参数规定了前缀。前缀和数组键名之间会自动加上一个下划
线。
代码示例:
<?php
// 声明变量
$name = "jack";
// 定义一个数组
$arr = array("name" => "rose");
// 将数组转变成变量
extract($arr);
// 输出
echo $name;
parse_str()
parse_str() 函数把查询字符串解析到变量中。
注释: 如果未设置 array 参数,由该函数设置的变量将覆盖已存在的同名变量。
注释: php.ini 文件中的 magic_quotes_gpc 设置影响该函数的输出。如果已启用,那么在 parse_str()
解析之前,变量会被 addslashes() 转换。
语法: parse_str ( string , array )
参数解释:
string:必需。规定要解析的字符串。
array:可选。规定存储变量的数组名称。该参数指示变量存储到数组中。
代码示例:
<?php
parse_str("name=HSJ&age=18");
echo $name."<br>";
echo $age;
?>
<?php
parse_str("name=HSJ&age=18",$arr);
print_r($arr);
?>
变量覆盖示例:
<?php
$name = "Jack";
parse_str("name=HSJ&age=18");
echo $name;
echo "<br/>";
echo $age;
?>
<?php
$arr = array("name" => "Jack");
parse_str("name=HSJ&age=18", $arr);
print_r($arr);
?>
import_request_variables()
import_request_variables() 函数将 GET POST Cookie 变量导入到全局作用域中。 该函数在最新
版本的 PHP 中已经不支持。
import_request_variables() 函数将 GET POST Cookie 变量导入到全局作用域中。如果你禁止了
register_globals ,但又想用到一些全局变量,那么此函数就很有用。
版本要求: PHP 4 >= 4.1.0, PHP 5 < 5.4.0
语法:
bool import_request_variables ( string $types [, string $prefix ] )
参数说明:
$types :指定需要导入的变量,可以用字母 G P C 分别表示 GET POST Cookie ,这些字
母不区分大小写,所以你可以使用 g p c 的任何组合。 POST 包含了通过 POST 方法上传的文 bool import_request_variables ( string $types [, string $prefix ] ) 件信息。 注意这些字母的顺序,当使用 gp 时, POST 变量将使用相同的名字覆盖 GET 变量。任何
GPC 以外的字母都将被忽略。
$prefix : 变量名的前缀,置于所有被导入到全局作用域的变量之前。所以如果你有个名为 userid
GET 变量,同时提供了 pref_ 作为前缀,那么你将获得一个名为 $pref_userid 的全局变量。虽
prefix 参数是可选的,但如果不指定前缀,或者指定一个空字符串作为前缀,你将获得一个
E_NOTICE 级别的错误。
示例代码:
<?php
header("Content-type:text/html;charset=utf-8");
$name = "jack";
// 导入GET和POST作为变量
import_request_variables("gp");
// 输出,如果此时GET/POST中有name变量,那么此时name就会被覆盖掉
echo $name;
$$
$$ 是一种可变变量的写法,它可以使一个普通变量的值作为可变变量的名字,这种类型常常会使用遍历
的方式来释放变量的代码,最常见的就是 foreach 的遍历。
代码示例:
<?php
session_start();
$name = "rose";
// 准备全局变量名
$arr = array("_GET","_POST","_COOKIE","_SESSION");
// 遍历
foreach ($arr as $value){
foreach ($$value as $k=>$v){
$$k = $v;
}
}
echo $name;
如果 GET/POST/COOKIE/SESSION 中任意传递来 name 参数, 代码里面的 name 变量就会被覆盖。
变量覆盖防御
变量覆盖漏洞最常见的漏洞点是在做变量注册时没有验证变量是否存在,以及在赋值给变量的时候,所
以一般推荐使用原始的变量数组,如 $ GET $ POST ,或者在注册变量前一定要验证变量是否存在。
1. 使用原始变量
建议不注册变量,直接用原生的 $ GET $ POST 等数组变量进行操作,如果考虑程序可读性等原因,需要
注册个别变量,可以直接在代码中定义变量,然后再把请求中的值赋值给他们。
2. 验证变量存在
如果一定要使用前面几种方式注册变量,为了解决变量覆盖的问题,可以再注册变量前先判断变量是否
存在。如使用 extract( ) 函数则可以配置第二个参数为 EXTR_SKIP 。使用 php parse_str 函数注册变量前需
要先自行通过代码判断变量是否存在。最重要的一点,自行申明的变量一定要初始化,不然即使注册变
量代码在执行流程最前面也能覆盖掉这些未初始化的变量。
  • 22
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值