dedecms 转义绕过 v5.8无条件rce分析

  • A+
所属分类:代码审计

记录一下分析过程

参考文章:

https://srcincite.io/blog/2021/09/30/chasing-a-dream-pwning-the-biggest-cms-in-china.html

****

****

绕过转义

漏洞在:include/filter.inc.php

****

首先dedecms是全局变量注册,这一点在include/common.inc.php可以看出来

dedecms 转义绕过 v5.8无条件rce分析

首先是遍历post get cookie 并调用_RunMagicQuotes 进行转义

dedecms 转义绕过 v5.8无条件rce分析

这里是防止你覆盖get post globals这类变量,通过循环注册 转义,并赋值

dedecms 转义绕过 v5.8无条件rce分析

再来看看filter.inc.php

dedecms 转义绕过 v5.8无条件rce分析

可以看到这里如果$magic_quotes_gpc从配置文件中读取没有开gpc的话也是通过addslashes转义,可以看出这里有个变量覆盖的问题

并且foreach循环取key的时候也没有过滤magic_quotes_gpc变量,导致这里可以变量覆盖 不进入转义 直接return

可以全局查找一下那些文件引入了filter.inc.php

在dedecms v5.7中 的bookfeedback.php找到了

dedecms 转义绕过 v5.8无条件rce分析

由于引入顺序的原因,可以导致转移全部失效

如果后引入common.inc.php就不会了

dedecms 转义绕过 v5.8无条件rce分析

复现如下

dedecms 转义绕过 v5.8无条件rce分析

语句是我自己打印出来的

dedecms 转义绕过 v5.8无条件rce分析

就不闭合了,网费不够了

RCE

漏洞存在于dedecms v5.8

阅读完作者文章看漏洞位于flink文件 但是我看到onlymsg值默认是1,不知道作者怎么绕过去的

dedecms 转义绕过 v5.8无条件rce分析

在进行了一个插入操作后,进入showmsg

dedecms 转义绕过 v5.8无条件rce分析

可以看到onlymsg默认值为0

function ShowMsg($msg, $gourl, $onlymsg = 0, $limittime = 0){    if (empty($GLOBALS['cfg_plus_dir'])) {        $GLOBALS['cfg_plus_dir'] = '..';    }    if ($gourl == -1) {        $gourl = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '';        if ($gourl == "") {            $gourl = -1;        }    }

    $htmlhead = "    <html>rn<head>rn<title>DedeCMS提示信息</title>rn    <meta http-equiv="Content-Type" content="text/html; charset={dede:global.cfg_soft_lang/}" />    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">    <meta name="renderer" content="webkit">    <meta http-equiv="Cache-Control" content="no-siteapp" />    <link rel="stylesheet" type="text/css" href="{dede:global.cfg_assets_dir/}/pkg/uikit/css/uikit.min.css" />    <link rel="stylesheet" type="text/css" href="{dede:global.cfg_assets_dir/}/css/manage.dede.css">    <base target='_self'/>    </head>    <body>    " . (isset($GLOBALS['ucsynlogin']) ? $GLOBALS['ucsynlogin'] : '') . "    <center style="width:450px" class="uk-container">        <div class="uk-card uk-card-small uk-card-default" style="margin-top: 50px;">        <div class="uk-card-header"  style="height:20px">DedeCMS 提示信息!</div>
    <script>rn";    $htmlfoot = "    </script>            </center>        <script src="{dede:global.cfg_assets_dir/}/pkg/uikit/js/uikit.min.js"></script>  <script src="{dede:global.cfg_assets_dir/}/pkg/uikit/js/uikit-icons.min.js"></script>    </body>rn</html>rn";
    $litime = ($limittime == 0 ? 1000 : $limittime); //1000    $func = '';

    if ($gourl == '-1') {        if ($limittime == 0) {            $litime = 3000;        }
        $gourl = "javascript:history.go(-1);";    }
    if ($gourl == '' || $onlymsg == 1) {
        $msg = "<script>alert("" . str_replace(""", "“", $msg) . "");</script>";

    } else {        //当网址为:close::objname 时, 关闭父框架的id=objname元素        if (preg_match('/close::/', $gourl)) {            $tgobj = trim(preg_replace('/close::/', '', $gourl));
            $gourl = 'javascript:;';            $func .= "window.parent.document.getElementById('{$tgobj}').style.display='none';rn";            //echo $func;
        }
        $func .= "var pgo=0;      function JumpUrl(){        if(pgo==0){ location='$gourl'; pgo=1; }      }rn";        $rmsg = $func;        $rmsg .= "document.write("<div style='height:130px;font-size:10pt;background:#ffffff'><br />");rn";        $rmsg .= "document.write("" . str_replace(""", "“", $msg) . "");rn";        $rmsg .= "document.write("";
        if ($onlymsg == 0) {            if ($gourl != 'javascript:;' && $gourl != '') {                $rmsg .= "<br /><a href='{$gourl}'>如果你的浏览器没反应,请点击这里...</a>";                $rmsg .= "<br/></div>");rn";                $rmsg .= "setTimeout('JumpUrl()',$litime);";            } else {                $rmsg .= "<br/></div>");rn";            }        } else {            $rmsg .= "<br/><br/></div>");rn";        }        $msg = $htmlhead . $rmsg . $htmlfoot;        //echo $msg;
    }

    $tpl = new DedeTemplate();    $tpl->LoadString($msg);
    $tpl->Display();}

flink中showmsg gourl参数设置为-1

dedecms 转义绕过 v5.8无条件rce分析

-1时 取referer的值覆盖$gourl

dedecms 转义绕过 v5.8无条件rce分析

gourl根据特定字符replace之后传给tgobj 在后面拼到了func 最终频道$msg中

dedecms 转义绕过 v5.8无条件rce分析

进到loadstring就是根据msg内容md5创建一个文件,并对模板内容进行解析

跟入display

dedecms 转义绕过 v5.8无条件rce分析

dedecms 转义绕过 v5.8无条件rce分析

在wirecache的时候有一个黑名单检测

dedecms 转义绕过 v5.8无条件rce分析

但是这个匹配有点鸡肋,黑名单也不全 自己想办法绕过即可

dedecms 转义绕过 v5.8无条件rce分析

最终通过include来包含模板 执行代码,复现如下

dedecms 转义绕过 v5.8无条件rce分析

dedecms 转义绕过 v5.8无条件rce分析

flink是需要改成1的

通过寻找recommend.php 可以实现无条件rce

dedecms 转义绕过 v5.8无条件rce分析

条件均满足 即为-1 only也为0 美滋滋

dedecms 转义绕过 v5.8无条件rce分析

 

原文始发于微信公众号(8ypass):ZGVkZWNtcyDovazkuYnnu5Xov4cgdjUuOOaXoOadoeS7tnJjZeWIhuaekA==

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: