
CVE-2026-68398 ثغرة استخدام بعد التحرير (use-after-free) في Ubuntu PPPoL2TP لتصعيد الامتيازات محليًا

يحتوي هذا المستودع على استغلال محلي لرفع الصلاحيات خاص بنسخة بناء محددة لثغرة CVE-2026-68398، وهي سباق من نوع استخدام بعد التحرير (use-after-free) بين معالجة الاستقبال في PPPoL2TP وتدمير قناة PPP غير مرتبطة. تم التحقق من صحته في QEMU مقابل الحزمة الرسمية لنظام Ubuntu 22.04 linux-image-5.15.0-187-generic (5.15.0-187.197).
يبدأ الاختبار النهائي كمستخدم مخصص بمعرّف UID 1001 دون مجموعات إضافية، ودون صلاحيات (capabilities)، ودون وصول sudo، ثم يحصل على UID 0 في النطاق الأولي (initial namespace). تبقى KASLR وSMEP وSMAP وAppArmor مفعّلة. لا يتم إقلاع الضيف مع nokaslr أو nopti أو nosmep أو nosmap.
تحذير
يعمل هذا الكود عمدًا على إتلاف حالة كومة (heap) النواة ويرتبط بنسخة بناء نواة Ubuntu محددة بدقة. يمكن أن يؤدي فشل السباق إلى انهيار (panic) النظام أو إتلافه. شغّله فقط في جهاز افتراضي معزول وقابل للتخلص منه وتملكه.
تنفَّذ الدالة pppol2tp_recv() في مسار استقبال L2TP عبر UDP داخل قسم حرج (critical section) لقراءة RCU وتستدعي في النهاية ppp_input(&po->chan). مقبس PPPoX وقناته المضمّنة ppp_channel آمنان مع RCU، لكن البنية الداخلية struct channel التي تستخدمها ppp_input() هي تخصيص (allocation) منفصل.
بالنسبة لقناة مرتبطة عبر PPPIOCGCHAN ولكنها غير مرتبطة بوحدة PPP وغير مجسّرة (bridged)، يقوم مسار الإغلاق بتحرير ذلك الكائن الداخلي فورًا:
RX: l2tp_udp_encap_recv -> pppol2tp_recv -> ppp_input(channel)
CLOSE: pppol2tp_release -> pppox_unbind_sock
-> ppp_unregister_channel -> ppp_release_channel -> kfree(channel)
وبالتالي يمكن لمسار الاستقبال العمل على قائمة skb وقائمة الانتظار الخاصة بالقناة المحرّرة. يضيف الإصلاح استدعاءً رجعيًا (callback) لـ RCU إلى struct channel ويؤجّل تطهير القائمتين والتحرير حتى انقضاء فترة سماح (grace period) لـ RCU.
تم اكتشاف الثغرة وإصلاحها في النواة الرسمية (upstream) بواسطة Norbert Szetei من Doyensec. الإصلاح الرئيسي (mainline) هو ec4215683e47424c9c4762fd3c60f552a3119142.
يحدد سجل Linux CNA أن السلالة المعرضة للثغرة تبدأ مع Linux 4.15. قد تحمل نوى البائعين (vendor kernels) الإصلاح تحت رقم إصدار مختلف، لذا فإن مصدر الرمز الدقيق أو سجل تغييرات الحزمة له الأولوية على هذا الجدول.
| خط النواة | أول إصدار مُصلَح | التزام الإصلاح |
|---|---|---|
| 6.6.y | 6.6.148 | 4bb84e964ff0 |
| 6.12.y | 6.12.101 | 3ab32218d718 |
| 6.18.y | 6.18.42 | c9574b8a8ede |
| 7.1.y | 7.1.6 | 06213c85d8c0 |
| Mainline | 7.2-rc4 | ec4215683e47 |
تتطلب خطوط النوى المدعومة الأقدم من جهة البائعين نقلًا عكسيًا (backport). اعتبارًا من 2026-08-12، يضع متتبع CVE لنظام Ubuntu حزمة linux الخاصة بـ Jammy في حالة needs-triage؛ ولم يتم تحديد أي حزمة Ubuntu Jammy مصححة. لا يزال مصدر الإصدار المُختبر 5.15.0-187.197 يستدعي kfree(pch) مباشرة وهو معرض للثغرة.
| الخاصية | القيمة |
|---|---|
| التوزيعة | Ubuntu 22.04.5 LTS (Jammy) |
| حزمة النواة | linux-image-5.15.0-187-generic / 5.15.0-187.197 |
| إصدار النواة | 5.15.0-187-generic #197-Ubuntu |
| البنية | x86-64 |
| الجهاز الافتراضي | QEMU/KVM، -cpu host، أربع وحدات vCPU، 5 GiB من الذاكرة |
| الهوية الأولية | uid=1001(poc) gid=1001(poc) groups=1001(poc) |
| الصلاحيات الأولية | الميراثية (inheritable) والمسموحة (permitted) والفعّالة (effective) والمحيطية (ambient) جميعها صفر |
| الهوية النهائية | uid=0(root) gid=0(root) في النطاقات الأولية |
| تغييرات الإقلاع | لا شيء؛ سطر أوامر قياسي مع تفعيل KASLR |
لم تتم إعادة تجميع النواة. كانت صورة السحابة المصغّرة تفتقر إلى linux-modules-extra-5.15.0-187-generic، لذا تم تثبيت تلك الحزمة الرسمية من Ubuntu لتوفير l2tp_ppp. يعتمد تثبيت Jammy العادي الذي يستخدم الحزمة الوصفية linux-generic أصلًا على حزمة modules-extra المطابقة. يتم تحميل وحدة البروتوكول تلقائيًا عندما ينشئ الاستغلال مقبس PPPoL2TP الخاص به.
| المتطلب | حالة Ubuntu 5.15.0-187 | استخدام الاستغلال |
|---|---|---|
| PPP | CONFIG_PPP=y | مدمجة في النواة |
| L2TP / PPPoL2TP | CONFIG_L2TP=m، CONFIG_PPPOL2TP=m | وحدة linux-modules-extra الرسمية |
| مفاتيح المستخدم | CONFIG_KEYS=y | يستعيد القناة المحرّرة kmalloc-256 |
| AppArmor | CONFIG_SECURITY_APPARMOR=y | تبقى مفعّلة؛ تشتمل بيانات الاعتماد المزوّرة على تسمية unconfined صالحة |
| KASLR | CONFIG_RANDOMIZE_BASE=y | يبقى مفعّلًا؛ يتم استرداد الإزاحة (slide) وقت التشغيل |
| SMAP | CONFIG_X86_SMAP=y | تبقى مفعّلة |
| نطاقات المستخدم/الشبكة | مفعّلة بواسطة Ubuntu لكنها غير مستخدمة | لا يلزم إعداد نطاقات أو اكتساب صلاحيات |
/dev/ppp | غير مطلوب | القناة مرتبطة لكنها لا تتصل أبدًا بوحدة PPP |
يستخدم كاشف KASLR التلقائي قناة جانبية (side channel) لتوقيت تعليمات prefetch في معمارية x86 ويتطلب تعليمة RDTSCP مع تعطيل KPTI. تُظهر وحدة المعالجة المركزية المضيفة المختبرة rdtscp وsmep وsmap وهي غير متأثرة بثغرة Meltdown، لذا تترك Ubuntu خاصية KPTI معطّلة دون أي تجاوز في الإقلاع. على معالج يبلغ فيه /proc/cpuinfo عن علم pti، يرفض الكاشف العمل. هذه حالة عتادية خاصة بالاستغلال: تبقى الثغرة الأساسية CVE قابلة للوصول، لكن هذا الإصدار لا يدّعي تجاوز KASLR على نظام مفعّل فيه KPTI. توجد إزاحة مقدّمة يدويًا لأغراض التشخيص المضبوط فقط.
struct channel. يتعامل مسار RX الذي لا يزال يعمل مع بايتات المفاتيح المتحكم بها على أنها قائمة skb وقائمة انتظار خاصة به.core_pattern كمساحة مساعدة للإفصاح وتكشف مؤشر تخصيص مفاتيح.override_creds() مع بيانات الاعتماد المزوّرة. تتطابق حقول UID/GID والصلاحيات (capabilities) ومؤشرات المستخدم والنطاق وucount والمجموعة المطلوبة مع نسخة بناء Ubuntu المحددة بدقة./proc/self/exe إلى ملف فريد في /tmp، ويغيّره إلى ملكية root بالوضع 4755 ويتحقق من تلك السمات./usr/bin/id.الجسر الأخير ضروري لأن override_creds() تغيّر بيانات الاعتماد الذاتية للمهمة النشطة في النواة؛ يحوّل تثبيت وتنفيذ النسخة SUID الموثّقة ذلك البدائي قصير الأمد إلى بيانات اعتماد عملية عادية.
يربط ملف Makefile الاستغلال ربطًا ثابتًا (statically). يتم تجميع كائن prefetch الحساس للتوقيت عمدًا عند مستوى -O0؛ بينما يستخدم الاستغلال نفسه مستوى -O2.
make
أوامر مكافئة:
gcc -O0 -Wall -Wextra -Werror -c -o build/kaslr_prefetch.o kaslr_prefetch.c
gcc -O2 -static -pthread -Wall -Wextra -Werror \
-o build/CVE-2026-68398 exploit.c build/kaslr_prefetch.o
من حساب المستخدم العادي على النواة المُتحقق منها بدقة: