DedeCMS代碼注入漏洞(CVE-2022-36216)
1. 簡述
漏洞涉及檔案:
/uploads/dede/member_toadmin.php
/uploads/include/common.inc.php
整體流程簡述:
參數傳入流程
/uploads/include/common.inc.php
1. `_RunMagicQuotes()`
2. `addslashes($svar)`
下面的$id 值是通過參數傳入流程傳入進來的。
/uploads/dede/member_toadmin.php
1. `$arr_password[$id] = "{$timestamp}";`
2. `$content = "json_encode($arr_password);`
3. `$fp = fopen($filename, 'w')`
1. `$filename = DEDEDATA.'/password.data.php';`
5. `fwrite($fp, $content);`
漏洞代碼節選:
// /uploads/include/common.inc.php 檔案處代碼
if (!defined('DEDEREQUEST'))
{
foreach(Array('_GET','_POST','_COOKIE') as $_request)
{
foreach($_request as $_k => $_v)
{
if($_k == 'nvarname') ${$_k} = $_v;
else ${$_k} = _RunMagicQuotes($_v);
}
}
}
// /uploads/include/common.inc.php 檔案處代碼
function _RunMagicQuotes(&$svar)
{
if(!get_magic_quotes_gpc())
{
if( is_array($svar) )
{
foreach($svar as $_k => $_v) $svar[$_k] = _RunMagicQuotes($_v);
}
else
{
...
$svar = addslashes($svar);
}
}
return $svar;
}
// /uploads/dede/member_toadmin.php
if($dopost == "toadmin")
{
...
$filename = DEDEDATA.'/password.data.php';
if (file_exists($filename)) {
require_once(DEDEDATA . '/password.data.php');
$arr_password = json_decode($str_password, true);
}
...
$arr_password[$id] = "{$timestamp}";
$content = "<?php\r\n\$str_password='".json_encode($arr_password)."';";
$fp = fopen($filename, 'w') or die("寫入檔案 $filename 失敗,請檢查權限!");
fwrite($fp, $content);
fclose($fp);
}
2. 分析
漏洞成因:
在DedeCMS中, 首先會用_RunMagicQuotes()函數,把 $_GET, $_POST, $_COOKIE 這三種方式擷取到的使用者輸入過濾一遍。
然後在_RunMagicQuotes()函數中, 調用了PHP内置的addslashes()函數将擷取到的所有輸入進行轉義。
然後 json_encode() 函數會将反斜杠進行轉義, 這時候單引号就逃逸了 addslashes()函數的過濾, 逃逸了過濾的單引号, 和最開頭的單引号實作了閉合。如下圖所示
閉合掉單引号之後, 利用php拼接的性質, 就能傳入惡意函數了, 當 $id 的值為 '.phpinfo()?>時, 如下圖所示
3. 複現
1.首先打開注冊會員功能
找到本地檔案uploads/install/config.cache.inc.php, 将裡面的$cfg_mb_open = 'N'; 改為 $cfg_mb_open = 'Y';。
2.然後注冊一個會員(就在首頁上)
3.前往背景頁面, 找到會員 -> 注冊會員清單 -> 提升。點選提升按鈕, 按照提示填寫表格。填寫完畢之後, 暫時先不要點選确定提升按鈕。
4.配置好浏覽器代理, 打開BurpSuit或者類似的其它工具, 開啟Proxy子產品中的Intercept is on。然後再點選上一步的确定提升按鈕, 這時候能夠捕獲到HTTP請求包, 請求體部分如下所示。
請注意這裡的id參數, 這裡就是漏洞觸發點, 将其修改為 3'.phpinfo()?>, 然後将資料包Forward 放回去
可以看到, 惡意代碼已經成功注入到 /uploads/data/password.data.php 檔案中
通路 /uploads/data/password.data.php 檔案, 可以看到成功執行了注入進去的代碼。
4. 雞肋
讓我們回到最開始的那段漏洞代碼片段中, 裡面有一段代碼是這樣寫的。
<?php
$filename = DEDEDATA.'/password.data.php';
if (file_exists($filename)) {
require_once(DEDEDATA . '/password.data.php');
$arr_password = json_decode($str_password, true);
}
這段代碼, 檢測了是否存在 password.data.php 這個檔案, 如果存在的話, 則直接對password.data.php 檔案的内容進行解碼。也就是說我們沒有辦法再往裡面注入惡意代碼了。
那麼問題來了,如果遇到網站已經有一個正常内容的password.data.php檔案,這個漏洞就沒有任何意義了,畢竟這個漏洞隻能在沒有這個檔案的情況下才能觸發。食之無味,棄之可惜。
DedeCMS任意檔案删除漏洞(CVE-2022-30508)
1. 簡述
漏洞涉及檔案: /uploads/dede/upload.php
漏洞具體代碼:
$delete = preg_replace("#^([.]*[/]*)*#", "", $delete);
...
if ($dopost === 'delete') {
$uploadTmp = DEDEDATA . '/uploadtmp';
if (unlink($uploadTmp . '/' . $delete)) {
echo 'success';
exit();
}
echo 'fail';
}
2. 分析
漏洞成因: preg_replace()對過濾不嚴格,導緻依然能夠路徑穿越。然後通過代碼中的unlink()函數實作任意檔案删除。
3. 複現
首先在根目錄下建立一個test.txt檔案
由于該漏洞涉及的代碼片段比較簡單,直接使用内置的參數輸入方式輸入參數,這裡選擇的是$_GET傳參
/uploads/dede/upload.php?dopost=delete&delete=/Rebmal/../../../test.txt
可以看到已經成功删除了test.txt檔案。
4. 建議
請更新到最新版本。
from : https://xz.aliyun.com/t/12526