[CVE-2023-3460] 취약점 분석 보고서
WordPress 웹사이트에서 사용자 등록 및 커뮤니티 기능을 관리하는 데 사용되는 도구인 Ultimate Member WordPress 플러그인에 영향을 미치는 인증우회(Authentication Bypass)취약점
Ultimate Member WordPress 플러그인에 영향을 미치는 인증우회(Authentication Bypass) 취약점 (CVE-2023-3460)
1.개요
CVE-2023-3460은 WordPress의 인기 플러그인인 Ultimate Member에서 발견된 심각한 권한 상승 취약점이다. 이 취약점을 통해 공격자는 관리자 권한을 가진 계정을 생성할 수 있다. 이를 악용하여 공격자는 관리자 계정을 생성하여 웹사이트를 장악할 수 있다.
- CVE ID: CVE-2022-3460
- CVSS 점수: 9.8 (높음)
2. 환경 셋팅
- XAMPP 3.3.0
- Wordpress 6.7
- Ultimate Member < 2.6.7
3. 분석
컬럼
1. wp_capabilities
- 사용자의 역할과 권한을 관리하는 컬럼
테이블
1. wp_users
- 이용자의 user_login, user_pass, user_email 등의 컬럼에 필수 정보가 저장되고, 자동증가 필드로는 ID라는 컬럼이 있음
2. wp_usermeta
- umeta_id, user_id, meta_id, meta_key, meta_value 등의 컬럼으로 구성되고, wp_user 테이블의 ID 컬럼과 연결하기 위해 user_id라는 컬럼이 있고, umeta_id는 자동증가 필드이고 meta_key, meta_value 컬럼에는 이용자 등록 정보 중의 커스텀 필드의 값이 저장됨
3. wp_usermeta
- wp_usermeta 테이블에는 umeta_id, user_id, meta_key, meta_value 등의 컬럼으로 구성되는데, wp_users 테이블의 ID 컬럼과 연결하기 위해 user_id라는 컬럼이 있고, umeta_id는 자동증가 필드이고, meta_key, meta_value 컬럼에는 이용자 등록 정보 중의 커스텀 필드의 값이 저장됨
4. Diff 분석
주요 변경사항
1. class-register.php
if ( ! defined( 'ABSPATH' ) )
구문 수정:- 기존:
exit
만 호출 - 변경: 블록
{}
로 감싸서 명시적으로 표현.
- 기존:
__construct
메서드:- 기존:
function
→ 변경:public function
add_action
에서verify_nonce
호출의 매개변수 개수 변경 (1, 1
→1, 2
).
- 기존:
verify_nonce
메서드:- 기존:
$args
→ 변경:$args
와$form_data
추가.
- 기존:
2. class-user.php
remove_accents
함수 추가remove_accents
는 문자열에서 강세(악센트)를 제거한다.- 강세가 포함된 메타 키에서도 차단 규칙이 적용되도록 보완.
1
- || false !== stripos( remove_accents( $meta_key ), $ban )
$context
파라미터 추가- 의도: - 특정 컨텍스트에서만 추가적인 차단 규칙을 적용.
1
+ public function is_metakey_banned( $meta_key, $context = '' )
- 컨텍스트 기반 조건 추가
submission
컨텍스트일 때,usermeta_whitelist
에 포함되지 않은 키를 금지.
1
2
3
4
+ if ( ! $is_banned && 'submission' === $context
+ && ! in_array( $meta_key, UM()->form()->usermeta_whitelist, true ) ) {
$is_banned = true;
}
- banned_keys 목록
- 2.6.6 버전의 경우 악센트가 있는 문자를 허용하기에 공격자는 악센트를 이용해 banned_key 검사를 우회하여 관리자 권한을 가진 사용자를 생성할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public function __construct() {
global $wpdb;
$this->banned_keys = array(
'metabox',
'postbox',
'meta-box',
'dismissed_wp_pointers',
'session_tokens',
'screen_layout',
$wpdb->get_blog_prefix() . 'user-',
'dismissed',
'cap_key',
$wpdb->get_blog_prefix() . 'capabilities',
'managenav',
'nav_menu',
'user_activation_key',
'level_',
$wpdb->get_blog_prefix() . 'user_level',
);
// a list of keys that should never be in wp_usermeta
$this->update_user_keys = array(
'user_email',
'user_pass',
'user_password',
'display_name',
'user_url',
'role',
);
5. POC
This post is licensed under CC BY 4.0 by the author.