
Python-PoC für CVE-2026-92805: Der unauthentifizierte XHR des UVdesk-Installationsassistenten ermöglicht das Umschreiben von DATABASE_URL und die Erstellung von ROLE_SUPER_ADMIN über Fingerprint- und Admin-Modi.
UVdesk unauth Wizard Super-Admin POC
UVdesk Community Skeleton bis 1.1.8 — der Installation-Wizard-XHR (ConfigureHelpdesk) hat keine Authentifizierung und keine Installationsstatus-Prüfung. Ein nicht authentifizierter Aufrufer kann DATABASE_URL überschreiben und einen ROLE_SUPER_ADMIN erstellen. Es gibt kein öffentliches gepatchtes Tag (v1.1.9 liefert 404).
Nur für autorisierte Tests. Führe dies nicht gegen Systeme aus, die dir nicht gehören oder für die du keine Testberechtigung hast.
Voraussetzungen: Python 3, nur Standardbibliothek.
python3 cve-2026-92805-uvdesk-wizard-admin.py -u http://TARGET --test
python3 cve-2026-92805-uvdesk-wizard-admin.py -u http://TARGET --admin --email [email protected] --password 'PwnedAdmin1!'
python3 cve-2026-92805-uvdesk-wizard-admin.py -u https://TARGET --test --insecure
python3 cve-2026-92805-uvdesk-wizard-admin.py -u TARGET --test
| Flag | Was es bewirkt |
|---|---|
-u / --url | Helpdesk-Basis-URL (erforderlich). http:// oder https://. Ein Hostname ohne Schema wird zuerst als HTTPS versucht, dann als HTTP. http→https-Weiterleitungen behalten POST bei. Ungültige TLS-Zertifikate werden ohne Verifizierung erneut versucht; --insecure überspringt die Verifizierung von Anfang an |
--test | Nur Fingerprinting: POST /wizard/xhr/check-requirements (specification=php-version). Kein .env-Schreiben, kein Benutzer |
--admin | Vollständige Wizard-Kette: DB + Super-User in der PHP-Session speichern, DATABASE_URL schreiben, migrieren, ROLE_SUPER_ADMIN erstellen |
--email / --password / --name | Zu erstellender Super-Admin (Standardwerte [email protected] / PwnedAdmin1! / Pwned Admin) |
--db-host / --db-port / --db-user / --db-pass / --db-name | MySQL, wie die PHP-App es sieht (Standardwerte 127.0.0.1:3306 / uvdesk / uvdesk / uvdesk) |
--create-db | Den Wizard auffordern, CREATE DATABASE auszuführen, falls das Schema fehlt |
--insecure | TLS-Verifizierung überspringen |
--timeout | HTTP-Timeout in Sekunden (Standard 120; Migrationen können langsam sein) |
--test-Endpunkt: POST /wizard/xhr/check-requirements. Ein 200-JSON mit "version" / "status" ist PRESENT / VULNERABLE. Es trifft niemals load/configurations oder load/super-user. Nach einer abgeschlossenen Installation leitet GET / vom Wizard-HTML weg; die XHR-Routen antworten weiterhin. Das ist der Bug.
--admin ist nicht authentifiziert. Der Wizard denkt, er sei der Erstinstallations-Installer. --db-* sind kein MySQL-Client auf deiner Maschine; sie werden an die App gesendet, damit PHP sich verbinden kann (Same-Host 127.0.0.1 ist der übliche Fall).
Du musst nicht einen existierenden Schema-Namen entdecken. --db-name ist ein Name, den du wählst (Standard uvdesk). --create-db setzt das createDatabase-Flag des Wizards, sodass PHP CREATE DATABASE ausführt, falls dieser Name fehlt. Ohne --create-db ist ein fehlender Name NEED_DB („The requested database was not found“). Das Erstellen eines neuen Namens erfordert einen MySQL-Benutzer mit CREATE (ein abgeschotteter uvdesk@localhost, der nur Rechte auf uvdesk.* hat, kann uvdesk wiederverwenden, aber möglicherweise kein uvdesk_pwn erstellen). --test spricht nie mit MySQL.
Wenn bereits ein Super-Admin auf diesem Schema existiert, ist load/super-user ein No-Op — --create-db plus ein frischer --db-name erstellt ein Schema, das dir gehört, und richtet DATABASE_URL darauf aus.
Stdout: UVDESK, WIZARD_PAGE, PHP, STATUS, PRESENT, VULNERABLE, NOT_VULNERABLE, NOT_FOUND, NEED_DB, ADMIN, LOGIN.

CVE: CVE-2026-92805. Produkt: uvdesk/community-skeleton.