变量覆盖漏洞原理和总结

前言

哈哈哈,还是看了很多文章感觉都没说到重点,所以就写了一篇。说到变量覆盖这个漏洞,其实就是对我们程序里面的全局变量进行了个覆盖,意思就是说通过我们前端传过来的参数来控制程序里面全局变量的值,一般要发现变量覆盖漏洞,只能是代码审计了,而且一般是出现在支付、登录等等页面里面的,这个漏洞大部分都是配合其他漏洞来进行攻击的。

正文

先说一说有哪些函数可能出现这个漏洞

extract()函数,parse_str()函数,$$,import_request_variables()想这些函数就有可能出现变量覆盖漏洞了,不急我们慢慢一个个解读过去。

一:$$导致的变量覆盖

<?
$id;
if($_GET && $f= 'aaa')
{
foreach($_GET as $falg => $value)
{
$$flag= $value;
}
echo $id;
}
?>

可以看到这个这里用到了双$$,这个是怎么造成变量覆盖的呢,其实是通过这个foreach函数来实现的和$$来配合实现的,我们想说一说这个foreach,这个函数是把我们get过的参数的建名当成变量,建值但是变量所对应的值来传递给程序的,举个例子:www.xxx.com/1.php?id=1,这里它把这个id=1传过来的了,foreach就把这个id=1的id当成变量赋值给$flag,又把1当成值赋值个$value,那么$flag=id,$value=1了,然后又把$value赋值给$$flag,这个$$flag可以看成$($falg),刚刚$flag=id了,那么$$flag就是$id了,然后就把1赋值给了$id,这样就达到了变量覆盖的目的了。

二: 全局变量覆盖

这个肯定就是要说到php的register_global,register_globals的意思是注册为全局变量,所以当等于On的时候,传递过来的值会被直接注册为全局变量而直接使用(比如:/1.php?id=1,直接把id作为全局变量了,而1就当成了id这个全局变量的值了),当等于OFF的时候,就需要到特定的数组中去得到它(意思就是不把他当成全局变量了),下面我们看看源码。

<?php
if ($a){
echo "hello!";
}
?>

可以看到他判断了$a是否存在或者是为1还是0,是的话就输出hello,如果register_globals=on的话,那只要通过get、post等传一个www.xxx.com/1.php?id=1的参数就可以把变量覆盖了,应为上面说了这个register_globals等于On的时候,直接把id作为全局变量了,而1就当成了id这个全局变量的值了,就相当是$id=1。所以会输出hello,这个代码太简单了一般是有一个get[a]或者post[a]等来接收的,这里我只是没写。

<?php  
if (ini_get('register_globals')) 
foreach($_REQUEST as $k=>$v);  
print $id;  
?> 

这个代码也是,当register_globals=ON时,再尝试控制“$a”的值www.xxx.xom/1.php?id=1的时候是不行的,应为这里我们没有事先声明这个$id我们只是对这个$id进行了输出,这个逻辑就错了,所以我们可以用一个GLOBALS[a]来覆盖全局变量,这样就成了www.xxx.xom/1.php?GLOBALS[a]=1,用这个相当于事先声明这个$id为全局变量的意思,所以就达到了覆盖了。

三:extract()变量覆盖


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

对于PHP extract() 函数从数组中把变量导入到当前的符号表中。对于数组中的每个元素,键名用于变量名,键值用于变量值。这个和前面的foreach一眼把get过来的id=1id=1的id当成变量名,1当成值了,所以我们只要传一个?id=0就可以输出word!了,当然前提条件是register_globals=ON,而且当register_globals=OFF时,在调用extract()时也会达到这个效果,所以我们要防止覆盖的话要使用EXTR_SKIP保证已有变量不会被覆盖,如下图所示。

 

四:parse_str()变量覆盖

<?php
parse_str("a=1");
echo $a; 
parse_str("b=1&c=2",$array);
print_r($array);   
?>

这个函数把查询字符串解析到变量中,如果没有array 参数,则由该函数设置的变量将覆盖已存在的同名变量,第一个parse_str意思就是把这个a=1的a当成变量,1当成值来进行1赋值如果全局有这个变量的话就会赋值,没有也会再定义一个。第二个parse_str是把这个两个变量当成了数组输出到$arry里面,可以看下运行结果

 

五:import_request_variables变量覆盖

import_request_variables 函数可以在 register_global = off 时,把 GET/POST/Cookie 变量导入全局作用域中。

<?php
$a = '0';
import_request_variables('G');
 
if($a == 1){
  echo "hello!";
}else{
  echo "word!";
}
?>

就如字面意思,就直接把输入的当变量并赋值了,比如:www.xxx.com/1.php?a=0,这里就直接把赋值给了$a,所以会输出word!,还有就是import_request_variables 函数里面的’G‘就是代表get传参,’P‘就是代表post传参。

结尾

这个漏洞,黑盒测试是几乎不可能测试的出来的,只能通过代码审计了,而且这个漏洞都要配合其他漏洞来攻击,所以有点难利用,所以在实战中不仅要审计这一个漏洞就够了,最后如果说的有误希望师傅们指出。

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值