Schwere Schwachstelle in UpdraftPlus 1.22.3 behoben

Veröffentlicht: 2022-02-18

Während einer internen Prüfung des UpdraftPlus-Plug-ins haben wir eine willkürliche Schwachstelle beim Herunterladen von Backups entdeckt, die es Benutzern mit geringen Berechtigungen wie Abonnenten ermöglichen könnte, die neuesten Backups einer Website herunterzuladen.

Wenn sie ausgenutzt wird, könnte die Schwachstelle Angreifern Zugriff auf privilegierte Informationen aus der Datenbank der betroffenen Site gewähren (z. B. Benutzernamen und gehashte Passwörter).

Wir haben die Schwachstelle den Autoren des Plugins gemeldet, und sie haben kürzlich Version 1.22.3 veröffentlicht, um sie zu beheben. Aufgrund der Schwere dieses Problems wurden auch erzwungene automatische Updates vorangetrieben. Wenn Ihre Website dies noch nicht getan hat, empfehlen wir Ihnen dringend, auf die neueste Version (1.22.3) zu aktualisieren und eine bewährte Sicherheitslösung auf Ihrer Website zu haben, z. B. Jetpack Security.

Die eigene Empfehlung von UpdraftPlus finden Sie hier.

Einzelheiten

Plugin-Name: UpdraftPlus
Plugin-URI: https://wordpress.org/plugins/updraftplus/
Autor: https://updraftplus.com/

Die Schwachstelle

Willkürliche Backup-Downloads

Betroffene Versionen: Jede Version zwischen 1.16.7 und 1.22.3 (kostenlose Version) und
CVE-ID: CVE-2022-0633
WPVDB-ID: d257c28f-3c7e-422b-a5c2-e618ed3c0bf3
CVSSv3.1: 8.5
CWSS: 87.6

Das Plugin verwendet benutzerdefinierte „Nonces“ und Zeitstempel, um Backups sicher zu identifizieren. Angesichts der Tatsache, dass die Kenntnis dieser Nonce und des Zeitstempels jemandem Zugriff auf einige der Funktionen des Plugins geben kann, ist es von entscheidender Bedeutung, sicherzustellen, dass diese Informationen nur für diejenigen zugänglich sind, die sie rechtmäßig benötigen.

Wie wir zeigen werden, war dies leider nicht der Fall.

Nonce-Leck

Der erste Übeltäter befand sich in UpdraftPlus_Admin::process_status_in_heartbeat Methode.

	/**
	 * 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;
	}

Es wurde nicht richtig sichergestellt, dass der Benutzer, der diese Heartbeat-Anforderung sendet, ein Administrator war (z. B. über Funktionen wie current_user_can), was ein Problem darstellte, da diese Funktion als Erstes versucht, die Liste der aktiven Backup-Jobs über die Methode get_activejobs_list abzurufen .

Ein Angreifer könnte daher eine böswillige Anfrage erstellen, die auf diesen Heartbeat-Callback abzielt, um Zugriff auf Informationen über das bisher letzte Backup der Website zu erhalten, das unter anderem die Nonce eines Backups enthält.

Backup-Download

Es gibt einige Möglichkeiten, Backups auf UpdraftPlus herunterzuladen, von denen die meisten ordnungsgemäß gesichert wurden.

	/**
	 * 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
		}
	}
}

Leider hat die Methode UpdraftPlus_Admin::maybe_download_backup_from_email, die mit admin_init verbunden ist, die Rollen der Benutzer auch nicht direkt validiert.

Während einige Überprüfungen indirekt durchgeführt wurden, wie z. B. die Überprüfung der globalen Variable $pagenow , haben frühere Untersuchungen gezeigt, dass diese Variable beliebige Benutzereingaben enthalten kann. Angreifer könnten diesen Endpunkt verwenden, um Datei- und Datenbanksicherungen herunterzuladen, basierend auf den Informationen, die sie aus dem oben erwähnten Heartbeat-Bug verloren haben.

Zeitleiste

14.02.2022 – Erstkontakt mit UpdraftPlus
15.02.2022 – Wir senden ihnen Details zu dieser Schwachstelle
16.02.2022 – UpdraftPlus 1.22.3 wird veröffentlicht, erzwungene automatische Updates gestartet

Fazit

Wir empfehlen Ihnen, zu überprüfen, welche Version des UpdraftPlus-Plug-ins Ihre Website verwendet, und wenn es in den betroffenen Bereich fällt, aktualisieren Sie es so schnell wie möglich!

Bei Jetpack arbeiten wir hart daran sicherzustellen, dass Ihre Websites vor dieser Art von Schwachstellen geschützt sind. Wir empfehlen, dass Sie einen Sicherheitsplan für Ihre Website haben, der das Scannen von bösartigen Dateien und Sicherungen umfasst. Jetpack Security ist eine großartige WordPress-Sicherheitsoption, um sicherzustellen, dass Ihre Website und Besucher sicher sind.

Kredite

Ursprünglicher Forscher: Marc Montpas

Vielen Dank an den Rest des Jetpack Scan-Teams für Feedback, Hilfe und Korrekturen.