Skip to content
KitploitKITPLOIT
أدواتعمليات الاستغلالالمدونة
Log in
إرسال
أدواتعمليات الاستغلالالمدونة
إرسال

أدوات الاختراق واختبار الاختراق والأمن السيبراني لترسانتك الأمنية!

Kitploit هو دليل لأدوات الاختراق والأمن السيبراني واختبار الاختراق. اكتشف آخر تحديثات المشاريع للعثور على الثغرات وتحليل الأنظمة وأتمتة الاختبارات وتعزيز أمنك.

الخلاصاتاتصالالخصوصية© 2026 Kitploit

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
CVE-2026-8933 — إثبات مفهوم بلغة C للثغرة CVE-2026-8933، وهي تصعيد امتيازات محلي في snap-confine يستخدم تجميد cgroup، وسباقات الروابط الرمزية، وحقن قواعد udev لتنفيذ أوامر بصلاحيات الجذر. | Kitploit
أدوات/GitHubGitHub/yifengchen-cc/cve-2026-8933
تصعيد الامتيازاتأمن الحاوياتتحليل الثغرات الأمنيةالاستغلال
GitHubyifengchen-cc/cve-2026-8933

CVE-2026-8933

إثبات مفهوم بلغة C للثغرة CVE-2026-8933، وهي تصعيد امتيازات محلي في snap-confine يستخدم تجميد cgroup، وسباقات الروابط الرمزية، وحقن قواعد udev لتنفيذ أوامر بصلاحيات الجذر.

عرض المستودع
منذ 13 أياملم تتم المراجعة بعد

الأكثر شعبية

عرض الكل →

اكتشف الأدوات الأكثر استخدامًا من قبل مجتمعنا.

استكشف جميع الأدوات

تصفح مجموعتنا من الأدوات

عرض جميع الأدوات →
مشاركة

CVE-2026-8933 — snap-confine set-capabilities تصعيد صلاحيات محلي PoC

أعد إنتاج إشعار Qualys بعنوان «Local Privilege Escalation in set-capabilities versions of snap-confine» (https://cdn2.qualys.com/advisory/2026/07/21/snap-confine-set-capabilities.txt).

تم الاختبار فعليًا على الجهاز المحلي (Ubuntu 25.10 / snapd 2.73+ubuntu25.10.1 / النواة 6.17): بدءًا من uid 1000، في النهاية يقوم systemd-udevd بتنفيذ الأمر بصلاحيات root، ويحصل /tmp/pwned على uid=0(root) gid=0(root) groups=0(root)، بما يتوافق مع التأثير المعروض في نهاية الإعلان.

سجل المشكلات التي واجهتها أثناء إعادة الإنتاج، وسبب التقييم الخاطئ في المرة الأولى بأنه "غير قابل للاستغلال"، راجع NOTES.md.

الملفات

الملفالوصف
poc.cPoC كامل (ملف واحد)
Makefileالبناء (يربط libfuse3.so.3.17.4 المثبتة على النظام)
include/ملفات رأس libfuse3 3.17.4 (مطابقة لمكتبة وقت التشغيل على النظام)
NOTES.mdسجل المشكلات + مراجعة منهجية تحليل قابلية الوصول

مبدأ الثغرة

cmd/snap-confine/mount-support.c (snapd 2.73):

sc_bootstrap_mount_namespace()      // 第 475 行起
  479:  mkdtemp("/tmp/snap.rootfs_XXXXXX")          <- 目录先归调用者所有
  491:  sc_do_mount(scratch, scratch, NULL, MS_BIND)
  498:  sc_do_mount("none", scratch, NULL, MS_UNBINDABLE)
  503:  sc_do_mount("none", scratch, "tmpfs", ...)
  504:  sc_replicate_base_rootfs(scratch, rootfs_dir, mounts)

sc_replicate_base_rootfs()
  330:  chown(scratch, 0, 0)
  418:  fd = open(full_path, O_CREAT | O_TRUNC, 0644)   <- 缺少 O_NOFOLLOW
  422:  fchown(fd, 0, 0)

أرقام الأسطر مأخوذة من الشيفرة المصدرية لـ snapd 2.73 على هذا الجهاز (cmd/snap-confine/mount-support.c). إعلان Qualys يشير إلى نسخته الخاصة من الملف، وأرقام الأسطر المقابلة لديه هي 511 / 523 / 530 / 535 / 536 / 362 / 450 / 454 —— العبارات متطابقة واحدة بواحدة، لكن أرقام الأسطر مختلفة.

الملف /usr/lib/snapd/snap-confine على هذا الجهاز هو mode=755 + قدرات الملف (وليس setuid-root)، لذا فهو يعمل بمعرّف المستخدم الفعّال (euid) الخاص بالمهاجم، لكنه يحمل قدرات قريبة من صلاحيات root: الأدلة والملفات التي ينشئها تظل مملوكة للمهاجم لفترة قصيرة، بينما يقوم open() في السطر 418 باتباع الروابط الرمزية.

يؤكد التفكيك: أعلام open@plt على هذا الجهاز هي 0x240 (O_CREAT|O_TRUNC، بدون O_NOFOLLOW)؛ وفي 2.77.1 المُصلَّح تكون النقطة نفسها 0x20240.

الخطوات الست لـ PoC

  1. ضع snap-confine داخل cgroup الخاص بك: systemd-run --user --scope --unit=snap.<snap>.<app>. هذا النطاق (scope) يخص المستخدم الحالي، وcgroup.freeze قابل للكتابة، وبالتالي يمكن السماح لـ snap-confine بالمرور نداء نظام واحداً في كل مرة.
  2. جمّد في الموضع الصحيح: عند SNAPD_DEBUG=1 يطبع snap-confine associated snap application process ... with device cgroup. يظهر هذا السطر بعد إرفاق برنامج BPF الخاص بـ cgroup الجهاز، وقبل mkdtemp(). لا يمكن التجميد أبكر: يعيد مدقق BPF القيمة EAGAIN عند وجود freeze trap، فيخرج snap-confine مباشرة. stderr موصول بـ pty (وليس أنبوباً): وإلا فسيُخزَّن stdio في المخزن المؤقت للكتل، وغالباً ما يُدفَق العلامة فقط بعد mkdtemp() وbind mount. كذلك يُشغَّل النطاق بـ CPUQuota=1%: من العلامة إلى mkdtemp() لا يوجد سوى بضع مئات من الميكروثواني من وقت CPU، وهو من رتبة زمن تأخر إيقاظ عملية الالتقاط؛ فيمدّ تحديد المعدل هذه النافذة في الزمن الحقيقي إلى مستوى الميلي ثانية، وبعد تأكيد التجميد يُعاد cpu.max فوراً إلى 100%.
  3. استبدل دليل scratch برابط رمزي يشير إلى دليلنا الخاص: mount(2) يتبع الروابط الرمزية في مسار الهدف، فتقع جميع عمليات bind/unbindable/tmpfs الخاصة بـ snap-confine على <scratch>.dA، بينما لا تزال حلقة النسخ تستخدم دليل scratch كـسلسلة نصية.
  4. بعد تركيب tmpfs (ns_mount_count(sc, .dA) >= 2)، أعد توجيه الرابط الرمزي إلى <scratch>.dB، وضع في dB روابط رمزية بأسماء مطابقة للملفات العادية في المستوى الأعلى من base rootfs، تشير إلى /run/udev/rules.d/97-cve-2026-8933-<pid>-<rand>.rules. عندها يقع تحليل المسار في حلقة النسخ على dB —— وهو دليل عادي نتحكم فيه بالكامل. ويُترك tmpfs في dA، فلا يعود يعيقنا. ملاحظة: عندما يكون على .dA تركيب واحد فقط فهو bind mount (فـ /tmp نفسه tmpfs، ويبقى fstype بعد bind هو tmpfs)، ويجب الانتظار حتى ظهور التركيب الثاني (tmpfs الحقيقي) قبل إعادة التوجيه، وإلا فإن mount --make-unbindable الخاص بـ snap-confine سيعيد EINVAL لأن المسار لم يعد جذر تركيب.
  5. اكسب النافذة بين open()/fchown(): تنفذ حلقة النسخ على أول ملف عادي open(O_CREAT|O_TRUNC) (تتبع الرابط الرمزي، وتنشئ الملف بصلاحية root تحت /run/udev/rules.d)، ثم fchown(fd,0,0). يظل الملف في هذه اللحظة ملكاً لنا. يستخدم PoC في الوقت نفسه وسيلتين:
    • المسار الرئيسي: الاستمرار في استخدام freezer للسماح بنحو نداء نظام واحد في كل مرة، وبمجرد أن يرى stat() الملف وأن uid لا يزال uid الخاص بنا، فوراً chmod 0666 + كتابة قاعدة udev (عندها يكون snap-confine مجمداً، وتكون النافذة "مفتوحة على مصراعيها")؛
    • الاحتياط: عدة عمليات spinner تستبق النافذة نفسها بحلقة chmod() ساخنة. بعد أن يسبق spinner، يصبح الملف مملوكاً لـ root لكن وضعه 0666 —— إذ تبقى بتات الوضع محفوظة بعد fchown(0,0)، لذا يستطيع المسار الرئيسي أيضاً إكمال الكتابة (فالشيفرة تتحقق من "هل يمكن الكتابة"، لا من "هل أنت المالك").
  6. أطلق udev: يسمح ملف AppArmor الخاص بـ snap-confine بـ /run/udev/** rw. تركيب/إلغاء تركيب نظام ملفات FUSE يجعل النواة تصدر uevent من نوع add للنظام الفرعي bdi، فينفذ systemd-udevd فوراً PROGRAM= الموجود في القاعدة بصلاحية root.

الاستخدام

make
./poc --diagnose            # 只读自检,不改动任何系统状态
./poc                       #  exploit,默认最多 5 次尝试
./poc --attempts 8          # 增加尝试次数
./poc --file default256.png # 只用 base rootfs 里的这一个普通文件
sudo ./poc --cleanup        # 清理(仅在异常中断留下残留时需要)

المعاملات:

المعاملالوصف
--snap NAMEأي snap يُستخدم rootfs الخاص به (الافتراضي firefox، ويمكن أيضاً استخدام متغير البيئة CVE8933_SNAP)
--app NAMEتطبيق ذلك snap (الافتراضي هو أول تطبيق تحت apps: في meta/snap.yaml)
--file NAMEاستخدام ملف عادي واحد فقط من base rootfs؛ إن لم يوجد تطابق يُنهي البرنامج مع خطأ
--attempts Nعدد المحاولات (الافتراضي 5)
--step US / --step2 USزمن CPU لكل شريحة في المرحلتين (بالميكروثانية)، للتصحيح
--keepالاحتفاظ بمجلدي <scratch>.dA / .dB والروابط الرمزية (للتصحيح)
--diagnoseفحص ذاتي للقراءة فقط
--cleanupتنظيف المخلفات السابقة (يتطلب root)

تُكتب السجلات إلى /tmp/cve8933.log، ويُكتب مخرجات تصحيح snap-confine إلى /tmp/cve8933-debug.txt.

يمكن لـ CVE8933_PAYLOAD_CMD='<shell 命令>' استبدال جسم payload (لاستعراض تنفيذ أوامر root أخرى)، وفي هذه الحالة لا يتم التنظيف التلقائي؛ يجب أن تكتب الأوامر المخصصة أيضاً إلى /tmp/pwned، وإلا سيعتبر PoC أن هذه المحاولة لم تنجح.

نتائج الاختبار الفعلي

$ ./poc
[+] WIN: uid=0(root) gid=0(root) groups=0(root)
[+] exploit succeeded, evidence in /tmp/pwned

/tmp/cve8933.log العملية الناجحة المقابلة (2026-10-23، إعادة الاختبار بعد التعديل):

[    0.256] === attempt 1/5 ===
[ 1062.158] marker seen after 750.5 ms
[ 1067.530] scratch dir /tmp/snap.rootfs_oFBraI replaced by a symlink to ...dA
[ 1100.887] bind mount + tmpfs on ...dA after 417 slices
[ 1100.974] scratch directory now points to ...dB with 4 symlinks -> ...rules
[ 1108.782] took the file over while snap-confine was stopped (242 slices)
[ 1108.820] rule written after 797.1 ms
[ 1108.832] target: uid=0 gid=0 mode=0666 size=73 content="ACTION=="add", ..."

(كانت إحدى المحاولات السابقة التي شملت 8 محاولات قد نجحت في المحاولة الثانية فقط: كان تأكيد التجميد في المحاولة الأولى متأخرًا جدًا، وقد تجاوز snap-confine عملية bind mount خلال نفس الشريحة الزمنية.)

ظهر لفترة وجيزة في /run/udev/rules.d/:

-rw-rw-rw- 1 root root 73 ... 97-cve-2026-8933-85431-485b.rules

المحتوى هو ACTION=="add", SUBSYSTEM=="bdi", PROGRAM="/tmp/cve-2026-8933-payload.sh"، وتؤكد سجلات udevd أنه تم تحميله ("marked world-writable ... Proceeding anyway")، ويُنفَّذ الـ payload بصلاحيات root.

حول معدل النجاح

تنزيل الأداة