
إثبات مفهوم (PoC) عبر Loopback لثغرة في وسيط SAML في Keycloak 26.8.1: اسم SAMLResponse مكرر ومُرمَّز نسبيًا يتجاوز التحقق من توقيع إعادة التوجيه، مما يسمح بتسجيل الدخول بصفة مستخدم آخر.
يمكن لشخص لا يملك حساب Keycloak إكمال تسجيل دخول SAML الخاص بالشركة بصفته شخصًا آخر. يسجّل الدخول مرة واحدة لدى مزوّد الهوية الأعلى، ويحتفظ بذلك التوجيه الموقّع، ويضع مستند SAML ثانيًا أمامه تحت اسم مُرمّز بنسبة مئوية. يتحقق Keycloak من التوقيع الصادق ثم يسجّل دخوله بالاسم الموجود في المستند المزوّر. يتطلب ذلك وسيط SAML يوقّع استجابات HTTP-Redirect، مع تفعيل التحقق من التوقيع وإبقاء توقيعات التأكيد معطّلة، وهو ما يضبطه استيراد البيانات الوصفية. وهو ليس الانقسام بالفاصلة المنقوطة من issue #53354.
الفئة: بقايا OAuth الوصول: عن بُعد (بدون مصادقة إلى Keycloak؛ يتطلب وسيط SAML يوقّع التوجيهات)
Keycloak 26.8.1 (24ed1dad) - Red Hat
| المعرّف | لا يوجد CVE بعد |
| الفئة | بقايا OAuth |
| الوصول | عن بُعد (بدون حساب Keycloak؛ يتطلب توقيع HTTP-Redirect حقيقيًا واحدًا من IdP) |
| CWE | CWE-287 / CWE-347 / CWE-116 |
| CVSS | عالٍ: 7.4 CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N |
| المنتج | Keycloak |
| المتأثر | 26.8.1 (24ed1dadf3f246a555adb6d3d4a99e9b3003fb3b)؛ Quarkus 3.40.1؛ الصورة quay.io/keycloak/keycloak:26.8.1 |
| المصادقة | لا شيء على Keycloak. يتطلب وسيط مزوّد هوية SAML مع validateSignature=true وwantAssertionsSigned غائبًا أو بقيمة false. |
| الترخيص | GNU Affero GPL v3.0 |
| المختبر | 127.0.0.1:18084 فقط |
يحتاج إلى NameID الخاص بالضحية (عادةً بريد إلكتروني) وإلى توجيه HTTP-Redirect موقّع حقيقي واحد من ذلك IdP. لا يحتاج إلى كلمة مرور Keycloak. لا يحتاج إلى صندوق بريد. مزوّد هوية يدعم POST فقط لا يمنح ذلك التوقيع. يبقى ACS الخاص بـ GET مثبّتًا حتى عندما يفضّل استيراد البيانات الوصفية POST.
| الصلاحية | الطريقة / نقطة الوصول | الاستطلاع / السلامة / التوافر | مُثبت مختبريًا أم مُستنتج |
|---|---|---|---|
| ربط مستند SAML مزوّر بينما يظل التوقيع الصادق يتحقق | GET broker ACS مع SAML%52esponse=<forged> قبل SAMLResponse الموقّع | السلامة (المصادقة) | مُثبت مختبريًا. بريد التحكم [email protected]. بريد الهجوم [email protected] |
| إنشاء مستخدم الضحية عبر أول تسجيل دخول للوسيط | callback.authenticated على NameID المزوّر | السلامة (إنشاء حساب) | مُثبت مختبريًا. عدد الضحايا 0 قبل استعلام الانقسام، و1 بعده |
| جلسة كمستخدم وسيط موجود، بما في ذلك مسؤول يستخدم نفس IdP | نفس ACS، NameID لذلك المستخدم | السلامة (الاستيلاء على الحساب) | مُستنتج. أنشأ المختبر الضحية عند أول تسجيل دخول |
| الحفاظ على RelayState وجلسة المصادقة | يبقى RelayState بالقيمة الموقّعة | السلامة | المصدر. يغطي التوقيع RelayState |
| التحكم السلبي | توجيه موقّع صادق، بدون معامل إضافي | لا ينطبق | مُثبت مختبريًا. يكتمل التحكم ببريد المهاجم |
يبقى مغلقًا على هذه البقايا
| المحور | الطريقة / نقطة الوصول | سبب إغلاقه |
|---|---|---|
| السلامة | الانقسام بالفاصلة المنقوطة SAMLResponse=...;SAMLResponse=... | issue #53354. quarkus.http.use-semicolon-as-query-param-delimiter=false |
| السلامة | تأكيد غير موقّع عندما يكون wantAssertionsSigned=true | يتطلب handleLoginResponse عندئذٍ توقيع تأكيد |
| السلامة | لا يوجد وسيط SAML، أو IdP يدعم POST فقط بدون توقيع توجيه | لا يحصل المهاجم أبدًا على SigAlg + Signature على GET |
| السلامة | RCE على المضيف، Admin REST بدون مصادقة | خارج الفئة |
| السلامة | نموذج الاسم الافتراضي VERIFY_PROFILE | مُثبت مختبريًا كخطوة إكمال، وليس كدحض. يحتوي النموذج بالفعل على البريد الوسيط |
ثبّتُ إصدار Keycloak 26.8.1. يأخذ RESTEasy Reactive الوسيط @QueryParam("SAMLResponse") من Vert.x، الذي يفكّ ترميز النسبة المئوية لأسماء الاستعلامات، لذا ينهار SAML%52esponse إلى SAMLResponse وتفوز القيمة الأولى. تعيد verifyRedirectSignature بناء السلسلة الموقّعة من getQueryParameters(false) على الاستعلام الخام، حيث يبقى ذلك الاسم مفتاحًا مختلفًا.
المسارات الخاطئة المسجّلة سلفًا: التعامل مع #53354 على أنه هذا المتبقي (اسم مُرمَّز بنسبة مئوية، لا فاصلة منقوطة)؛ تتبّع استجابات ACS 302 في عميل المختبر وإسقاط AUTH_SESSION_ID؛ قراءة firstName/lastName الفارغين عند VERIFY_PROFILE على أنهما فشل (فالبريد الإلكتروني هو بالفعل NameID الوسيط)؛ صدفة عكسية. مسرح.
Python 3.11+ مع cryptography. يتطلب Docker.
python3 keycloak-saml-redirect-param-split-Abraxas-Labs.py
أو:
cd lab
./run.sh
استهدف فقط http://127.0.0.1:18084. الصورة quay.io/keycloak/keycloak:26.8.1. يقوم المشغّل chdir إلى lab/ ثم ينفّذ run.sh. مزوّد الهوية في المختبر يعمل داخل العملية نفسها. لا يتواصل أبدًا مع مزوّد هوية حقيقي.
IOC image=quay.io/keycloak/keycloak:26.8.1 label-version=26.8.1
IOC serverinfo-version=26.8.1
IOC validate-signature=true want-assertions-signed=absent
IOC review-profile=DISABLED
IOC [email protected]
IOC victim-before=0
IOC [email protected]
IOC victim-after=1
SUCCESS KC-H04-SAML-REDIRECT kcs04b8n1
تحقّق من مستند الاستعلام نفسه الذي يحلّله نقطة النهاية. فكّ ترميز النسبة المئوية لأسماء المعاملات قبل إعادة بناء التوقيع، أو ارفض أي استعلام يحتوي على أكثر من SAMLResponse واحد بعد فك الترميز. فعّل wantAssertionsSigned لوسطاء إعادة التوجيه، بما في ذلك مسار استيراد البيانات الوصفية.
24ed1dadf3f246a555adb6d3d4a99e9b3003fb3b)SAMLEndpoint.redirectBinding (SAMLEndpoint.java:182-183، :779-813، :896-914)SamlProtocolUtils.verifyRedirectSignature (SamlProtocolUtils.java:216-249)KeycloakUriInfo.getQueryParameters (KeycloakUriInfo.java:147-163)GNU Affero GPL v3.0. راجع LICENSE. للاستخدام في مختبر الاسترجاع المحلي فقط. دون أي ضمان.
مختبرات أبراكساس [email protected]
يُرجى نسب CVE إلى Abraxas Labs.