代码审计duomicms—变量覆盖漏洞
变量覆盖漏洞
什么是变量覆盖?
变量覆盖指的是可以用我们的传参值替换程序原有的变量值
如下
<?php
$a=123;
$a=1;
echo $a;
?>
怎么去寻找变量覆盖?
经常导致变量覆盖漏洞场景有:
$$使用不当,extract()函数使用不当,parse_str()函数使用不当import_request_variables()使用不当,开启了全局变量注册等。
经常引发变量覆盖漏洞的函数有:extract() parse_str() import_request_variables()
1.extract()
分析源码我们可以知道,
1、文件将get方法传输进来的值通过extrace()函数处理。
2、通过两个if语句分别判断是否存在gift变量,和变量gift的值和变量content的值是否相等。变量content的值是通过读取变量test的值获取到的。如果两个变量相等输出flag。如果不相等,输出错误。
似乎逻辑上没啥问题,但是如果我们传参了test呢?
第一开始test在php中已经定义了,但是因为extrace()函数,我传参test时相当于重新给test赋值对不对?因为php执行语句是自上而下,那我传的参数完全可以覆盖掉之前所定义的
那么当我传参gift=a&test=a,相当于test=a
那么这里是不是就直接输出flag了呢 (因为test决定,test都是我可以决定的)
####2.parse_str()
parse_str() 将查询字符串解析到变量中:
<?php
parse_str("name=zkaq&&age=60");
echo $name."<br>";
echo $age;
?>
输出了zkaq和60
那么parse_str(“name=Bill&age=60”) 相当于完成了age =‘60’
那么如果在parse_str中可以直接传参的话,那么是不是也可以覆盖变量呢。
不仅仅是函数会导致变量覆盖,有些特殊符号的特殊搭配也会引起变量覆盖漏洞,比如$$
$$ 导致的变量覆盖问题在CTF代码审计题目中经常在foreach中出现,如以下的示例代码,使用foreach来遍历数组中的值,然后再将获取到的数组键名作为变量,数组中的值作为变量的值。因此就产生了变量覆盖漏洞。请求?name=test 会将$name的值覆盖,变为test。
来,我们上一个例题:
<?php
$a = 1;
foreach(array('_COOKIE','_POST','_GET') as $_request) {
foreach($$_request as $_key=>$_value) //将键和键值分开
{$$_key=addslashes($_value);}}//addslashes,就是类似于一个魔术引号的作用
echo $a;
?>
这个代码会接受我们的GET提交、POST提交、COOKIE参数,将这个接受来的参数依次放入$_request
_value 这是个数组解析,实际上就是键值分离
正常而言_value);就变为了$a = 2 .
简单来说就是
<?php
$a = 'b';
$b = 'c';
echo $$a;
?>
输出结果等于C;
我们首先,自行搭建靶场,进行测试
我们安装好过后
我们可以使用seay代码审计工具去快速的找到危险函数,这里是变量覆盖的,所以特意自己加了一个匹配$$的规则:([^$"]|$)${?$
在系统配置的规则配置里面可以添加
打开自动审计功能,但是会存在90%以上的误报,自动审计
我们偶然发现存在weixin的文件夹,微信之前爆出过xxe漏洞,这代表这个cms也可能存在xxe,我们审计代码,果然发现具有这个函数,我们把这个漏洞复现一下
突然发现,必须要登陆,才可以传参进行XXE
通过我们的seay审计工具,我们快速的发现了一个存在变量覆盖的地方(duomiphp\common.php文件)
我们再看看能执行这个代码的先决条件,去满足这个if
isset() — 检测变量是否设置。
简单说就是
1.必须要有传参
2.键名不能有cfg_和GLOBALS 3.COOKIE传参中不能有$_k
我们发现这个login.php文件利用require_once()调用了
"…/duomiphp/common.php"文件,而且它开启了
而这个session是控制登陆用户的权限的一个参数
那么我们可以通过common.php进行一个伪造session
我们直接访问这个文件并构造这个变量
interface/comment.php?_SESSION[duomi_group_id]=1&_SESSION[duomi_admin_id]=1&_SESSION[duomi_admin_name]=admin
然后直接访问admin目录
发现已经获取管理员权限
下一篇: javascript的超集是什么