Ultimate Member에서 발생한 권한 상승
Ultimate Member는 활성 설치수가 200,000이 넘는 플러그인으로 사용자 등록, 멤버십 기능을 제공합니다. 2020년 11월 wp_capabilities의 기능을 악용한 권한 상승 취약점(CVE-2020-36155)이 2.1.11 이하 버전에서 발견됐습니다.
CVE-2020-36155은 사용자 등록 기능에서 발생합니다. 가입하는 과정에서 임의의 데이터를 추가해 권한 상승이 가능했습니다. 간단하게 설명해 가입 시 '권한=관리자'라는 값을 추가하면 관리자로 권한이 설정되는 취약점입니다. 취약점은 사용자의 입력 값을 필터링하지 않고 그대로 데이터베이스에 업데이트하기 때문에 발생합니다.
이후 이 취약점은 2.1.12 버전에서 패치되었습니다. Ultimate Member는 블랙리스트 기반 필터링을 사용합니다. 허용되지 않은 메타 데이터 키를 설정하고 if 문을 통해 필터링을 합니다. 이로 인해 사용자는 임의의 값(예를 들어, '권한=관리자' )을 입력할 수 없었습니다. 하지만 2023년에 이 필터링을 우회한 권한 상승 취약점(CVE-2023-3460)이 2.6.7 이하의 버전에서 다시 발생하였습니다.
CVE-2023-3460은 구현된 필터링을 악센트 문자( à, è, ì, ò, ù )를 통해 우회합니다. 워드프레스는 악센트 문자를 일반 문자처럼 받아들여 데이터베이스에 저장합니다. 하지만, 코드로 구현된 필터링은 이 문자를 잡아내지 못했으며, 이를 통해 권한 상승이 가능했습니다. 이후 화이트리스트 기반으로 필터링을 구현해 취약점을 패치했습니다.
아래에서 코드와 실습을 통해 살펴보겠습니다.
wp_capability 란?
Wordpress는 wp_capabilities로 사용자의 역할과 권한을 관리합니다.
워드프레스는 사용자의 기본 값(아이디, 비밀번호, 이메일 등)을 wp_user 테이블, 기타 값(권한, 닉네임 등)을 wp_usermeta 테이블에 저장합니다. wp_capabilities는 wp_usermeta 테이블에서 사용자 역할과 권한 데이터를 저장합니다.
아래 예시 데이터를 보면 사용자의 권한이 administrator 저장된 것을 확인할 수 있습니다.
* wp_capabilities 및 워드프레스 테이블에 대한 자세한 설명은 아래에서 확인하실 수 있습니다.
2024.02.15 - [Bug Bounty/PoC 분석] - ProfilePress 권한 상승 취약점 분석(Exploit for CVE-2021-34621)
CVE-2020-36155에 대한 이해
2020년에 먼저 발생한 CVE-2020-36155를 먼저 살펴보겠습니다.
플러그인은 register 페이지에서 입력된 데이터로 데이터베이스의 값을 업데이트 합니다. 이 과정에서 별도의 필터링을 하지 않아 공격자가 임의의 메타 키를 삽입해 관리자 권한을 얻을 수 있습니다.
do_action( 'um_before_save_registration_details', $this->id, $submitted );
update_user_meta( $this->id, 'submitted', $submitted );
$this->update_profile( $submitted );
function update_profile( $changes ) {
$args['ID'] = $this->id;
$changes = apply_filters( 'um_before_update_profile', $changes, $args['ID'] );
foreach ( $changes as $key => $value ) {
if ( ! in_array( $key, $this->update_user_keys ) ) {
if ( $value === 0 ) {
update_user_meta( $this->id, $key, '0' );
} else {
update_user_meta( $this->id, $key, $value );
}
} else {
$args[ $key ] = esc_attr( $changes[ $key ] );
}
}
위는 user_meta를 업데이트하는 부분의 코드입니다. 데이터를 받아오는 과정부터 업데이트 하는 과정까지 필터링 로직이 구현되지 않았습니다. 공격자는 register 프로세스에서 wp_capabilities[administrator] 값을 추가하면 관리자 권한을 얻을 수 있습니다. 아래 실습을 통해 취약점을 더 이해해보도록 하겠습니다.
CVE-2020-36155 PoC
취약점 정보
Vulnerability type: Privilege Escalation
CVSS Severity Score: 10
Affected Versions: < 2.1.12
Patched Available: YES
PoC Link:
Ultimate Member < 2.1.12 - Unauthenticated Privilege Escalation via User Meta
취약한 버전 파일:
실습
1. PoC 테스트를 위해 Ultimate Member 2.6.6 버전으로 테스트를 진행합니다.
2. 플러그인이 활성화되면 register 페이지에 데이터를 입력하고 등록합니다.
3. Burp Suite를 통해 요청을 가로챈 후 기존의 요청에서 페이로드 wp_capabilities[administrator]=0를 추가해 전송합니다.
4. WordPress 대시보드에서 사용자 권한이 관리자로 설정된 것을 확인합니다.
취약점 패치와 CVE-2023-3460에 대한 이해
CVE-2020-36155 취약점 이후 Ultimate Member는 register 과정에 필터링 로직을 추가했습니다. 아래 is_metakey_banned()를 통해 허용되지 않은 입력을 차단합니다. 필터링은 금지된 메타데이터 목록을 사용하기 때문에 블랙리스트 기반 방식으로 구현되었습니다.
public function update_profile( $changes ) {
$this->updating_process = true;
$args['ID'] = $this->id;
$changes = apply_filters( 'um_before_update_profile', $changes, $args['ID'] );
//사용자 메타 데이터 키 목록 사용
foreach ( $changes as $key => $value ) {
if ( $this->is_metakey_banned( $key ) ) {
continue;
}
if ( ! in_array( $key, $this->update_user_keys, true ) ) {
if ( $value === 0 ) {
update_user_meta( $this->id, $key, '0' );
} else {
update_user_meta( $this->id, $key, $value );
}
} else {
$args[ $key ] = $value;
}
}
public function is_metakey_banned( $meta_key ) {
$is_banned = false;
//제출된 메타데이터가 금지된 메타데이터 목록에 있으면 ture를 반환해 break.
foreach ( $this->banned_keys as $ban ) {
if ( is_numeric( $meta_key ) || false !== stripos( $meta_key, $ban ) ) {
$is_banned = true;
break;
}
}
//필터링에 걸리지 않으면 false를 반환하고 사용자 등록을 허용.
return $is_banned;
}
CVE-2023-3460 필터링은 악센트 문자 (à) 를 통해 우회되었습니다.
WordPress는 일부 악센트(강세표시) 문자를 기본 문자로 수용합니다. 사용자가 악센트 문자와 함께 메타데이터를 제출하면 is_metakey_banned()는 이를 감지하지 못해 사용자 등록을 허용하고 공격자는 관리자 권한을 얻을 수 있습니다. 따라서 wp_càpabilities[administrator]를 통해 사용자 권한 상승 취약점이 발생합니다.
data["wp_c𝙖pabilities[administrator]"] = "0"
#data["wp_càpàbilities[administrator]"] = ""
CVE-2023-3460 PoC
취약점 정보
Vulnerability type: Privilege Escalation
CVSS Severity Score: 9.8
Affected Versions: =< 2.6.7
Patched Available: YES
PoC Link:
Analyzing the Ultimate Member Plugin Vulnerability - CVE-2023-3460 - CYFIRMA
취약한 버전 파일:
실습
1. PoC 테스트를 위해 Ultimate Member 2.6.6 버전으로 테스트를 진행합니다.
2. 플러그인이 활성화되면 register 페이지에 데이터를 입력하고 등록 요청을 보냅니다.
3. Burp Suite를 통해 요청을 가로챈 후 기존의 요청에서 페이로드 wp_càpabilities[administrator]=1를 추가해 전송합니다.
4. WordPress 대시보드에서 사용자 권한이 관리자로 설정된 것을 확인합니다.
취약점 패치
Ultimate Member는 취약점을 2.6.7 버전에서 수정했습니다. 수정된 내용은 아래와 같습니다.
public function is_metakey_banned( $meta_key, $context = '' ) {
$is_banned = false;
foreach ( $this->banned_keys as $ban ) {
if ( is_numeric( $meta_key ) || false !== stripos( $meta_key, $ban ) || false !== stripos( remove_accents( $meta_key ), $ban ) ) {
$is_banned = true;
break;
}
}
if ( ! $is_banned && 'submission' === $context && ! in_array( $meta_key, UM()->form()->usermeta_whitelist, true ) ) {
$is_banned = true;
}
return $is_banned;
}
취약점이 발생했던 is_metakey_banned()가 수정되었습니다. 해당 함수는 in_array( $meta_key, UM()->form()->usermeta_whitelist로 화이트 리스트 검증을 수행합니다.
화이트 리스트의 필터는 0: user_login, 1: form_id, 2: timestap 세개의 필드로만 구성됩니다. 따라서 공격자는 강조표시 문자를 통해 권한 우회 취약점을 악용할 수 없습니다.
참고 블로그
https://wordpress.stackexchange.com/questions/103492/whats-the-meaning-of-the-field-wp-capabilities-in-table-wp-usermeta
https://sploitus.com/exploit?id=5434DDF9-58E8-5271-BBBC-66EED3F5A6C8
'Bug Bounty > PoC 분석' 카테고리의 다른 글
[CVE Study]ProfilePress 권한 상승 취약점 분석(Exploit for CVE-2021-34621) (0) | 2024.02.15 |
---|