
مقالة تعليمية وإثبات مفهوم في وضع الاختبار لـ CVE-2026-92162، وهو اجتياز مسار في معامل arch الخاص بـ DeployAppstream في Flatpak يتيح إنشاء دليل الجذر.
مقال تعليمي وإثبات مفهوم في وضع الاختبار لثغرة اجتياز المسار في مساعد نظام Flatpak (flatpak-system-helper). تقبل طريقة DeployAppstream عبر D-Bus سلسلة arch تُوضع داخل مسار نظام الملفات وتُنشأ بصلاحيات الجذر، دون أي تحقق. يمكن لمستخدم محلي نشط تمرير مكوّنات ../ والتسبب في قيام الخدمة ذات صلاحيات الجذر بإنشاء أدلة خارج شجرة appstream المقصودة.
يرافق هذا المستودع التحليل التقني الكامل وتقرير ما بعد البحث. وهو موجود لأغراض تعليمية، وللمدافعين الذين يرغبون في فهم الآلية، وللاختبار المصرّح به على الأنظمة التي تملكها أو لديك إذن كتابي بتقييمها.
تُنشر هذه المواد بعد الإفصاح المنسّق وبعد إتاحة إصدار Flatpak مُصلَّح. شغّل إثبات المفهوم فقط على جهاز مختبري تملكه أو لديك إذن صريح باختباره. لا تشغّله على أنظمة لا تتحكم بها. أنت مسؤول عن الالتزام بالقانون وبضمن نطاق أي إذن تملكه.
تتحقق الدالة handle_deploy_appstream() في مساعد النظام من معامل origin لكنها لا تتحقق من معامل arch. بالنسبة لـ OCI remote، ينتقل arch إلى flatpak_build_file ثم إلى g_mkdir_with_parents، التي تعمل بصلاحيات الجذر وتحل ../ معجمياً. إجراء polkit الخاص بالطريقة هو org.freedesktop.Flatpak.appstream-update، وهو allow_active=yes، لذا تصل جلسة محلية نشطة إلى الكود دون طلب كلمة مرور. على نظام يحتوي بالفعل على OCI remote، مثل Fedora Workstation الافتراضي مع remote الخاص به fedora، يمكن لمستخدم منخفض الصلاحيات إنشاء أدلة مملوكة للجذر في مسار عشوائي. تستهدف الحمولة في هذا المستودع /root/.ssh نفسه.
تم إثبات هذه الثغرة، الاكتشاف A، كجزء من سلسلة ثغرتين استُخدمت للتصعيد من مستخدم محلي غير مصادَق إلى الجذر على الجهاز، في مختبر مُتحكَّم به ومصرّح به. تعمل السلسلة كما يلي: الاكتشاف A ينشئ /root/.ssh بصلاحيات الجذر. الاكتشاف B، وهو قدرة كتابة ثانوية، يمكنه بعد ذلك كتابة محتوى يتحكم به المهاجم داخل ذلك الدليل. معاً يمنحان المهاجم ملفاً مملوكاً للجذر في مسار يختاره المهاجم. كل خطأ بمفرده محدود: الاكتشاف A ينشئ الأدلة فقط، والاكتشاف B يمكنه الكتابة فقط حيث يوجد دليل أب بالفعل. الاكتشاف A يوفّر دليل الأب الذي يحتاجه الاكتشاف B، ويصبح الزوجان كتابة ملف بصلاحيات الجذر.
تم تحديد الاكتشاف B بشكل مستقل من خلال هذا البحث، لكنه ليس اكتشافاً جديداً: إنه الضعف المعروف، الذي لا يزال دون إصلاح، في مسار كتابة البيانات الإضافية الخاص بـ Deploy الموثّق في تقرير ما بعد البحث. لذلك يغطي هذا المقال الاكتشاف A ويُنسب إليه، ويستخدم الاكتشاف B فقط كمكوّن معروف غير مُصلَّح تعتمد عليه السلسلة.
يوضّح هذا المستودع الاكتشاف A فقط. منهجية التسلسل والدروس الدفاعية موثّقة في تقرير ما بعد البحث.
يوفّر المشروع بالفعل flatpak_is_valid_arch، الذي يقيّد اسم المعمارية بـ [A-Za-z0-9_]. المعالجة هي استدعاؤه على معامل arch عند حدود المعالج وداخل مساعدات بناء المسار. لا يمكن لقيمة ../ أن تجتاز هذا الشرط. حدّث إلى إصدار Flatpak المُصلَّح.
.
├── README.md This file.
├── requirements.txt System package prerequisites for the PoC.
└── poc_arch_traversal.sh PoC for the unvalidated arch parameter.
Sandboxed test mode by default, production
mode targets /root/.ssh. Educational use only.
requirements.txt
موجودة.allow_active=yes. تحقق باستخدام:
loginctl list-sessions وتأكد من أن جلستك تُظهر مقعداً (seat)./usr/libexec/flatpak-system-helper؛
يبحث السكربت أولاً عن مساعد مبني حديثاً في builddir/ أو _build/ من
شجرة مصدر Flatpak، وFLATPAK_SYSTEM_HELPER يتجاوز كل شيء.
راجع requirements.txt لحزم النظام المطلوبة.يكتشف وضع الإنتاج تلقائياً أي OCI remote موجود على تثبيت النظام ويستخدمه. أي OCI remote يعمل، حتى لو كان وهمياً أو غير قابل للوصول، لأن mkdir يحدث قبل الاتصال بالسجل إطلاقاً. إذا لم يوجد أي OCI remote، يُلغى السكربت برسالة "No OCI remote found" ولا يرسل شيئاً.
يوفّر Fedora Workstation بالفعل OCI remote باسم fedora، لذا لا حاجة
لفعل أي شيء هناك. تحقق مما هو موجود باستخدام flatpak remotes --system (يُظهر OCI
remote كلمة oci في عمود خياراته).
هذا هو الأمر الوحيد في التدفق كله الذي يحتاج sudo، والسكربت لا يشغّله نيابة عنك أبداً. أضف واحداً باستخدام:
sudo flatpak remote-add --system --no-gpg-verify oci-poc oci+http://127.0.0.1:19876
(لا يملك flatpak علامة --oci، على الأقل حتى الإصدار 1.19.0، وهو الإصدار الذي
يستند إليه هذا العمل؛ بادئة URL oci+ هي ما يجعل الـ remote سجل OCI.) رسالة "Warning: Could not update extra metadata"
متوقعة عندما لا يكون هناك سجل يعمل؛ ومع ذلك يُضاف الـ remote.
bash poc_arch_traversal.sh
يبدأ السكربت ناقل D-Bus خاصاً ومساعداً في وضع --session، كل ذلك
تحت دليل مؤقت. يستدعي DeployAppstream بالحمولة
../../../../../root/.ssh ويتحقق من إنشاء الدليل المُهرَّب
في <workdir>/root/.ssh، بما يحاكي الهدف الحقيقي. توقّع خطأ D-Bus في
منتصف المخرجات: ذلك هو فشل جلب فهرس OCI بعد أن كان الدليل
قد أُنشئ بالفعل، وهو السلوك المتوقع.
bash poc_arch_traversal.sh prod
لا يطلب السكربت كلمة مرور أبداً. يكتشف تلقائياً OCI remote، ويشغّل
DeployAppstream دون مصادقة بالحمولة المُهرَّبة، ويطبع
استجابة المساعد. ينشئ مساعد الجذر /root/.ssh ثم يفشل عند
السجل غير القابل للوصول، مما يطبع خطأ D-Bus المتوقع. إذا كانت الاستجابة
خطأ مصادقة بدلاً من ذلك، فأنت لست في جلسة محلية نشطة؛
شغّله من طرفية الجهاز. يمكن فرض remote محدد باستخدام
bash poc_arch_traversal.sh prod <remote>.
يعمل المشغّل نفسه دون صلاحيات، لكن تأكيد النتيجة يحتاج الجذر، لذا يترك السكربت ذلك لك. بعد التشغيل، على نفس الجهاز:
sudo ls -laR /root/.ssh
sudo stat -c '%U:%G' /root/.ssh
يجب أن يكون الدليل موجوداً ومملوكاً لـ root:root. خطأ D-Bus في
مخرجات السكربت ليس فشلاً: إنه يثبت أن mkdir عمل قبل الجلب، لأن
الدليل المُهرَّب موجود رغم فشل استدعاء الطريقة.
إذا كان /root/.ssh موجوداً بالفعل قبل التشغيل (مثلاً على مضيف
يشغّل sshd)، فالتشغيل لا يفعل شيئاً على ذلك المسار ولا يترك شيئاً خلفه: ملف
lock الخاص بالمساعد عابر ويُزال عند عودة الطريقة، و
icons يُكتب فقط بعد جلب فهرس ناجح. للتحقق النظيف،
شغّله على مسار غير موجود بعد.
sudo rm -rf /root/.ssh # only if it did not exist before the run
sudo flatpak remote-delete --system oci-poc
البحث والمقال من إعداد Yehia Ali Mohamed Ezzat.
التوثيق والكود في هذا المستودع مُقدَّمان لأغراض تعليمية. استخدمه على مسؤوليتك الخاصة وفقط حيث تكون مصرّحاً.