[CVE Study] CVE-2023-2384

코코·2024년 1월 14일
0

CVE_Study

목록 보기
3/3

오늘은 ! WordPress Plugin의 Bookit 취약점에 대해 공부해보려한다.
CVE-2023-2384에 대해 알아보자. 취약점 분석 글이 자세하게 적혀있어 차근차근 따라가며 학습해보려고 한다.


CVE-2023-2384

Wordpress Bookit 2.3.6 이하 버전에서 발생하는 인증 우회 취약점. 사용자의 Email만 알고 있다면, 해당 사용자로 로그인할 수 있다.


바로 코드부터 살펴보자. 취약한 코드는 CustomerController.php 파일에 존재한다.

	public static function get_customer( $data ) {
		
		if ( ! empty( $data['user_id'] ) ) {
			$id = Customers::get('wp_user_id', $data['user_id'])->id;
		} else {
			$id = Customers::get('email', $data['email'])->id;
		}

IF 조건문을 통해 user_id가 있는지 없는지 확인한다.
만약 user_id가 있다면, user_id를 통해서 id를 가져오고, user_id가 없다면, E-mail을 통해 id를 가져온다.

$data는 사용자가 입력한 파라미터이다.


다음 코드를 살펴보자.

		$settings = SettingsController::get_settings();
		if ( $settings['booking_type'] == 'registered' && !is_user_logged_in() ) {
			$data['role']    = User::$customer_role;
			$data['user_id'] = Customers::save_or_get_wp_user($data);
			/** Authorize wp User */
			wp_clear_auth_cookie();
			wp_set_current_user ( $data['user_id'] );
			wp_set_auth_cookie  ( $data['user_id'] );
		}

위에서 get_settings()를 통해 설정을 가져온다.
이를 통해 booking_type예약된 상태이고, 사용자가 로그인되지 않은 상태라면 아래의 로직으로 이동하게 된다.

아래의 로직은 save_or_get_wp_user 메서드를 통해 user_id를 가져온다.

참고용으로 save_or_get_wp_user 함수를 가져와봤다.

	public static function save_or_get_wp_user($data) {

		$is_exist_user = get_user_by_email($data['email']);
		if ( $is_exist_user ) {
			return $is_exist_user->data->ID;
		}

		$user_data = [
			'user_login'    => $data['email'],
			'user_pass'     => $data['password'],
			'first_name'    => $data['full_name'],
			'last_name'     => '',
			'user_email'    => $data['email']
		];

		if ( empty( $user_data['first_name'] ) ) {
			$user_data['first_name'] = $data['email'];
		}

		if ( array_key_exists('role', $data) && get_role($data['role']) != null ) {
			$user_data['role'] = $data['role'];
		}

		return wp_insert_user($user_data);
	}

다시 계속해서 살펴보자.

		$settings = SettingsController::get_settings();
		if ( $settings['booking_type'] == 'registered' && !is_user_logged_in() ) {
			$data['role']    = User::$customer_role;
			$data['user_id'] = Customers::save_or_get_wp_user($data);
			/** Authorize wp User */
			wp_clear_auth_cookie();
			wp_set_current_user ( $data['user_id'] );
			wp_set_auth_cookie  ( $data['user_id'] );
		}

wp_clear_auth_cookie 함수를 통해 Cookie를 clear 시키고,
찾은 user_id를 통해 wp_set_current_user와 wp_set_auth_cookie를 설정한다.


wp_set_current_user 함수는 user_id를 통해 현재 사용자를 변경하는 함수이고, wp_set_auth_cookie 함수는 사용자 ID를 기반으로 쿠키를 설정하는 함수이다.


궁금하다면, 아래의 링크를 통해 확인해볼 수 있다.
✔️ wp_set_current_user() - https://developer.wordpress.org/reference/functions/wp_set_current_user/
✔️ wp_set_auth_cookie() - https://developer.wordpress.org/reference/functions/wp_set_auth_cookie/



즉, 예약할 때 존재하는 ID의 E-mail을 잘 입력해주면 해당 ID로 로그인할 수 있다.




취약 상황 구현

그러면 위의 내용 토대로 실제 취약한 버전을 다운로드하여 구현해보자.


[bookit]

위의 ShortCode를 통해 페이지를 생성해준다.

생성 후 카테고리를 하나 생성해주고 서비스를 생성하고 마지막으로 Staff도 하나 생성해줘야한다.


위의 카테고리, 서비스, 직원을 생성해주면 캘린더를 통해 예약을 할 수 있다.
"SUBMIT" 버튼을 클릭해준다.

다른 부분을 모두 채워준다. 중요한 부분은 E-mail 입력란에 관리자 E-mail을 입력하여 BOOK NOW 버튼을 눌러준다.

관리자 계정으로 로그인되는 것을 확인할 수 있다.(coco가 관리자 계정 닉네임)




🥳


※ 참고
👉 https://plugins.trac.wordpress.org/log/bookit/

profile
화이팅!

0개의 댓글