变量覆盖漏洞

**

变量覆盖漏洞

**
全局变量覆盖
1)变量如果未被初始化,且能被用户所控制,那么很可能会导致安全问题。而在PHP中, 这种情况在register_globals为ON时尤其严重。在PHP 4.2.0之后的版本中,register_globals默认由ON变为了 OFF。register_globals的意思就是注册为全局变量,所以当On的时候,传递过来的值会被直接的注册为全局变量直接使用,而Off的时候,我们需要到特定的数组里去得到它。

<?php
// 当用户合法的时候,赋值 $authorized = true
if (authenticated_user()) {
    $authorized = true;
} 
// 由于并没有事先把 $authorized 初始化为 false,
// 当 register_globals 打开时,可能通过GET auth.php?authorized=1 来定义该变量值
// 所以任何人都可以绕过身份验证
if ($authorized) {
    include "/highly/sensitive/data.php"; phperz.com
}
?>  

2)通过GLOBALS获取的变量,也可能导致变量覆盖。

<_?php
echo ,Register_globals:(int) ini_get ("register_globals") . "<br/>n;
if (ini_get(register一globals) foreach($_REQUEST as $k=>$v) unset($($k)); //此代码是禁用register_globals,如上所述,会以数组的形式访问变量。
print $a; 
print $__GET [b];
?>

比如我们有一个url:

http://www.axom/testl .php?a=l &b=2

当register_globals=on的时候,我们输入以上url,由于变量a没有被初始化,并且因为有禁用代码(此时register_globals为off)会出错。但是如果我们输入以下url:

http://www.a.com/test I .php?GL0BALS[a]=1&b=2

即使我们的register_globals为off,但是此时变量a变成了全局变量,unset函数只会销毁局部变量,而不会销毁全局变量,所以变量a成功输出没有报错。
我们要摧毁局部变量必须使用$GLOBALS。我们看以下代码:

<?php
function foo{
unset($GL0BALS[ 'bar']);//此代码的作用就是销毁全局变量bar
$bar = "something”;
} 
foo();
?>

这段代码使用了全局变量,但是当我们的register_globals=off的时候,无法覆盖到全局变量。
总的来说就是,我们能否使用全局变量取决于register_globals是否开启。
总结以上:
就是说我们在防止全局变量覆盖的时候,首先我们可以使用register_globals=off,但是用户使用全局变量GLOBALS的仍然能够突破register_globals=off的限制,要解决此问题我们可以用$GLOBALS来销毁全局变量。
**

extract()变量覆盖

**
extractO函数能将变量从数组导入当前的符号表,其函数定义如下:
int extract ( array $var_array [, int $extract_type] [, string $prefix ])
其中,第二个参数指定函数将变量导入符号表时的行为,最常见的两个值是“EXTR_OVERWRITE” 和 “EXTR—SKIP”。当值为“EXTR_OVERWRITE”时,在将变量导入符号表的过程中,如果变量名发生冲突, 则覆盖已有变量:值为“EXTR_SKIP”则表示跳过不覆盖。若第二个参数未指定,则在默认情 况下使用“ EXTR_OVERWRITE。

<?php
$auth = 0;
extract($_GET);
if ($auth == 1){
echo "private!";
}
else {
echo "public"
}
?>

当extract()函数从用户可以控制的数组中导出变量时,可能发生变量覆盖。在这个例 子里,extract() 从$_GET中导出变量,从而可以导致任意变量被覆盖。假设用户构造以下 链接:

http://www.a.com/testl.php?auth=l

一种较为安全的做法是确定register_globals = OFF后,在调用extract()时使用 EXTR_SKIP保证已有变量不会被覆盖。但extract()的来源如果能被用户控制,则仍然是一种非常糟糕的使用习惯。同时还要留意变量获取的顺序,在PHP中是由php.ini中的 variables_order所定义的顺序来获取变量的。
variables_order:
该设置描述PHP解析变量顺序,包括GET,_POST,COOKIE,_ENV ,$_SERVER 数组,
解析顺序从左到右,后解析新值覆盖旧值。默认设定为EGPCS(Environment,GET,POST,Cookie,Server)。
如果将其设为“GP”,会导致 PHP 完全忽略环境变量,cookies 和 server 变量,并用 POST 方法的变量覆盖 GET 方法的同名变量。
在这里我们实战一下 :
BUGKU代码审计之extract变量覆盖

**

遍历初始化变量

**
常见的一些以遍历的方式释放变量的代码,可能会导致变量覆盖。

$ehs =";
if($_POST && $charset != 'utf-8') {
$chs = new Chinese('UTF-8', $charset); 
foreach ($__POST as $key => $value) {
$$key = $chs->Convert($value);
}
unset($chs);
<?php
$a = 'abc';
$$a = 789;
echo $abc;
?>

简单的解释一下代码:

  $a =abc;

 $$a可以理解为先解析后边这个$a,然后在进行解析,最终解析成为$abc

  所以直接打印$abc就是一个变量,打印出来就是789

具体实战:
¥¥变量覆盖问题

**

import—request_variables 变量覆盖

**

import_request_variables()将GET、POST、Cookie中的变量导入到全局,使用这个函数只 需要简单地指定类型即可。其中第二个参数是为导入的变量添加的前缀,如果没有指定,则将 覆盖全局变量。

<?php
$auth = 'O';
import_request一variables('G');
if ($auth ~ 1){
 echo "private!";
}
else {
echo "public!"; 
}
?>

以上代码中,import_request_variablesCG’)指定导入GET请求中的变量,从而导致变量覆 盖问题。
import_request_variables — 将 GET/POST/Cookie 变量导入到全局作用域中。如果你禁止了 register_globals,但又想用到一些全局变量,那么此函数就很有用。
**

parse_str()变量覆盖

**
parse_str() 函数用于把查询字符串解析到变量中,如果没有array 参数,则由该函数设置的变量将覆盖已存在的同名变量。 极度不建议 在没有 array参数的情况下使用此函数,并且在 PHP 7.2 中将废弃不设置参数的行为。此函数没有返回值。
如果指定了 parse_str()的第二个参数,则会将query string中的变量解析后存入该数组变量 中。因此在使用parSe_str()时,应该养成指定第二个参数的好习惯。
parse_str函数导致的变量覆盖问题

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值