到小组第一次做汇报,开始把我纠结了很久,不知道讲什么,四处求助,开始说有大一的嫩娃娃们要听,我觉得讲些基础的东西比较好,比如什么注入和xss之类入门的东西,但是他们又说这次不用管大一的嫩娃娃们,我们自己平时怎么讲的就怎么讲,这个更纠结我了,想了很多东西,总感觉有点不合适,如果你讲的东西没有自己的见解并且都是大家知道的,就没有什么意义了,于是乎我左思右想,就想到了最近的dedecms注入,注入出来的时候我就去看了具体的代码,也简单分析了一下,结合我以前看过dedecms的经验,也发现了很多有意思的东西。
还记得在今年6月份吧!晴天小涛在90sec发了来一帖子,是关于dedecms全局变量再次覆盖的问题,当时我也去看了下dedecms的这个 漏洞 的具体代码,也做了一些分析,见:http://lanu.sinaapp测试数据/0day/100. html 当时只是在关于为什么会再次发生全局变量覆盖这个问题上做了分析,没有去关心其他的东西了,这篇文章我也在90sec上发了,当时晴天小涛回复说,哪儿还有个二次变量覆盖问题,有时间我们还可以继续分析下,当时忙着考试吧,快放假了,做学生的当时都很忙,就没有再去分析了。
正好现在出了这个sql注入就是和我们当时说的那个二次变量覆盖有关系,我也有时间,所以就去具体看来下,分析了下!就做为小组汇报的题材了!虽然这个分析在90sec上花开若相惜也做了分析。
前面全是废话,下面走入正题!
====================================================
我们先从去年的dedecms的全局变量覆盖说起:http://HdhCmsTest2cto测试数据/Article/201108/100014.html,而现在我们的注入文件/plus/feedback.php 中
require_once(dirname(__FILE__)."/include/common.inc.php");
if($cfg_feedback_forbid=='Y') exit(' 系统 已经禁止评论功能!');
require_once(DEDEINC."/filter.inc.php");
可以看出上边包含有两个文件我们先看
/include/common.inc.php
function _RunMagicQuotes(&$svar)
{
if(!get_magic_quotes_gpc())
{
if( is_array($svar) )
{
foreach($svar as $_k => $_v) $svar[$_k] = _RunMagicQuotes($_v);
}
else
{
if( strlen($svar)>0 && preg_match('#^(cfg_|GLOBALS|_GET|_POST|_COOKIE)#',$svar) )
{
exit('Request var not allow!');
}
$svar = addslashes($svar);
}
}
return $svar;
}
if (!defined('DEDEREQUEST'))
{
//检查和注册外部提交的变量 (2011.8.10 修改登录时相关过滤)
function CheckRequest(&$val) {
if (is_array($val)) {
foreach ($val as $_k=>$_v) {
if($_k == 'nvarname') continue;
CheckRequest($_k);
CheckRequest($val[$_k]);
}
} else
{
if( strlen($val)>0 && preg_match('#^(cfg_|GLOBALS|_GET|_POST|_COOKIE)#',$val) )
{
exit('Request var not allow!');
}
}
}
//var_dump($_REQUEST);exit;
CheckRequest($_REQUEST);
foreach(Array('_GET','_POST','_COOKIE') as $_request)
{
foreach($$_request as $_k => $_v)
{
if($_k == 'nvarname') ${$_k} = $_v;
else ${$_k} = _RunMagicQuotes($_v);
}
}
}
在这段代码中_RunMagicQuotes()函数是用来转义的,如果php自带的gpc没有开启,就是用他转义。
然后接下来的代码就是初始化变量了,这儿初始化变量是对带入的值做了转义的,如$_GET[test]=111' 就会成为$test=111\'
这样的形式。
接下来我们再看 /plus/filter.inc.php ,这个文件主要是过滤脏话的,就是说,你说的脏话全部会被替换成***,在代码里边的脏话替换函数是_FilterAll(),
他这个文件再次对变量进行了初始化:
/* 对_GET,_POST,_COOKIE进行过滤 */
foreach(Array('_GET','_POST','_COOKIE') as $_request)
{
foreach($$_request as $_k => $_v)
{
${$_k} = _FilterAll($_k,$_v);
}
}
看见了,这儿变量二次初始的时候只用了_FilterAll() 进行过滤,如果php自带的gpc是关闭的时候,上边common.inc.php进行的变量初始化时的$test=111\',这儿再进行变量初始化则得到$test=111' 由于在feedback.php 文件中我们可以看出,filter.inc.php文件里面的变量初始化会在common.inc.php之后,所以$test=111'会覆盖$test=111\' 使得前面的转义失效了,最终$test=111'。
这就是我们能够注入的根源所在,再加上feedback中的$typeid初始化过后,就没有再次过滤了,所以我们就可以使用他注入了。
exp:
from:90sec 鬼哥
接下来我们做下思维延伸:
1.懂的了原理我们就可以继续再去审计下dedecms的代码了,我们可以仔细的看下,包含有filter.inc.php的文件,说不定你也能挖出几个洞来!
2.在filter.inc.php中有一个脏话替换函数,会把脏话替换成***, 如果我们传如的参数里面有这样的一个字符 /他妈/ 他就会成为/***/,我相信大家已经想到了什么。
3.程序员不好当啊!
查看更多关于三叶草小组汇报--dedecms的故事 - 网站安全 - 自学的详细内容...