
Python PoC для CVE-2026-92805: неаутентифицированный XHR мастера установки UVdesk позволяет перезаписать DATABASE_URL и создать ROLE_SUPER_ADMIN через режимы fingerprint и admin.
UVdesk unauth wizard super-admin POC
UVdesk Community Skeleton вплоть до 1.1.8 — XHR установочного мастера (ConfigureHelpdesk) не имеет аутентификации и проверки состояния установки. Неаутентифицированный вызывающий может перезаписать DATABASE_URL и создать ROLE_SUPER_ADMIN. Публичного исправленного тега нет (v1.1.9 возвращает 404).
Только для авторизованного тестирования. Не запускайте это против систем, которыми вы не владеете или на тестирование которых у вас нет разрешения.
Требуется: Python 3, только стандартная библиотека.
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
| Флаг | Что делает |
|---|---|
-u / --url | Базовый URL хелпдеска (обязательно). http:// или https://. Имя хоста без схемы сначала пробуется как HTTPS, затем HTTP. Редиректы http→https сохраняют POST. Плохие TLS-сертификаты повторяются без проверки; --insecure пропускает проверку с самого начала |
--test | Только фингерпринтинг: POST /wizard/xhr/check-requirements (specification=php-version). Без записи .env, без пользователя |
--admin | Полная цепочка мастера: сохранение БД + суперпользователя в PHP-сессии, запись DATABASE_URL, миграция, создание ROLE_SUPER_ADMIN |
--email / --password / --name | Супер-админ для создания (по умолчанию [email protected] / PwnedAdmin1! / Pwned Admin) |
--db-host / --db-port / --db-user / --db-pass / --db-name | MySQL так, как его видит PHP-приложение (по умолчанию 127.0.0.1:3306 / uvdesk / uvdesk / uvdesk) |
--create-db | Попросить мастер выполнить CREATE DATABASE, если схема отсутствует |
--insecure | Пропустить проверку TLS |
--timeout | Таймаут HTTP в секундах (по умолчанию 120; миграции могут быть медленными) |
Эндпоинт --test: POST /wizard/xhr/check-requirements. 200 JSON с "version" / "status" — это PRESENT / VULNERABLE. Он никогда не обращается к load/configurations или load/super-user. После завершённой установки GET / перенаправляет прочь от HTML мастера; XHR-маршруты всё ещё отвечают. Это и есть баг.
--admin неаутентифицирован. Мастер думает, что это установщик первого запуска. --db-* — это не MySQL-клиент на вашей машине; они отправляются в приложение, чтобы PHP мог подключиться (тот же хост 127.0.0.1 — обычный случай).
Вам не нужно обнаруживать существующее имя схемы. --db-name — это имя, которое вы выбираете (по умолчанию uvdesk). --create-db устанавливает флаг createDatabase мастера, чтобы PHP выполнил CREATE DATABASE, если это имя отсутствует. Без --create-db отсутствующее имя — это NEED_DB («The requested database was not found»). Создание нового имени требует MySQL-пользователя с CREATE (заблокированный uvdesk@localhost, имеющий права только на uvdesk.*, может переиспользовать uvdesk, но может не создать uvdesk_pwn). --test никогда не обращается к MySQL.
Если супер-админ уже существует на этой схеме, load/super-user — это no-op — --create-db плюс свежий --db-name поднимает схему, которой вы владеете, и направляет DATABASE_URL на неё.
Stdout: UVDESK, WIZARD_PAGE, PHP, STATUS, PRESENT, VULNERABLE, NOT_VULNERABLE, NOT_FOUND, NEED_DB, ADMIN, LOGIN.

CVE: CVE-2026-92805. Продукт: uvdesk/community-skeleton.