Luki znalezione we wtyczce Patreon WordPress

Opublikowany: 2021-03-26

Podczas wewnętrznego audytu wtyczki Patreon dla WordPress zespół Jetpack Scan znalazł kilka słabych punktów, które pozwoliłyby komuś przejąć stronę internetową.

Te luki zostały ujawnione twórcom wtyczek, którzy niezwłocznie wydali wersję 1.7.2, która naprawia wszystkie te problemy. Jeśli używasz starszej wersji wtyczki, zaktualizuj ją już dziś!

Czytaj dalej, aby poznać wszystkie szczegóły techniczne. Jeśli to przejdzie przez twoją głowę, nie martw się. Oferujemy Jetpack Scan do obsługi skanowania złośliwego oprogramowania i automatycznych aktualizacji lub usuwania dla Ciebie.

Nasz zespół zidentyfikował różne wektory ataków, w tym podatności na lokalne ujawnienie plików, podatności na fałszowanie żądań między witrynami (CSRF) i odbite skrypty między witrynami (XSS).

Luki w zabezpieczeniach umożliwiające ujawnienie plików lokalnych to błędy, które mogą wykorzystać źli gracze, aby uzyskać dostęp do krytycznych informacji, takich jak tajne klucze witryny i poświadczenia bazy danych. Luki w zabezpieczeniach typu Reflected Cross-Site Scripting i Cross-Site Request Forgery to problemy, które umożliwiają atakującym wykonywanie określonych działań w imieniu niczego niepodejrzewających użytkowników poprzez nakłanianie ich do kliknięcia starannie spreparowanych złośliwych łączy.

Niektóre z nich, jeśli zostaną wykorzystane, mogą umożliwić złośliwym osobom przejęcie podatnych na ataki stron internetowych.

Luka w zabezpieczeniach umożliwiająca ujawnienie plików lokalnych
Wersje, których dotyczy problem: <1.7.0
Identyfikator CVE: CVE-2021-24227
CVSSv3: 7,5
CWSS: 83,6

	public static function servePatronOnlyImage( $image=false ) {

		if ( ( !isset( $image ) OR !$image ) AND isset( $_REQUEST['patron_only_image'] ) ) {
			$image = $_REQUEST['patron_only_image'];
		}
		
		if ( !$image OR $image == '') {
			// This is not a rewritten image request. Exit.
			return;
		}

		if ( !( isset( $_REQUEST['patreon_action'] ) AND $_REQUEST['patreon_action'] == 'serve_patron_only_image' ) ) {
			return;	
		}

		$upload_locations = wp_upload_dir();

		// We want the base upload location so we can account for any changes to date based subfolders in case there are

		$upload_dir = substr( wp_make_link_relative( $upload_locations['baseurl'] ) , 1 );	

		$image = get_site_url() . '/' . $upload_dir . '/' . $image;
		
		if ( current_user_can( 'manage_options' ) ) {
			Patreon_Protect::readAndServeImage( $image );	
		}			
		
		// Below define can be defined in any plugin to bypass core locking function and use a custom one from plugin
		// It is independent of the plugin load order since it checks if it is defined.
		// It can be defined by any plugin until right before the_content filter is run.

		if ( apply_filters( 'ptrn/bypass_image_filtering', defined( 'PATREON_BYPASS_IMAGE_FILTERING' ) ) ) {
			Patreon_Protect::readAndServeImage( $image );
		}
	
		// Check if the image is protected:

		$attachment_id = attachment_url_to_postid( $image );
	
		// attachment_url_to_postid returns 0 if it cant find the attachment post id
		
		if ( $attachment_id == 0 ) {
			
			// Couldnt determine attachment post id. Try to get id from thumbnail
			$attachment_id = Patreon_Protect::getAttachmentIDfromThumbnailURL( $image );
	
			//No go. Have to get out and serve the image normally
			if ( $attachment_id == 0 OR !$attachment_id ) {
				Patreon_Protect::readAndServeImage( $image );

Patreon-Connect zawierał lukę umożliwiającą ujawnienie lokalnych plików, która może zostać wykorzystana przez każdą osobę odwiedzającą witrynę. Korzystając z tego wektora ataku, osoba atakująca może ujawnić ważne pliki wewnętrzne, takie jak wp-config.php, które zawierają poświadczenia bazy danych i klucze kryptograficzne używane do generowania plików jednorazowych i plików cookie.

W przypadku pomyślnego wykorzystania ta luka w zabezpieczeniach może doprowadzić do całkowitego przejęcia witryny przez złych graczy.

Odzwierciedlenie XSS w formularzu logowania
Wersje, których dotyczy problem: < 1.7.2
Identyfikator CVE: CVE-2021-24228
CVSSv3: 8.8
CWSS: 80,6

	public static function processPatreonMessages() {
		
		$patreon_error = '';
		if ( isset( $_REQUEST['patreon_error'] ) ) {
			
			// If any specific error message is sent from Patreon, prepare it
			$patreon_error = ' - Patreon returned: ' . $_REQUEST['patreon_error'];
			
		}

		if ( isset( $_REQUEST['patreon_message'] ) ) {
			
			return '<p class="patreon_message">' . apply_filters( 'ptrn/error_message', self::$messages_map[ $_REQUEST['patreon_message'] ] . $patreon_error ) . '</p>';

Patreon-Connect przechwytuje formularz logowania WordPress (wp-login.php) i oferuje użytkownikom możliwość uwierzytelniania w witrynie za pomocą konta Patreon. Niestety, część logiki rejestrowania błędów za kulisami pozwalała na odzwierciedlenie danych wejściowych kontrolowanych przez użytkownika na stronie logowania, bez oczyszczenia.

Aby skutecznie wykorzystać tę lukę, osoba atakująca musi skłonić swoją ofiarę do odwiedzenia łącza z pułapką zawierającą złośliwy kod Javascript. Ponieważ Javascript działa w kontekście przeglądarki ofiary, atakujący może dostosować kod ukryty w tym łączu, aby zrobić wszystko, na co pozwalają mu uprawnienia tego użytkownika.

Jeśli ten atak zakończy się powodzeniem przeciwko administratorowi, skrypt może całkowicie przejąć kontrolę nad witryną.

Odzwierciedlenie XSS w akcji AJAX 'patreon_save_attachment_patreon_level'
Wersje, których dotyczy problem: < 1.7.2
Identyfikator CVE: CVE-2021-24229
CVSSv3: 8.8
CWSS: 80,6

		$args = array (
			'attachment_id' => $attachment_id,
			'patreon_level' => $_REQUEST['patreon_attachment_patreon_level'],
			'message' => $message,
		);
		
		echo self::make_image_lock_interface( $args	);
	public function make_image_lock_interface( $args = array() ) {
		
		$interface = '';
		
		$interface .=  '<div class="patreon_image_lock_modal_content">';
		$interface .=  '<span class="patreon_image_lock_modal_close">&times;</span>';

		$interface .=  ' <form id="patreon_attachment_patreon_level_form" action="/wp-admin/admin-ajax.php" method="post">';
		$interface .=  '<h1 class="patreon_image_locking_interface_heading">Lock Image</h1>';
		$interface .=  '<div class="patreon_image_locking_interface_level">';
		$interface .=  '<span class="patreon_image_locking_interface_input_prefix">$<input id="patreon_attachment_patreon_level" type="text" name="patreon_attachment_patreon_level" value="' . $args['patreon_level'] . '" / ></span>';

Wtyczka wykorzystuje również hak AJAX do aktualizacji poziomu zastawu wymaganego przez subskrybentów Patreon, aby uzyskać dostęp do danego załącznika. Ta akcja jest dostępna dla kont użytkowników z uprawnieniem „manage_options” (tj. tylko administratorów).

Niestety, jeden z parametrów używanych w tym punkcie końcowym AJAX nie jest oczyszczany przed wydrukowaniem z powrotem do użytkownika, więc związane z nim ryzyko jest takie samo, jak w przypadku poprzedniej opisanej przez nas luki XSS.

CSRF pozwala napastnikom nadpisywać/utworzyć meta użytkownika
Wersje, których dotyczy problem: <1.7.0
Identyfikator CVE: CVE-2021-24230
CVSSv3: 6,5
CWSS: 42

	public function toggle_option() {
		
		if( !( is_admin() && current_user_can( 'manage_options' ) ) ) {
			return;
		}
		
		$current_user = wp_get_current_user();
		
		$option_to_toggle = $_REQUEST['toggle_id'];
		
		$current_value = get_user_meta( $current_user->ID, $option_to_toggle, true );
		
		$new_value = 'off';
		
		if( !$current_value OR $current_value == 'off' ) {
			$new_value = 'on';			
		}
		
		update_user_meta( $current_user->ID, $option_to_toggle, $new_value );
		
	}

Niektóre punkty końcowe nie sprawdziły poprawności otrzymanego żądania, które zostało wysłane po uzasadnionej akcji użytkownika, co można wykonać za pomocą wartości jednorazowych. Jeden z tych niechronionych punktów końcowych umożliwił wrogim osobom stworzenie pułapki łącza, które po odwiedzeniu nadpisuje lub tworzy dowolne metadane użytkownika na koncie ofiary.

Jeśli zostanie wykorzystany, ten błąd może zostać użyty do zastąpienia meta „wp_capabilities”, która zawiera role i uprawnienia konta użytkownika, którego dotyczy problem. Wykonanie tego zasadniczo zablokowałoby ich dostęp do witryny, blokując im dostęp do płatnych treści.

CSRF umożliwia atakującym odłączenie witryn od Patreon
Wersje, których dotyczy problem: <1.7.0
Identyfikator CVE : CVE-2021-24231
CVSSv3: 6,5
CWSS: 26,1

			if ( isset( $_REQUEST['patreon_wordpress_action'] ) AND $_REQUEST['patreon_wordpress_action'] == 'disconnect_site_from_patreon' AND is_admin() AND current_user_can( 'manage_options' ) ) {

			// Admin side, user is admin level. Perform action:
			
			// To disconnect the site from a particular creator account, we will delete all options related to creator account, but we will leave other plugin settings and post gating values untouched
			
			$options_to_delete = array(
				'patreon-custom-page-name',
				'patreon-fetch-creator-id',
				'patreon-creator-tiers',
				'patreon-creator-last-name',
				'patreon-creator-first-name',
				'patreon-creator-full-name',
				'patreon-creator-url',
				'patreon-campaign-id',
				'patreon-creators-refresh-token-expiration',
				'patreon-creator-id',
				'patreon-setup-wizard-last-call-result',
				'patreon-creators-refresh-token',
				'patreon-creators-access-token',
				'patreon-client-secret',
				'patreon-client-id',
				'patreon-setup_is_being_done',
				'patreon-setup-done',
				'patreon-currency-sign',
			);
			
			// Ask the API to delete this client:
			
			$creator_access_token = get_option( 'patreon-creators-access-token', false );
			$client_id 			  = get_option( 'patreon-client-id', false );
				
			// Exceptions until v1 v2 transition is complete
			
			$api_version = get_option( 'patreon-installation-api-version' );

			if ( $api_version == '1' ) {

				// Delete override - proceed with deleting local options
				
				foreach ( $options_to_delete as $key => $value ) {
					delete_option( $options_to_delete[$key] );
				}
				
				update_option( 'patreon-installation-api-version', '2' );
				update_option( 'patreon-can-use-api-v2', true );
				
				wp_redirect( admin_url( 'admin.php?page=patreon_wordpress_setup_wizard&setup_stage=reconnect_0') );
				exit;
			}
			

Ta jest podobna do ostatniej luki, ponieważ jest to ten sam rodzaj ataku (CSRF), ale jest wymierzony w administratorów. Ten konkretny wektor ataku działa jak poprzedni. Osoba atakująca musi uzyskać zalogowanego administratora, aby odwiedził specjalnie spreparowane łącze.

Ponieważ ten konkretny punkt końcowy może odłączyć witrynę od Patreon, atakujący atakujący ten wektor ataku mogą również to zrobić, co uniemożliwiłoby synchronizację nowej zawartości z witryną.

Oś czasu

  • Pierwsza próba kontaktu (nieudana) – 4 grudnia
  • Druga próba kontaktu – 11 grudnia
  • Autorzy potwierdzają raport – 15 grudnia
  • Wersja 1.7.0 została wydana – 5 stycznia
  • Zgłaszamy dwa dodatkowe problemy XSS – 9 marca
  • Autorzy uznają drugi raport – 9 marca
  • Wersja 1.7.2 została wydana – 11 marca

Wniosek

Zalecamy sprawdzenie aktualnej wersji wtyczki Patreon-Connect, której używasz na swojej stronie, a jeśli nie 1.7.2, zaktualizuj ją tak szybko, jak to możliwe!

W Jetpack ciężko pracujemy, aby zapewnić ochronę Twoich stron internetowych przed tego typu lukami. Aby być o krok przed wszelkimi nowymi zagrożeniami, wypróbuj Jetpack Scan, który obejmuje skanowanie bezpieczeństwa i automatyczne usuwanie złośliwego oprogramowania.

Kredyty

Ujawnienie zabezpieczeń było możliwe dzięki George Stephanis, Fioravante Souza, Miguel Neto, Benedictowi Singerowi i Marcowi Montpasowi.