Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
Strumenti/GitHubGitHub/ivanesk315/cve-2026-18963
Analisi delle VulnerabilitàExploitSfruttamento di Applicazioni WebSicurezza WebPenetration TestingGestione Identità e Accessi (IAM)AutenticazioneApprendimento e FormazioneLab e Pratica
GitHubivanesk315/cve-2026-18963

CVE-2026-18963

Lab basato su Docker ed exploit Python per CVE-2026-18963, un bypass del flusso di reset delle credenziali di Keycloak che consente l'acquisizione dell'account tramite il bypass della verifica email.

0 giorni faNon ancora revisionato
Vedi Repository

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi

CVE-2026-18963 — Lab Bypass del Flusso Reset-Credentials di Keycloak

Panoramica

Lab che simula la vulnerabilità CVE-2026-18963 (CVSS 9.1) in Keycloak, che consente a un attaccante di impadronirsi di qualsiasi account tramite il bypass della verifica email nel flusso di reimpostazione della password.

Solo per scopi di ricerca sulla sicurezza e didattici.

Requisiti

  • Docker & Docker Compose
  • Python 3.8+
  • pip

Istruzioni per l'uso

1. Avvio di Keycloak vulnerabile

root@kitploit:~
docker-compose up -d

Attendere l'avvio di Keycloak (~30-60 secondi).

2. Configurazione del lab

root@kitploit:~
pip install -r requirements.txt
python setup-lab.py

Lo script creerà:

  • Realm vuln-lab con reset-password abilitato
  • Configurazione SMTP (MailHog) per l'invio di email
  • Utente victim ([email protected] / VictimPass123!)

3. Esecuzione dell'exploit

root@kitploit:~
python exploit.py -u http://127.0.0.1:8080 -r vuln-lab -t victim -p Pwned123!

Opzioni:

  • -u / --url: URL di Keycloak (default: http://127.0.0.1:8080)
  • -r / --realm: Nome del realm (default: vuln-lab)
  • -t / --target: Username target (default: victim)
  • -p / --password: Nuova password (default: Pwned123!)
  • -v / --verbose: Abilita output di debug

4. Visualizzazione email (opzionale)

MailHog UI: http://127.0.0.1:8025 — visualizza le email di reset-password inviate durante l'exploit.

5. Pulizia

root@kitploit:~
docker-compose down -v

Dettagli tecnici

Causa principale

Due bug combinati in Keycloak formano la catena di attacco:

Bug 1 — Corruzione dello stato del selettore (DefaultAuthenticationFlow.java): Quando l'utente clicca "Try Another Way", la nota di autenticazione AUTHENTICATION_SELECTOR_SCREEN_DISPLAYED viene salvata come "true" (stringa booleana) invece dell'ID del modello di esecuzione. Il valore "true" non è vincolato ad alcuna esecuzione specifica, quindi persiste attraverso i passaggi del flusso, causando la visualizzazione del selettore in un contesto errato.

Bug 2 — Successo incondizionato dell'azione (ResetCredentialEmail.java): Il metodo action() di ResetCredentialEmail chiama context.success() incondizionatamente senza verificare l'action token. Normalmente, action() viene chiamato solo quando l'utente clicca il link nell'email (che contiene l'action token). Ma quando il selettore è corrotto, l'attaccante può attivare action() direttamente attraverso l'elaborazione del flusso.

Flusso di attacco dettagliato

root@kitploit:~
Attacker                              Keycloak
   │                                     │
   │─── GET /auth (OIDC + PKCE) ────────>│  1. Inizializza auth session
   │<── Login page + cookies ────────────│
   │                                     │
   │─── GET /reset-credentials ─────────>│  2. Passa al reset flow
   │<── Username form ──────────────────│
   │                                     │
   │─── POST tryAnotherWay=on ─────────>│  3. Corrompe lo stato del selettore
   │<── Authenticator selector ─────────│     SELECTOR_DISPLAYED = "true"
   │                                     │
   │─── POST username=victim ──────────>│  4. Invia username tramite selettore
   │<── "Check your email" page ────────│     Email inviata, CURRENT_EXEC = email_id
   │                                     │
   │─── GET /reset-credentials ────────>│  5. Reinserisce il reset flow
   │<── Corrupted selector (!!!) ───────│     processFlow() vede SELECTOR="true"
   │                                     │     → mostra il selettore per lo step email
   │                                     │
   │─── POST {} (empty body) ──────────>│  6. BYPASS: attiva action()
   │<── 302 → UPDATE_PASSWORD ─────────│     processAction() non trova
   │                                     │     authenticationExecution nel form
   │─── GET /required-action ──────────>│     → cade nel ramo action()
   │<── Password update form ──────────│     ResetCredentialEmail.action()
   │                                     │     → context.success() (incondizionato!)
   │                                     │     → il flow passa a ResetPassword
   │                                     │
   │─── POST password-new=Pwned! ──────>│  7. Imposta la nuova password
   │<── 302 → /account/ ──────────────│     Account takeover completato
   │                                     │
   └── Login con la nuova password ─────┘

Perché lo step 6 funziona?

In DefaultAuthenticationFlow.processAction(), quando riceve il POST:

  1. Verifica tryAnotherWay nel form → NO (form vuoto)
  2. Verifica authenticationExecution nel form → NO (form vuoto)
  3. Cade nel ramo finale: chiama authenticator.action(result) sul modello dall'URL

Poiché l'URL contiene execution=<email_exec_id> (dall'action del form del selettore), viene chiamato ResetCredentialEmail.action() → restituisce context.success() → il flow passa a ResetPassword → mostra il form di impostazione della password.

Versioni interessate

ProdottoInteressateCorrette
Keycloak (upstream)< 26.7.226.7.2+
RHBK 26.4.x< 26.4.1526.4.15+
RHBK 26.6.x< 26.6.626.6.6+

Patch (PR #51844)

DefaultAuthenticationFlow.java:

  • setAuthNote(SELECTOR_DISPLAYED, "true") → setAuthNote(SELECTOR_DISPLAYED, model.getId())
  • processFlow() verifica selector.equals(lastExecutionId) invece di Boolean.parseBoolean()
  • Se non corrisponde → removeAuthNote(SELECTOR_DISPLAYED)

ResetCredentialEmail.java:

  • action() verifica ACTION_TOKEN_USER_ID prima di chiamare context.success()
  • Se non c'è un action token valido → context.failure(INVALID_USER)

Riferimenti

  • NVD - CVE-2026-18963
  • Red Hat CVE Page
  • Keycloak Issue #51833
  • Fix PR #51844
  • Kudelski Security Research
  • The Hacker News
Scarica lo strumento