Skip to content
KitploitKITPLOIT
FerramentasBlog
Enviar
FerramentasBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
CVE-2026-18963-Exploit — Exploit para Keycloak CVE-2026-18963 que permite a tomada de conta não autenticada via bypass de redefinição de credenciais. Inclui detecção segura, prova não destrutiva, tomada de conta completa, enumeração de nomes de usuário e um laboratório com versões vulneráveis e corrigidas. | Kitploit
Ferramentas/GitHubGitHub/snizi/cve-2026-18963-exploit
Autenticação e AutorizaçãoAnálise de VulnerabilidadesExploraçãoExploração de Aplicações WebTestes de Penetração
GitHubsnizi/cve-2026-18963-exploit

CVE-2026-18963-Exploit

Ver Repositório

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →

Sobre

71há 4 diasAinda não revisado

Exploit para Keycloak CVE-2026-18963 que permite a tomada de conta não autenticada via bypass de redefinição de credenciais. Inclui detecção segura, prova não destrutiva, tomada de conta completa, enumeração de nomes de usuário e um laboratório com versões vulneráveis e corrigidas.

Compartilhar

CVE-2026-18963 — Bypass de reset-credentials do Keycloak → tomada de conta não autenticada

CVE Affected Python Dependencies

Conhecendo apenas um nome de usuário ou endereço de e-mail, um atacante não autenticado define uma senha arbitrária em qualquer conta do Keycloak. O e-mail de redefinição de senha é enviado à vítima real e nunca é necessário — o atacante nunca lê uma caixa de entrada, nunca clica em um link e não possui nenhuma credencial ou sessão prévia.

Afetados: Keycloak 26.0.0 – 26.7.1. Corrigido na versão 26.7.2.


Estou vulnerável?

Um único comando. Nenhum nome de usuário válido é necessário e sem efeitos colaterais — ele não envia e-mail, não grava em nenhuma conta e para antes da etapa explorável.```bash git clone https://github.com/Snizi/CVE-2026-18963-Exploit cd CVE-2026-18963-Exploit

python3 cve_2026_18963_poc.py
--base https://sso.example.com --realm YOUR_REALM
--client-id account
--redirect-uri https://sso.example.com/realms/YOUR_REALM/account/
--safe-check

root@kitploit:~
Python 3.9+, apenas biblioteca padrão. Nada para instalar.

| Saída | Veredicto | Significado |
|:---:|---|---|
| `0` | 🔴 **VULNERÁVEL** | o portão de e-mail estacionado foi servido — o bug em si |
| `2` | 🟢 **CORRIGIDO** | o fluxo desviou para o login e permaneceu lá (correção #51844 presente) |
| `2` | 🟡 **MITIGADO** | redefinição de credenciais inacessível — *Esqueci a senha* está desativado. **Não é uma correção.** |
| `3` | ⚪ **INCONCLUSIVO** | resposta não reconhecida — **não interprete isso como aprovação** |

Execute por realm — *Esqueci a senha* é uma configuração por realm, e `master` conta.
Detalhes, e por que a verificação não precisa de usuário e não altera nada, em
[§4a](#4a-safe-detection---safe-check--start-here).

**Já sabe que está exposto?** Vá para [remediação](#8-remediation) e
[detecção / caça a ameaças](#9-detection).

### Experimente sem um alvo

O repositório inclui um laboratório que inicia uma versão vulnerável **26.7.1** e uma corrigida **26.7.2**
lado a lado contra um realm idêntico, além de uma caixa de correio para observar o e-mail de redefinição
chegar e permanecer não lido enquanto a conta é assumida:```bash
cd lab && docker compose up -d

python3 ../cve_2026_18963_poc.py --base http://localhost:8080 \
  --realm poc --client-id poc-app --safe-check   # VULNERABLE
python3 ../cve_2026_18963_poc.py --base http://localhost:8100 \
  --realm poc --client-id poc-app --safe-check   # PATCHED

⚠️ Apenas para testes autorizados

Este repositório existe para defensores, respondedores a incidentes e testadores de penetração autorizados. Execute-o contra sistemas que você possui ou para os quais possui permissão por escrito para testar. Tudo aqui vem com um laboratório vulnerável autocontido (lab/), portanto nada externo precisa ser tocado para aprender como a falha funciona. Apontá-lo para infraestrutura de terceiros sem autorização é ilegal na maioria das jurisdições e não é algo que este projeto apoia.

Referências: keycloak#51833 · GHSA-4gv3-mc9p-5wqc · correção keycloak#51844


Conteúdo

  • 1. Causa raiz
  • 2. Versões afetadas (incluindo linhas legadas)
  • 3. O laboratório
  • 4. Utilização
    • 4a. Deteção segura (--safe-check) — comece aqui
    • 4b. Prova não destrutiva (--check)
    • 4c. Assunção total de controlo
    • 4d. Enumeração de nomes de utilizador (--enum)
  • 5. Temas de início de sessão personalizados
  • 6. Lacuna conhecida — PKCE
  • 7. Validação efetuada
  • 8. Remediação
  • 9. Deteção
  • Autor

1. Causa raiz

Duas falhas encadeadas. Nenhuma é explorável isoladamente.

Falha 1 — um sinalizador sem âmbito e persistente

services/src/main/java/org/keycloak/authentication/DefaultAuthenticationFlow.java

processAction() — qualquer POST que transporte a chave de formulário tryAnotherWay:```java processor.getAuthenticationSession().setAuthNote( AuthenticationProcessor.AUTHENTICATION_SELECTOR_SCREEN_DISPLAYED, "true"); return createSelectAuthenticatorsScreen(model);

root@kitploit:~
A nota é um **booleano simples, sem registro de qual conjunto de execução a definiu**. Ela é
limpa apenas no ramo que trata um parâmetro `authenticationExecution` enviado. Omita esse parâmetro — como este PoC faz em todo o fluxo — e a flag permanece
definida durante toda a vida da sessão de autenticação.

`processFlow()` — enquanto a flag for verdadeira, a avaliação normal do fluxo é ignorada:```java
if (Boolean.parseBoolean(authSession.getAuthNote(AUTHENTICATION_SELECTOR_SCREEN_DISPLAYED))) {
    String lastExecutionId = authSession.getAuthNote(CURRENT_AUTHENTICATION_EXECUTION);
    if (lastExecutionId != null) {
        AuthenticationExecutionModel executionModel =
            realm.getAuthenticationExecutionById(lastExecutionId);
        if (executionModel != null)
            return createSelectAuthenticatorsScreen(executionModel);   // <-- attacker-usable form
    }
}

It renders a submittable form aimed at whatever execution is currently parked, instead of keeping the session pinned on "waiting for the e-mail".

The glue is processResult() case FORK: — when Send Reset Email fires it stamps CURRENT_AUTHENTICATION_EXECUTION = <reset-credential-email execution id> and forks the browser to the login page. The parked execution is precisely the e-mail gate.

Defect 2 — the e-mail gate never checks the action token

`services/src/main/java/org/keycloak/authentication/authenticators/resetcred/ResetCredentialEmail.java````java @Override public void action(AuthenticationFlowContext context) { context.getUser().setEmailVerified(true); context.success(); }

root@kitploit:~
Unconditional. Nothing verifies that the flow was resumed by a valid action token,
so *reaching* `action()` is treated as equivalent to proving mailbox control.

### The chain```
tryAnotherWay POST            → sticky AUTHENTICATION_SELECTOR_SCREEN_DISPLAYED="true"
submit victim identifier      → mail sent to victim, e-mail execution parked (FORK)
re-enter reset-credentials    → sticky flag serves a form targeting the parked e-mail execution
POST that form                → ResetCredentialEmail.action() → success() → gate bypassed
                              → flow advances to UPDATE_PASSWORD → attacker sets the password

Seis pedidos HTTP, sem autenticação, sem parâmetro authenticationExecution em nenhum momento.

A correção (PR #51844)

  • A nota agora armazena model.getId(), e processFlow() a respeita somente quando ela é igual a CURRENT_AUTHENTICATION_EXECUTION; caso contrário, remove-a. No ataque, os dois diferem (id de choose-user vs. id de e-mail-gate) — exatamente o que o patch detecta, e exatamente o sinal em que --safe-check se baseia.
  • ResetCredentialEmail.action() agora exige context.getUser().getId().equals(authNote(ACTION_TOKEN_USER_ID)) e, caso contrário, falha com INVALID_USER.

2. Versões afetadas (incluindo linhas legadas)

O que "legado" significa para este CVE

  • As versões legadas não são automaticamente seguras — elas são seguras por um motivo específico. A nota booleana persistente foi introduzida na 26.0.0 pelo commit 6a9e60bb, que adicionou a tela de seletor de autenticador "Try another way" ao fluxo de redefinição. Qualquer versão mais antiga simplesmente não possui esse caminho de código. Isso inclui as distribuições antigas baseadas em WildFly e o RH-SSO 7.x, que não são afetados por este bug, embora permaneçam em fim de vida e vulneráveis a muitos outros. Permanecer em uma build legada não é uma remediação.
  • As linhas legadas 26.x são o problema real. 26.7.2 é a única versão corrigida publicada para o trem da comunidade. Se uma implantação estiver em 26.0 – 26.6, não há nenhuma versão de patch nessa linha — a correção exige um upgrade de versão menor, não uma versão pontual. As tags 26.4.15 / 26.6.6 são backports do fornecedor e não são intercambiáveis com as imagens da comunidade.
  • Como muitas implantações de longa duração estão fixadas em um 26.x mais antigo por motivos de compatibilidade, "estamos totalmente corrigidos na nossa linha" é uma suposição comum e incorreta aqui. Verifique a build em execução, não a política de atualização.

Pré-condições: o realm tem Forgot password habilitado e seu fluxo de redefinição de credenciais vinculado usa o autenticador integrado reset-credential-email.


3. O laboratório

O repositório inclui tanto um Keycloak vulnerável quanto um corrigido, importando o mesmo realm idêntico, além do Mailpit para capturar o e-mail de redefinição — para que você possa vê-lo chegar e permanecer não lido enquanto a conta é assumida.```bash cd lab docker compose up -d

root@kitploit:~
| Service | URL | Version |
|---|---|---|
| `kc-vuln` | http://localhost:8080 | 26.7.1 — **vulnerável** |
| `kc-patched` | http://localhost:8100 | 26.7.2 — **controle corrigido** |
| `kc-mailpit` | http://localhost:8025 | caixa de correio da vítima |

Realm `poc`, cliente público `poc-app`, usuário `victim` / `OriginalPassw0rd!`, administrador do Keycloak
`admin` / `admin`.

Fixar diferentes builds com `KC_VULN_VERSION` / `KC_PATCHED_VERSION`:```bash
KC_VULN_VERSION=26.5.7 docker compose up -d keycloak-vuln

Entre execuções, lab/reset-victim.sh restaura a senha da vítima (KC=http://localhost:8100 lab/reset-victim.sh tem como alvo a instância corrigida).

lab/legit_reset.py executa um reset genuíno ao extrair o link do action-token do Mailpit e clicar nele. É a amostra de controle para o trabalho de detecção na §9 — execute-o e o exploit contra o mesmo realm e depois compare os traces.

Teardown: docker compose down -v.


4. Uso

Python 3.9+, apenas biblioteca padrão — sem dependências, roda em qualquer jump box.``` --base Keycloak base URL (e.g. https://sso.example.com) --realm realm name --client-id any enabled public client with the standard flow --redirect-uri a URI permitted by that client (default http://localhost:9999/callback) --insecure skip TLS verification --verbose log every HTTP request --dump FILE write the response body of a failing step to FILE

root@kitploit:~
`--client-id` pode ser qualquer cliente público habilitado com o fluxo padrão. O cliente
`account` integrado existe em todos os realms e é a escolha confiável, mas restringe
os redirect URIs, então `--redirect-uri` **deve** ser
`<base>/realms/<realm>/account/` — o padrão é rejeitado e o passo 1 falha.

### 4a. Detecção segura (`--safe-check`) — comece aqui

Não precisa de **nome de usuário válido** e **não tem efeitos colaterais**. Este é o probe a usar
quando você não deve perturbar o alvo.```bash
python3 cve_2026_18963_poc.py \
  --base https://sso.example.com --realm corp \
  --client-id account \
  --redirect-uri https://sso.example.com/realms/corp/account/ \
  --safe-check

Por que não precisa de utilizador e não envia e-mail. ResetCredentialEmail.authenticate() também bifurca para um utilizador desconhecido:```java if (user == null) { context.forkWithSuccessMessage(EMAIL_SENT); return; }

root@kitploit:~
`processResult()` `case FORK:` portanto estaciona `CURRENT_AUTHENTICATION_EXECUTION`
na execução do e-mail **mesmo que ninguém tenha sido encontrado** — e nenhum e-mail é enviado,
porque não há ninguém para quem enviar. A sonda para no discriminador e nunca
faz POST no gate, então `action()` nunca é executada: sem NPE no alvo, sem escrita
em `emailVerified`, sem e-mail, sem conta tocada.

**Ele afirma apenas o sinal positivo.** VULNERÁVEL ⟺ o passo 5 retorna um formulário
ainda dentro de `login-actions/reset-credentials` cujo `execution` difere da execução
de escolha de usuário. Esse *é* o bug: a nota obsoleta
`AUTHENTICATION_SELECTOR_SCREEN_DISPLAYED` servindo o gate de e-mail estacionado.
Ambas as metades importam — o caminho prova que ainda estamos no fluxo de redefinição, o id
de execução diferente prova que é o gate de e-mail e não um re-render.

Qualquer outra coisa **não** é silenciosamente chamada de corrigida. PATCHED exige sua própria evidência
(fork para `login-actions/authenticate` *e* um campo de senha presente); tudo o que
resta é INCONCLUSIVO e precisa de um humano. Um design anterior tratava "não é o
formulário do gate" como corrigido, o que silenciosamente transforma todo tema personalizado, página de erro, bloqueio
de WAF e intersticial em um atestado de saúde falso.

### 4b. Prova não destrutiva (`--check`)

Conduz toda a cadeia, mas para no formulário Update Password. Alcançar esse formulário
sem um token de ação é conclusivo.```bash
python3 cve_2026_18963_poc.py \
  --base https://sso.example.com --realm corp \
  --client-id account \
  --redirect-uri https://sso.example.com/realms/corp/account/ \
  --victim [email protected] --check

Dois efeitos colaterais são inevitáveis, porque ocorrem a montante do formulário de senha — declare-os no escopo do engajamento:

  • um e-mail de redefinição de senha é enviado à vítima real (o passo 4 é uma solicitação de redefinição genuína), e
  • o action() vulnerável define emailVerified = true na conta.

Nenhuma credencial é modificada. Prefira uma conta de teste dedicada.

4c. Assunção total da conta

Apenas para demonstração em laboratório ou autorizada explicitamente.```bash python3 cve_2026_18963_poc.py
--base http://localhost:8080 --realm poc --client-id poc-app
--victim victim --new-password 'PoCPassw0rd!1'

root@kitploit:~
Sair `0` vulnerável · `2` não explorável · `1` senha alterada, mas a confirmação
da concessão falhou (aponte `--verify-client-id` para um cliente com Direct Access Grants).

Concluir o fluxo também retorna um **código de autorização OIDC para a vítima**, portanto
a tomada de controle é imediata — não é necessário um segundo login com a nova senha.

### 4d. Enumeração de nomes de usuário (`--enum`)

A mesma falha é um oráculo de nomes de usuário, e mais forte do que o Keycloak normalmente
permite. `ResetCredentialEmail.authenticate()` deliberadamente retorna um idêntico
*"You should receive an email shortly"* para usuários reais e desconhecidos, portanto o
próprio formulário de redefinição não pode ser usado para enumerar — essa defesa ainda se
mantém no passo 4. Ela se quebra no **passo 6**, onde `action()` desreferencia o usuário
incondicionalmente (`context.getUser().setEmailVerified(true)`).

| Identificador | Passo 6 | Veredito |
|---|---|---|
| usuário real | `200`, chega ao formulário de Update Password | VÁLIDO |
| usuário desconhecido | `400` (página de erro NPE) | INVÁLIDO |```bash
python3 cve_2026_18963_poc.py \
  --base http://localhost:8080 --realm poc --client-id poc-app \
  --enum candidates.example.txt

Nunca altera uma palavra-passe. Sai com 0 se algum identificador for resolvido, 2 caso contrário.

Custo por sonda — leia antes de executar. Alcançar o oráculo requer concluir o passo 4, pelo que cada sonda contra uma conta real envia a essa pessoa um e-mail genuíno de reposição de palavra-passe e define emailVerified = true no seu registo. Não é uma verificação silenciosa: é visível para o titular da conta e altera os seus dados. Uma wordlist de 5.000 nomes são 5.000 e-mails para pessoas reais e 5.000 contas alteradas.

Use-o para demonstrar que o oráculo existe num punhado de identificadores para o relatório — não para recolher um diretório. As proteções são deliberadamente conservadoras:

  • --enum-max N recusa listas com mais de N itens (padrão 25)
  • --enum-delay SEC pausa entre sondas (padrão 2.0)

Aumentar qualquer um deles deve ser uma decisão consciente registada nas notas do engagement.

Ângulo para o relatório: isto anula um controlo anti-enumeração que a Keycloak implementou de propósito. Vale a pena documentar como uma descoberta própria juntamente com a tomada de controlo, e elimina "os nossos nomes de utilizador não são adivinháveis" como fator atenuante.


5. Temas de login personalizados

Qualquer implementação séria inclui um tema de login personalizado, e os temas personalizados renomeiam ou removem os ids de elementos padrão (kc-form-login, kc-reset-password-form, kc-select-credential-form, kc-passwd-update-form). Uma ferramenta que dependa desses ids reporta um falso negativo exatamente nas implementações que mais importam — esta reportava, antes de ser reescrita. Temas vistos em produção usam ids como id="login-form" e incluem uma âncora de esqueci a palavra-passe com um href vazio.

Este PoC depende, portanto, de nada que um tema controle:

  • Apenas URLs de ação de formulários. Cada decisão é tomada a partir do action= dos formulários na página — login-actions/reset-credentials, login-actions/authenticate, login-actions/required-action — e do parâmetro de consulta execution dentro deles. Esses caminhos são gerados pelo próprio LoginActionsService da Keycloak, não pelo tema.
  • Sem ids de elementos. Faça grep ao código-fonte: não há um único id kc-* nele.
  • Sem texto de mensagens. As strings de resposta são localizadas — um realm alemão responde "Reset Credential nicht erlaubt", e corresponder a "You should receive an email" falha em todos os realms não ingleses.
  • Nunca segue uma ligação "Esqueci a palavra-passe" do tema. A ligação pode estar ausente, vazia, controlada por JavaScript, ou apontar para fora da Keycloak por completo — nada disso diz algo sobre se o endpoint está acessível. A ferramenta constrói /realms/<realm>/login-actions/reset-credentials?client_id=…&tab_id=… e testa-o diretamente, retirando tab_id de qualquer formulário que a página de login exponha.

Se um alvo ainda devolver INCONCLUSIVE, execute com --verbose --dump out.html e leia a resposta — a ferramenta recusa-se deliberadamente a adivinhar.


6. Lacuna conhecida — PKCE

Um cliente que imponha PKCE rejeita o passo 1 com Missing parameter: code_challenge_method. Isto é reportado como INCONCLUSIVE (saída 3), nunca como aprovação. Até que o suporte a PKCE seja implementado, um realm cujo único cliente público utilizável exija PKCE não pode ser verificado com esta ferramenta — experimente o cliente account integrado, que normalmente não o impõe.


7. Validação efetuada

Cada execução abaixo é contra o laboratório neste repositório, usando o código como publicado.

Duas descobertas que valem a pena assinalar para além do texto do advisory:

  1. Contas sem endereço de e-mail são exploráveis. ResetCredentialEmail.authenticate() segue o caminho forkWithSuccessMessage quando user.getEmail() é null, o que ainda estaciona a execução via case FORK:. O mesmo aplica-se a uma falha no envio de SMTP — um servidor de correio avariado ou ausente não é uma mitigação. Isto é diretamente relevante para realms federados com AD/LDAP, onde as contas frequentemente não têm atributo de correio.
  2. Concluir o fluxo inicia sessão do atacante como a vítima. O redirecionamento final transporta um código de autorização OIDC válido, pelo que a conta fica comprometida no momento em que o formulário de palavra-passe é submetido.

MFA não é uma mitigação. O fluxo padrão de reset-credentials não contém um passo OTP, e uma vez ultrapassado, o atacante pode remover os fatores registados da vítima.


8. Remediação

Correção: atualize. 26.7.2 para builds da comunidade, ou a tag de backport do fornecedor correspondente à sua subscrição. Tudo o resto é uma solução provisória.

Mitigações interinas, melhor primeiro:

  1. Desative Esqueci a palavra-passe por realm (Realm settings → Login). Confirmado como eficaz — o fluxo devolve HTTP 400 e não pode ser iniciado. Verifique todos os realms, incluindo master.
  2. Desative a execução Reset Password no fluxo reset-credentials vinculado. Funciona, mas a página de login ainda oferece a ligação, pelo que a experiência do utilizador é fraca. Útil onde um tema personalizado ignora a definição do realm.
  3. Adicione um autenticador obrigatório (OTP/WebAuthn) após o passo de e-mail no fluxo de reposição. Isto não fecha a bypass — apenas limita a tomada de controlo total a contas que tenham efetivamente registado esse fator.

Realms cujo fluxo de reposição vinculado seja totalmente personalizado e nunca invoque reset-credential-email não são exploráveis através deste caminho.


9. Deteção

A Keycloak não emite nenhum evento de "action token ignorado", pelo que a deteção é heurística. Execute lab/legit_reset.py juntamente com o exploit para gerar ambos os traços e comparar.

  • Registos do reverse-proxy / ingress — o sinal mais forte. Uma reposição legítima mostra um GET /login-actions/action-token?... (a vítima a clicar no e-mail) antes da alteração da palavra-passe. A bypass não tem esse GET. Em vez disso, mostra um POST para login-actions/reset-credentials cujo corpo contém tryAnotherWay, seguido de um segundo POST para o mesmo caminho com um corpo vazio, e depois o formulário de palavra-passe. Um POST tryAnotherWay dentro do fluxo de reposição não é algo que a UI padrão produza em uso normal.
  • Eventos de administração: SEND_RESET_PASSWORD seguido de UPDATE_PASSWORD a partilhar o mesmo code_id dentro de poucos segundos — sub-segundo no laboratório. Um utilizador com o e-mail já aberto também pode parecer rápido, por isso corrobore com os registos do proxy.
  • Contas cujo emailVerified mudou para true sem um evento VERIFY_EMAIL correspondente são um indicador de apoio útil, e um que o atacante não consegue evitar deixar.

A ausência de eventos não prova nada se o registo de eventos ou a retenção estiverem desativados. Verifique a janela de retenção antes de concluir que uma implementação não foi atingida.


Autor

Snizi — github.com/Snizi — [email protected]

Publicado sob a Licença MIT. Issues e PRs bem-vindos — particularmente suporte a PKCE e peculiaridades adicionais de temas do mundo real.

Baixar ferramenta
LinhaVulnerávelCorreção da comunidade
Legada (Keycloak baseado em WildFly, ≤ 17)não afetada—
Quarkus 17 – 25.xnão afetada—
26.026.0.0 – 26.0.17nenhuma
26.126.1.0 – 26.1.5nenhuma
26.226.2.0 – 26.2.16nenhuma
26.326.3.0 – 26.3.5nenhuma
26.426.4.0 – 26.4.1426.4.15 (tag de backport do fornecedor)
26.526.5.0 – 26.5.7nenhuma
26.626.6.0 – 26.6.526.6.6 (tag de backport do fornecedor)
26.726.7.0 – 26.7.126.7.2
ExitVerdictSignificado
0VULNERÁVELo gate de e-mail estacionado foi servido — o bug em si
2CORRIGIDOo fluxo bifurcou para o login e permaneceu lá (correção #51844 presente)
2MITIGADOreset-credentials inacessível — Forgot password está desativado. Não é uma correção.
3INCONCLUSIVOresposta não reconhecida — não interprete isto como aprovação
TesteAlvoResultado
--safe-check26.7.1VULNERABLE, saída 0 — gate de e-mail servido (execution ≠ choose-user)
--safe-check26.7.2PATCHED, saída 2 — bifurcado para login e permaneceu
--safe-check, Esqueci a palavra-passe desativado26.7.2MITIGATED, saída 2 — HTTP 400, fluxo inacessível
Tomada de controlo completa26.7.1saída 0 — palavra-passe definida, código OIDC emitido, password grant confirma
Tomada de controlo completa26.7.2saída 2 — bloqueado no passo 5, conta intocada
--check26.7.1alcançou UPDATE_PASSWORD; palavra-passe verificada inalterada depois
--enum26.7.1victim e [email protected] VALID, does-not-exist INVALID
Estado da credencial após tomada de controlo26.7.1nova palavra-passe → 200, palavra-passe antiga → 400
Estado da credencial após execução bloqueada26.7.2palavra-passe antiga → 200, palavra-passe do atacante → 400
Caixa de correio da vítimaMailpite-mails de reposição entregues e não lidos; a ligação do action-token nunca é obtida