2019 Lỗ hổng bảo mật zero-day trong Easy WP SMTP WordPress

Trong 2 tuần gần đây rất nhiều bạn có website sử dụng mã nguồn mở WordPress bị tấn công hoàng loạt. Hacker lợi dụng lỗ hổng bảo mật tạo một tài khoản có quyền admin để chiếm quyền quản lý của website. Ngay sau đó phát tán virus chèn link chuyển hướng website (1 tình trạng không hiếm gặp trên wordpress).

Cách phát hiện website đang bị tấn công

Để phát hiện website đang bị tấn công hay không bạn truy cập vào Quản trị WordPress -> Thành viên kiểm tra xem có thành viên đang ở quyền quản lý ngang mình không.

Nếu phát hiện có thành viên lạ ngang quyền admin của mình chứng tỏ website của mình đang bị tấn công.

Nguyên nhân và cách khắc phục

Nguyên nhân

Plugin Easy WP SMTP phổ biến , với hơn 300.000 cài đặt hoạt động, dễ bị lỗ hổng zero-day nghiêm trọng cho phép người dùng không được xác thực sửa đổi các tùy chọn WordPress hoặc tiêm và thực thi mã trong số các hành động độc hại khác

Lỗ hổng, được tìm thấy trong phiên bản v1.3.9, đã bị tin tặc khai thác kể từ ít nhất là ngày 15 tháng 3 và đã được phát hiện bởi NinjaFirewall,

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();
		}
	}
}

Hàm trên admin_init(), từ easy-wp-smtp.phptập lệnh, được chạy qua admin_inithook khi người dùng truy cập vào khu vực quản trị. Nó được sử dụng để xem / xóa nhật ký, nhập / xuất cấu hình plugin và cập nhật các tùy chọn trong cơ sở dữ liệu WordPress. Nó không kiểm tra khả năng của người dùng, do đó bất kỳ người dùng nào đã đăng nhập, như người đăng ký, đều có thể kích hoạt nó. Nhưng nó cũng có thể được thực thi bởi người dùng chưa được xác thực, bởi vì Easy WP SMTP sử dụng AJAX và admin_inithook cũng chạy trên admin-ajax.php như được chỉ ra trong tài liệu API WordPress:

Do đó, người dùng không được xác thực có thể gửi yêu cầu AJAX, ví dụ action=swpsmtp_clear_log, để kích hoạt chức năng trên và thực thi mã của nó.

Các khắc phục

1. Cập nhật plugin

Ngay lập tức cập nhật plugin Easy WP SMTP và các plugin khác, giao diện và wordpress lên phiên bản mới nhất.

2. Back up toàn bộ dữ liệu website

Tất cả mọi website cần có 1 bản backup hàng ngày hoặc hàng tuần để tránh sự việc hôm nay xảy ra. Vậy nên nếu bạn chưa có bản backup nào hãy lập tức backup toàn bộ website của mình xuống.

3. Xoá ngay tài khoản admin lạ

Nếu bạn đã bị chiếm quyền ngay lập tức xoá đi tài khoản admin lạ kia. Truy cập thêm phpMyadmin kiểm tra table user xem có liên kết lạ không, nếu có xoá ngay lập tức.

4. Bảo mật lại website của bạn

Đây là một lời cảnh tính dành cho tất cả mọi người sử dụng website mã nguồn mở WordPress là việc cập nhật website luôn luôn là điều cần thiết.
Nguồn: nintechnet