php之变量覆盖漏洞讲解
1.变量没有初始化的问题(1):
wooyun连接1:[link href="WooYun: PHPCMS V9 member表内容随意修改漏洞"]tenzy[/link]
$updateinfo['password'] = $newpassword;里面的数组没有初始化类似这样的赋值,我们在挖洞的时候搜索类似updateinfo这样的关键字看看
是否初始化,如果没有。。。且register_global=On支持
可以提交 updateinfo[amount]这样的数组随意修改自己的余额、点数、会员组、VIP等一切存放在member表的信息.
修复:$updateinfo = array();
变量没有初始化的问题(2):
wooyun连接2:[link href="WooYun: Stcms的一个sql注射"]Zvall[/link]
里面说明了绕过程序的防御,这个是导致注入的一个因素. 更多因素是因为where变量没有初始化! case 'list':
$totalNum = $mysql->numTable("member", $where);
Where 没初始化 导致可执行任意sql语句 http://localhost/stcms_html/member/u.php?action=list&where={sql}
修复:在类调用前加上$where='';
我们在挖洞的时候搜索类似where这样的关键字看,看看是否初始化.
变量没有初始化的问题(3):
wooyun连接3: [link href="WooYun: joomla变量覆盖导致注册提权漏洞"]牛奶坦克[/link]
// 这个地方获取用户注册信息,POST进来的jform数组,但是没有详细指定
$requestData = JRequest::getVar('jform', array(), 'post', 'array');
$data = (array)$this->getData();
// 遍历出注册信息
foreach ($temp as $k => $v) {
$data[$k] = $v;
}
看似没问题的可是二维数组的特性可以覆盖住:
jfrom[groups][]=7,利用foreach的问题覆盖掉groups数组,变成7(Administrator)。
修复:像wooyun连接1那样$updateinfo['password'] = $newpassword类似这样赋值。 或者检查数组是否为二维。
2.核心代码配置问题引发变量覆盖:
Dedecms:例子(1):
一. 了解PHP超级全局变量
下面是PHP的超级全局变量,可以了解一个特性,全是数组。
$GLOBALS, 所有全局变量数组
$_SERVER, 服务器环境变量数组
$_GET,通过GET方法传递给脚本的变量数组
$_POST, 通过POST方法传递给脚本的变量数组
$_COOKIE,cookie变量数组
$_REQUEST,所有用户输入的变量数组,包括$_GET, $_POST和$_COOKIE所包含的输入内容
$_FILES,与文件上传相关得变量数组
$_ENV,环境变量数组
$_SESSION,会话变量数组
二:理解$_GET变量
可以写个PHP来看看: <?php
var_dump($_GET);
?>
访问
http://www.xxx.com /test.php?key=value
得到
array(1) { ["key"]=> string(5) "value" }
OK,看到这里应该明白了,$_GET就是个数组,我们用GET方法可以传一个数组。
再访问
http://www.xxx.com /test.php?key[arr1]=value
得到
array(1) { ["key"]=> array(1) { ["arr1"]=> string(5) "value" } }
我们通过GET方法传入了一个嵌套数组。
到这里其实问题就出来了,很多PHP安全资料都没提过GET传嵌套数组的这个特性,偶尔在几个exploit里看到 - -!
三. 深入跟进DEDECMS全局变量注册漏洞
真正理解了$_GET变量后,我们来深入跟进这个漏洞产生的真正原因,模拟一下漏洞的全过程:
提交一个嵌套数组:
http://www.xxxx.com /test.php?_POST[GLOBALS][cfg_dbname]=X
array(1) { ["_POST"]=> array(1) { ["GLOBALS"]=>
array(1) { ["cfg_dbname"]=> string(1) "X" } } }
假如数据传入了DEDECMS程序,在第一层过滤,DEDECMS会检查$_REQUEST里有没有全局变量的关键字,但我们的KEY
是_POST且是个数组,所以轻松绕过。
foreach($_REQUEST as $_k=>$_v)
{
if( strlen($_k)>0 && eregi('^(cfg_|GLOBALS)',$_k) )
{
exit('Request var not allow!');
}
}
接着进入真正的注册变量流程,按顺序是先从$_GET变量注册的,我们的KEY是(_POST),第一轮遍历$_GET成功注册
了变量$_POST,第二轮遍历$_POST成功注册了变量$GLOBALS !
foreach(Array('_GET','_POST','_COOKIE') as $_request)
{
foreach($$_request as $_k => $_v) ${$_k} = _RunMagicQuotes($_v);
}
到这里漏洞的原因就清楚了,程序通过$_GET注册了$_POST,通过$_POST注册了$GLOBALS!
四. 领悟漏洞后的修补
完全领悟这个漏洞后,就会知道怎么修补了。
1. 可以看看DISCUZ是怎么做的,当发现KEY的第一个字符存在_就不注册变量。
foreach(array('_COOKIE', '_POST', '_GET') as $_request) {
foreach($$_request as $_key => $_value) {
$_key{0} != '_' && $$_key = daddslashes($_value);
}
}
2. DEDECMS可以用下面的方法临时修补,当遍历$_POST注册变量,发现变量名存在GLOBALS就会阻止注册变量。
foreach(Array('_GET','_POST','_COOKIE') as $_request)
{
foreach($$_request as $_k => $_v) {
if( strlen($_k)>0 && eregi('^(cfg_|GLOBALS)',$_k) ){
exit('Request var not allow!');
}
${$_k} = _RunMagicQuotes($_v);
}
}
例子exp:http://www.xx.com/织梦网站后台/login.php?dopost=login&validate=dcug&userid=账号&pwd=密码& _POST[GLOBALS]
[cfg_dbhost]=MYSQL外链IP&_POST[GLOBALS] [cfg_dbuser]=MYSQL的账号&_POST[GLOBALS][cfg_dbpwd]=MYSQL的密码& _POST[GLOBALS]
[cfg_dbname]=自己的dedecms的数据库
Dedecms:例子(2): 突破官网补丁(鸡助)
0x5sec
为什么超全局变量$_REQUEST没有读取到$_COOKIE的参数呢?这个是php 5.3以后php.ini默认设置
request_order = "GP",所以你懂的!如果你修改request_order = "GPC",$_REQUEST应该就可以接受到参数了!
所以如果php是大于5.3的,变量覆盖漏洞应该可以再次利用!
CheckRequest($_REQUEST); //这里检查变量是否合法 漏洞缺陷!$_COOKIE的参数根本不鸟他。。。
更多连接:https://forum.90sec.org/thread-2476-1-1.html
https://forum.90sec.org/thread-2468-1-1.html
3.Yaseng php变量覆盖实例:
Yaseng介绍得很详细了,各种突破.
对于Dedecms例子2中:有部分人说& _POST[0xHEX 16进制][cfg_dbhost] //GLOBALS这样能绕过? 本人测试多次不成功,可能是某些问题,也可能
是假的.
原文地址:http://zone.wooyun.org/content/1872
php之变量覆盖漏洞讲解的更多相关文章
- ctf变量覆盖漏洞:
1.变量覆盖: ①:针对extract函数的变量覆盖漏洞: <?php @error_reporting(E_ALL^E_NOTICE); require('config.php'); if($ ...
- PHP代码审计笔记--变量覆盖漏洞
变量覆盖指的是用我们自定义的参数值替换程序原有的变量值,一般变量覆盖漏洞需要结合程序的其它功能来实现完整的攻击. 经常导致变量覆盖漏洞场景有:$$,extract()函数,parse_str()函数, ...
- 变量覆盖漏洞学习及在webshell中的运用
一.发生条件: 函数使用不当($$.extract().parse_str().import_request_variables()等) 开启全局变量 二.基础了解: 1.$$定义 $$代表可变变量, ...
- 7. 由一道ctf学习变量覆盖漏洞
0×00 背景 近期在研究学习变量覆盖漏洞的问题,于是就把之前学习的和近期看到的CTF题目中有关变量覆盖的题目结合下进一步研究. 通常将可以用自定义的参数值替换原有变量值的情况称为变量覆盖漏洞.经常导 ...
- Web安全之变量覆盖漏洞
通常将可以用自定义的参数值替换原有变量值的情况称为变量覆盖漏洞.经常导致变量覆盖漏洞场景有:$$使用不当,extract()函数使用不当,parse_str()函数使用不当,import_reques ...
- 代码审计-MetInfo CMS变量覆盖漏洞
0x01 代码分析 安装好后是这样的 漏洞文件地址\include\common.inc.php 首先是在这个文件发现存在变量覆盖的漏洞 foreach(array('_COOKIE', '_POST ...
- CTF——代码审计之变量覆盖漏洞writeup【2】
题目: 基础: 所需基础知识见变量覆盖漏洞[1] 分析: 现在的$a=’hi’,而下面的函数需满足$a=’jaivy’才可以输出flag,那么需要做的事就是想办法覆盖掉$a原来的值. 那么出现的提示 ...
- 2020/2/1 PHP代码审计之变量覆盖漏洞
0x00 变量覆盖简介 变量覆盖是指变量未被初始化,我们自定义的参数值可以替换程序原有的变量值. 0x01 漏洞危害 通常结合程序的其他漏洞实现完整的攻击,比如文件上传页面,覆盖掉原来白名单的列表,导 ...
- PHP变量覆盖漏洞小结
前言 变量覆盖漏洞是需要我们需要值得注意的一个漏洞,下面就对变量覆盖漏洞进行一个小总结. 变量覆盖概述 变量覆盖指的是可以用我们自定义的参数值替换程序原有的变量值,通常需要结合程序的其他功能来实现完整 ...
随机推荐
- [Leetcode Week5]Word Ladder II
Word Ladder II 题解 原创文章,拒绝转载 题目来源:https://leetcode.com/problems/word-ladder-ii/description/ Descripti ...
- glib windows下编译
记录的比较粗糙,但是绝对可行的 一些小的瑕疵以后再解决吧 (android版本的过几天再贴,移植到android已经通过) msys+mingw包下载: http://sourceforge.net/ ...
- 开源的zip_unzip库
zip/unzip源码交叉编译 http://blog.chinaunix.net/uid-20288609-id-10016.html zlib 1.2.11 http://www.zlib.net ...
- 解决:org.apache.tomcat.jni.Error: 70023: This function has not been implemented on this platform
centos7.3 启动tomcat 出现错误: 八月 08, 2017 4:58:47 下午 org.apache.catalina.core.StandardEngine startInterna ...
- Ubuntu16.04 PPA方式安装JDK1.8
一.删除OpenJDK: sudo apt-get purge openjdk* 二.添加PPA: root@ubuntu:~# add-apt-repository ppa:webupd8tea ...
- OC学习——OC中的@protocol(@required、@optional)、代理设计模式
一.什么是协议? 1.协议声明了可以被任何类实现的方法 2.协议不是类,它是定义了一个其他对象可以实现的接口 3.如果在某个类中实现了协议中的某个方法,也就是这个类实现了那个协议. 4.协 ...
- k8s资源应用的自由伸缩Scale(up/down)
伸缩(Scale Up/Down)是指在线增加或减少 Pod 的副本数. 1.增加副本 Deployment nginx-deployment初始是两个副本. [root@k8s-master k ...
- SQLAlchemy技术文档(中文版)-下
10.建立联系(外键) 是时候考虑怎样映射和查询一个和Users表关联的第二张表了.假设我们系统的用户可以存储任意数量的email地址.我们需要定义一个新表Address与User相关联. from ...
- mysql数据库设计之三范式
第一范式: 第二范式: 正解: 第三范式: 示例: 正解: BC范式: 示例: 正解:
- 最近项目中用到的js
1.用字典判断数组是否有重复function ticketTypeValidate() { var ticketArr = []; var tickettype = $("div[name= ...