
End-to-end reproduction and cross-layer detection of CVE-2026-53576, the unauthenticated RCE in Kestra - taken past the base PoC to show how a common Docker-socket misconfiguration turns container-root into full host compromise.
أطلقت Kestra، وهي منصة مفتوحة المصدر لتنسيق سير العمل، مرشّح مصادقة يقرر ما إذا كان الطلب يحتاج إلى بيانات اعتماد من خلال التحقق مما إذا كان عنوان URL ينتهي بـ /configs - وهو فحص يهدف إلى إتاحة نقطة نهاية عامة واحدة غير ضارة.
ولأن الفحص كان ينظر فقط إلى نهاية السلسلة النصية، فإن أي طلب يصادف أن ينتهي عنوان URL الخاص به بهذه الطريقة كان يتخطى المصادقة بالكامل، بما في ذلك نقاط النهاية التي تُنشئ وتُشغّل تعليمات برمجية عشوائية. النتيجة: أي شخص يستطيع الوصول إلى نسخة Kestra المصابة عبر الشبكة يمكنه تشغيل أوامر بصلاحيات الجذر دون أي بيانات اعتماد، ودون تصيّد احتيالي، ودون تخمين كلمات المرور، ودون الحاجة إلى خطوة تصعيد صلاحيات.
في هذا التمرين، تم تنفيذ هذه الثغرة الواحدة من البداية إلى النهاية ضد نسخة مختبرية مستضافة ذاتيًا:
تم التقاط كل مرحلة مقابل بيانات القياس الدفاعية (نظام كشف التسلل الشبكي، وأمن وقت تشغيل المضيف، وتدقيق Linux، وسجلات النظام).
الأثر على الأعمال في حال عدم الترقيع: اختراق كامل للمضيف الذي يعمل عليه Kestra، وليس التطبيق فقط - وبالتالي أي شيء آخر يمكن الوصول إليه من ذلك المضيف.
الإصلاح: الترقية إلى Kestra 1.0.45 / 1.3.21 أو أحدث (الترقيع وحده يُغلق الثغرة الأساسية؛ أما مرحلتا التصعيد والاستمرارية فتتطلبان إصلاحًا منفصلًا ومستقلًا - لا تقم بتركيب مقبس Docker داخل حاويات التطبيقات، انظر القسم 8).
يوثّق هذا التقرير CVE-2026-53576، وهي ثغرة تنفيذ تعليمات برمجية عن بُعد دون مصادقة بتقييم CVSS 10.0 في Kestra ≤1.3.20، ناتجة عن تجاوز مصادقة بلاحقة المسار (AuthenticationFilter.java، endsWith("/configs")).
يمكن للمهاجم الذي يسمّي مساحة الأسماء (namespace) ومعرّف سير العمل configs أن يُنشئ ويُنفّذ أوامر shell عشوائية دون أي بيانات اعتماد، وبصلاحيات الجذر، داخل حاوية Kestra. تم إصلاحها في 1.0.45 و1.3.21. كما تم الإبلاغ عن الخلل نفسه بشكل مستقل تحت CVE-2026-49869، وهو الرقم المُدرج في كتالوج CISA KEV والمرتبط باستغلال فعلي في البرية. ينبغي الاستشهاد بالرقمين معًا، لأن المصادر العامة وأدوات الفحص قد تشير إلى أيٍّ منهما.
| المتأثرة | Kestra ≤ 1.3.20 (وما قبل 1.0.45 على خط 1.0.x) |
| المُصلَّحة | 1.0.45 / 1.3.21+ |
| CVE | CVE-2026-53576 |
| الإشعار التوأم | CVE-2026-49869 - الخلل نفسه، مُدرج في CISA KEV (في البرية) |
| التاريخ | الحدث |
|---|---|
| 2026-06-02 | إصدار Kestra 1.3.21؛ ويشير سجل التغييرات إلى "تجاوز مصادقة محتمل في مرشّح المصادقة" |
| 2026-06-03 | إصدار Kestra 1.0.45 على خط 1.0.x |
| 2026-09-02 | إضافة CVE-2026-49869 (الإشعار التوأم) إلى كتالوج CISA KEV |
| 2026-09-22 إلى 09-24 | إعادة إنتاج هذا المختبر، وبناء الكشف، والتحقق عبر الطبقات |
مختبر منزلي مستضاف ذاتيًا:
- مضيف Debian (اسم المضيف docker، النواة 6.12.107+deb13-amd64)،
- Docker Engine 29.8.1.
- Kestra منشور كصورة رسمية kestra/kestra:v1.3.20، يمكن الوصول إليه عبر وكيل عكسي Caddy على kestra.int.atlasvec.com.
- حزمة القياس تحت الاختبار: Falco (وقت التشغيل/eBPF، على مستوى المضيف)،
- Suricata 8.0.3 IDS (مرآة SPAN سلبية)، تُمرّر نحو Splunk.
قبل المساس بأي شيء، تأكدت من أن الهدف مصاب فعليًا وأن حزمة القياس تعمل. كما أخذت لقطة للحالة قبل الهجوم حتى أتمكن من التراجع عند الانتهاء.
Kestra يعمل بالإصدار المصاب:

الحاوية نفسها، تعمل ويمكن الوصول إليها:

وحدات Falco محمّلة على المضيف:

Falco يُصدر أحداثًا بنشاط (وضع eBPF الحديث):

خدمة Suricata نشطة:

وeve.json الخاص بها يكتب أحداثًا حية:

هذان خطآن يتصادفان معًا، وليس خطأً واحدًا.
أولًا، يقرر مرشّح المصادقة ما إذا كان الطلب يمكنه تخطي المصادقة من خلال مطابقة نهاية مسار الطلب:```java // AuthenticationFilter.java — the vulnerable check, confirmed against the self-hosted v1.3.20 source if (path.endsWith("/configs")) { // treated as a public, unauthenticated path }
هذا الفحص موجود لكشف نقطة نهاية واحدة غير ضارة، وهي إعدادات المثيل العام. ولأن `endsWith` يقرأ فقط نهاية السلسلة، فإنه لا يستطيع التمييز بين مسار آمن واحد وأي مسار آخر ينتهي بالطريقة نفسها.
ثانيًا، لا يزال موجّه Kestra يوجّه تلك المسارات المتشابهة إلى معالجاتها الحقيقية الحساسة. يصل `/api/v1/main/flows/configs` إلى معالج إنشاء التدفق. ويصل `/api/v1/main/executions/configs/configs` إلى معالج التنفيذ. يمرّر الفلتر كليهما كمسارات عامة، وينفّذهما الموجّه رغم ذلك. سمِّ مساحة الأسماء ومعرّف التدفق `configs`، وسينتهي مسار ينفّذ الكود بـ `/configs`، فيرث بذلك التمرير المجاني الخاص بالمسار العام.
يُظهر زوج الطلبات الملتقطة ذلك بوضوح. `GET /api/v1/main/flows/search` بدون بيانات اعتماد يعيد `401`. أما `POST /api/v1/main/flows/configs` مع ترويسة المصادقة الفارغة نفسها فيعيد `200` ويخزّن التدفق (انظر §5.1).
## 5. محاكاة الهجوم
> كل خطوة أدناه موثّقة بلقطة شاشة خاصة بها. كل ذلك يعمل داخل مختبر منزلي معزول خاص بي ضد نسخة Kestra مستضافة ذاتيًا خلف الوكيل العكسي.
### 5.1 المرحلة 1 - تجاوز المصادقة -> صلاحيات root داخل حاوية Kestra
**التحكم:** `GET /api/v1/main/flows/search` بدون بيانات اعتماد → `401 Unauthorized`.
يؤكد أن المصادقة مفروضة على مسار عادي.

_____