
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) الإصلاح تحت رقم إصدار مختلف، لذا فإن مصدر الرمز الدقيق أو سجل تغييرات الحزمة له الأولوية على هذا الجدول.
تتطلب خطوط النوى المدعومة الأقدم من جهة البائعين نقلًا عكسيًا (backport). اعتبارًا من 2026-08-12، يضع متتبع CVE لنظام Ubuntu حزمة linux الخاصة بـ Jammy في حالة needs-triage؛ ولم يتم تحديد أي حزمة Ubuntu Jammy مصححة. لا يزال مصدر الإصدار المُختبر 5.15.0-187.197 يستدعي kfree(pch) مباشرة وهو معرض للثغرة.
لم تتم إعادة تجميع النواة. كانت صورة السحابة المصغّرة تفتقر إلى linux-modules-extra-5.15.0-187-generic، لذا تم تثبيت تلك الحزمة الرسمية من Ubuntu لتوفير l2tp_ppp. يعتمد تثبيت Jammy العادي الذي يستخدم الحزمة الوصفية linux-generic أصلًا على حزمة modules-extra المطابقة. يتم تحميل وحدة البروتوكول تلقائيًا عندما ينشئ الاستغلال مقبس PPPoL2TP الخاص به.
يستخدم كاشف 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
من حساب المستخدم العادي على النواة المُتحقق منها بدقة:
id
grep '^Cap' /proc/self/status
./CVE-2026-68398 auto 60
يفحص المصدر الدالة uname() ويرفض أي إصدار غير 5.15.0-187-generic. السباق احتمالي؛ أعد إقلاع لقطة قابلة للتخلص منها قبل إعادة المحاولة بعد فشل أو انهيار.
ينتهي التشغيل الناجح بما يلي:
[KASLR] image_base=0xffffffffb9200000 slide=0x38200000
CVE-2026-68398 Ubuntu local privilege-escalation exploit
uid=1001 euid=1001 slide=0x38200000
...
[9/9] invoking override_creds and installing the SUID transition...
override callback: uid=0 euid=0 gid=0 egid=0
installed root-owned mode 4755 helper: /tmp/.cve-2026-68398-root-948
SUID helper ready; executing it from the original unprivileged task...
SUID transition: uid=0 euid=0 gid=0 egid=0
uid=0(root) gid=0(root) groups=0(root),1001(poc)
السجل الكامل المختصر من ذلك التشغيل الفعلي في QEMU موجود في docs/example-output.txt.
اكتملت السلسلة على ثلاث مرات إقلاع جديدة لنظام Ubuntu بعشوائية عادية. كانت قواعد الصورة المستردة تلقائيًا 0xffffffff90800000 و0xffffffffa5a00000 و0xffffffffb9200000. استخدم التشغيل النهائي حساب UID 1001 غير الإداري المخصص الموصوف أعلاه، وتحقّق من إزالة ملف SUID المؤقت بعد ذلك.
تم أيضًا تشغيل السباق النهائي نفسه لمدة 60 ثانية على التزام الإصلاح الرسمي (upstream) نفسه مع تفعيل KASAN وبنفس طوبولوجيا أربع وحدات vCPU. أكمل 5,969 دورة قناة/مفتاح، وأبلغ عن stage 1: no controlled reclaim، ولم يُنتج أي تقرير KASAN أو انتقال بين مراحل الاستغلال.
تم الفحص في 2026-08-12 قبل إنشاء هذا المستودع الخاص. لم يُرجع SearchSploit/Exploit-DB أي استغلال؛ ولم يُرجع Packet Storm أي ملف مطابق؛ وأعاد بحث GitHub عن الكود الدقيق 22 مرآة لسجلات CVE/نشرات أمنية دون أي PoC؛ ولم تعثر عمليات البحث الدقيقة على الويب إلا على الإصلاح الرسمي والبيانات الوصفية. هذه نتيجة لحظية، وليست ضمانًا بعدم ظهور PoC آخر لاحقًا.
kaslr_prefetch.cكُتب الاستغلال بواسطة A. Ramos <[email protected]> (تويتر: @aramosf). يُنسب اكتشاف الثغرة والإصلاح الرسمي إلى Norbert Szetei (Doyensec).
exploit.c مرخّص بموجب GPL-2.0 فقط. kaslr_prefetch.c وkaslr_prefetch.h مرخّصان بموجب MIT ويحتفظان بنسبة KASLD وإشعار الإذن الكامل في ملفات المصدر.
| خط النواة | أول إصدار مُصلَح | التزام الإصلاح |
|---|
| 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 |
| الخاصية | القيمة |
|---|
| التوزيعة | 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 |
| المتطلب | حالة 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 |