UpdraftPlus 1.22.3 中修復的嚴重漏洞

已發表: 2022-02-18

在對 UpdraftPlus 插件的內部審計期間,我們發現了一個任意備份下載漏洞,該漏洞可能允許訂閱者等低權限用戶下載站點的最新備份。

如果被利用,該漏洞可能允許攻擊者訪問受影響站點數據庫中的特權信息(例如,用戶名和散列密碼)。

我們向插件作者報告了這個漏洞,他們最近發布了 1.22.3 版本來解決這個問題。 由於此問題的嚴重性,還推送了強制自動更新。 如果您的站點尚未安裝,我們強烈建議您更新到最新版本 (1.22.3) 並在您的站點上安裝成熟的安全解決方案,例如 Jetpack Security。

您可以在此處找到 UpdraftPlus 自己的建議。

細節

插件名稱:UpdraftPlus
插件 URI:https://wordpress.org/plugins/updraftplus/
作者:https://updraftplus.com/

漏洞

任意備份下載

受影響的版本: 1.16.7 和 1.22.3(免費版)之間的每個版本,以及
CVE-ID: CVE-2022-0633
WPVDB ID: d257c28f-3c7e-422b-a5c2-e618ed3c0bf3
CVSSv3.1: 8.5
CWSS: 87.6

該插件使用自定義“隨機數”和時間戳來安全地識別備份。 鑑於上述 nonce 和時間戳的知識可以讓某人訪問相當多的插件功能,確保這些信息只對那些合法需要它的人開放是至關重要的。

不幸的是,正如我們將證明的那樣,事實並非如此。

隨機數洩漏

第一個罪魁禍首位於 UpdraftPlus_Admin::process_status_in_heartbeat 方法。

	/**
	 * Receive Heartbeat data and respond.
	 *
	 * Processes data received via a Heartbeat request, and returns additional data to pass back to the front end.
	 *
	 * @param array $response - Heartbeat response data to pass back to front end.
	 * @param array $data     - Data received from the front end (unslashed).
	 */
	public function process_status_in_heartbeat($response, $data) {
		if (!is_array($response) || empty($data['updraftplus'])) return $response;
		try {
			$response['updraftplus'] = $this->get_activejobs_list(UpdraftPlus_Manipulation_Functions::wp_unslash($data['updraftplus']));
		} catch (Exception $e) {
			$log_message = 'PHP Fatal Exception error ('.get_class($e).') has occurred during get active job list. Error Message: '.$e->getMessage().' (Code: '.$e->getCode().', line '.$e->getLine().' in '.$e->getFile().')';
			error_log($log_message);
			$response['updraftplus'] = array(
				'fatal_error' => true,
				'fatal_error_message' => $log_message
			);
		// @codingStandardsIgnoreLine
		} catch (Error $e) {
			$log_message = 'PHP Fatal error ('.get_class($e).') has occurred during get active job list. Error Message: '.$e->getMessage().' (Code: '.$e->getCode().', line '.$e->getLine().' in '.$e->getFile().')';
			error_log($log_message);
			$response['updraftplus'] = array(
				'fatal_error' => true,
				'fatal_error_message' => $log_message
			);
		}

		if (UpdraftPlus_Options::user_can_manage() && isset($data['updraftplus']['updraft_credentialtest_nonce'])) {
			if (!wp_verify_nonce($data['updraftplus']['updraft_credentialtest_nonce'], 'updraftplus-credentialtest-nonce')) {
				$response['updraftplus']['updraft_credentialtest_nonce'] = wp_create_nonce('updraftplus-credentialtest-nonce');
			}
		}

		$response['updraftplus']['time_now'] = get_date_from_gmt(gmdate('Y-m-d H:i:s'), 'D, F j, Y H:i');

		return $response;
	}

它沒有正確確保發送此心跳請求的用戶是管理員(例如,通過諸如 current_user_can 之類的函數),這是一個問題,因為該函數嘗試做的第一件事是通過get_activejobs_list方法獲取活動備份作業的列表。

因此,攻擊者可以針對此心跳回調製作惡意請求,以訪問有關該站點迄今為止的最新備份的信息,其中將包含備份的隨機數。

備份下載

有幾種方法可以在 UpdraftPlus 上下載備份,其中大部分都得到了適當的保護。

	/**
	 * Find out if the current request is a backup download request, and proceed with the download if it is
	 */
	public function maybe_download_backup_from_email() {
		global $pagenow;
		if ((!defined('DOING_AJAX') || !DOING_AJAX) && UpdraftPlus_Options::admin_page() === $pagenow && isset($_REQUEST['page']) && 'updraftplus' === $_REQUEST['page'] && isset($_REQUEST['action']) && 'updraft_download_backup' === $_REQUEST['action']) {
			$findexes = empty($_REQUEST['findex']) ? array(0) : $_REQUEST['findex'];
			$timestamp = empty($_REQUEST['timestamp']) ? '' : $_REQUEST['timestamp'];
			$nonce = empty($_REQUEST['nonce']) ? '' : $_REQUEST['nonce'];
			$type = empty($_REQUEST['type']) ? '' : $_REQUEST['type'];
			if (empty($timestamp) || empty($nonce) || empty($type)) wp_die(__('The download link is broken, you may have clicked the link from untrusted source', 'updraftplus'), '', array('back_link' => true));
			$backup_history = UpdraftPlus_Backup_History::get_history();
			if (!isset($backup_history[$timestamp]['nonce']) || $backup_history[$timestamp]['nonce'] !== $nonce) wp_die(__("The download link is broken or the backup file is no longer available", 'updraftplus'), '', array('back_link' => true));
			$this->do_updraft_download_backup($findexes, $type, $timestamp, 2, false, '');
			exit; // we don't need anything else but an exit
		}
	}
}

不幸的是,與 admin_init 掛鉤的 UpdraftPlus_Admin::maybe_download_backup_from_email 方法也沒有直接驗證用戶的角色。

雖然它確實間接應用了一些檢查,例如檢查$pagenow全局變量,但過去的研究表明該變量可以包含任意用戶輸入。 不良行為者可以根據他們從上述心跳漏洞中洩露的信息,使用此端點下載文件和數據庫備份。

時間線

2022-02-14 – 與 UpdraftPlus 的初次接觸
2022-02-15 – 我們向他們發送有關此漏洞的詳細信息
2022-02-16 – UpdraftPlus 1.22.3 發布,強制自動更新啟動

結論

我們建議您檢查您的站點使用的是哪個版本的 UpdraftPlus 插件,如果在受影響的範圍內,請盡快更新!

在 Jetpack,我們努力確保您的網站免受此類漏洞的影響。 我們建議您為您的站點制定一個安全計劃,其中包括惡意文件掃描和備份。 Jetpack Security 是一種出色的 WordPress 安全選項,可確保您的網站和訪問者的安全。

學分

原始研究員:馬克·蒙帕斯

感謝 Jetpack Scan 團隊的其他成員提供反饋、幫助和更正。