
استغلالات تعليمية متعددة اللغات لثغرة CVE-2026-31431، وهي تصعيد صلاحيات محلي في نواة لينكس عبر وحدة algif_aead، مع كاشف آمن وإرشادات استخدام في مسابقات CTF.
مستودع تعليمي يتضمن تطبيقات بلغات متعددة لاستغلال Copy Fail.
تم إنشاؤه وصيانته بواسطة @shotafry — لأن قراءة CVE ليست كافية. يجب إعادة إنتاجه.
Copy Fail هو ثغرة تصعيد صلاحيات محلية (LPE) في نواة لينكس، مصنفة كـ CVE-2026-31431. تؤثر على النظام الفرعي للتشفير في النواة، وتحديداً وحدة algif_aead التي تدير عمليات التشفير الموثّق (AEAD) عبر مآخذ AF_ALG.
تم إدخال الخلل في 2017 في تحسين لوحدة authencesn وظل غير مكتشف لمدة 9 سنوات تقريباً، وهو موجود في جميع توزيعات لينكس الحديثة تقريباً.
ما يجعل Copy Fail مميزاً مقارنة بثغرات LPE التاريخية الأخرى:
| الخاصية | Copy Fail | LPE نموذجي |
|---|---|---|
| يحتاج حالة سباق (race condition) | ❌ لا | ✅ نعم |
| يحتاج عنوان إزاحة محدد للنواة | ❌ لا | ✅ نعم |
| يعمل على جميع التوزيعات | ✅ نعم | ❌ عادةً لا |
| الموثوقية | حتمي 100% | متغير |
| يعدّل القرص | ❌ لا (RAM فقط) | يعتمد |
تم اكتشاف الثغرة بواسطة Taeyang Lee من فريق البحث في Theori. تم تطوير سلسلة الاستغلال الكاملة بواسطة فريق Xint Code Research، الذي وثق العملية باستخدام تحليل مدعوم بالذكاء الاصطناعي على النظام الفرعي crypto/ في نواة لينكس.
يتضمن الإفصاح العام PoC وظيفي، وتحليلاً تقنياً كاملاً، وتوثيقاً على copy.fail.
CVE: CVE-2026-31431
CVSS: 7.8 — عالية
المتجه: محلي
التأثير: تصعيد صلاحيات كامل (root)
التوزيعات: جميع توزيعات لينكس بنواة >= 2017 بدون تصحيح
درجة CVSS هي 7.8 ولا تصل إلى حرجة (9+) فقط لأنها تتطلب وصولاً محلياً مسبقاً — يجب أن يكون لدى المهاجم جلسة على النظام بالفعل. في بيئات السحابة ومع حاويات Docker، يكون هذا الشرط أسهل بكثير في تحقيقه مما يبدو.
تحتفظ نواة لينكس في RAM بالملفات التي تمت قراءتها مؤخراً. يُسمى هذا page cache. عندما تقرأ عملية /etc/passwd، لا تذهب النواة إلى القرص — بل تقدم النسخة الموجودة في RAM. هذا أسرع، لكنه يخلق سطح هجوم: إذا تمكنت من تعديل تلك النسخة في RAM دون لمس القرص، سيرى النظام بيانات مزيفة.
تسمح وحدة algif_aead بإجراء عمليات AEAD من مساحة المستخدم عبر مآخذ AF_ALG. الخلل موجود في التحسين الذي أُدخل في 2017: عند استخدام splice() لتمرير صفحات من ملف إلى المأخذ، تنتهي تلك الصفحات من page cache في قائمة التشتت الهدف (القابلة للكتابة) للعملية التشفيرية.
النتيجة: يمكن لأي مستخدم بدون صلاحيات كتابة 4 بايتات مُتحكم بها في أي ملف يمكنه قراءته، دون لمس القرص.
مستخدم بدون صلاحيات
│
▼
يفتح مأخذ AF_ALG (authencesn)
│
▼
sendmsg() — معاملات AEAD مع 4 بايتات لدينا في seqno_lo
│
▼
splice() — ملف → أنبوب → عملية المأخذ
[BUG] تبقى page cache للملف في قائمة التشتت الهدف
│
▼
recv() يطلق عملية AEAD
يفشل التحقق (EBADMSG) لكن الكتابة الخدشية حدثت بالفعل
│
▼
/etc/passwd (page cache) الآن يقول: مستخدم → UID 0
│
▼
su <مستخدم> → PAM يتحقق من كلمة المرور الحقيقية → setuid(0) → ROOT
تخيل أن النواة لديها سجل قيود القلعة (/etc/passwd). Copy Fail يشبه اكتشاف أنك إذا فتحت ورشة السحر في القلعة بترتيب محدد جداً، فإن سجل القيود يبقى بالخطأ على طاولة عملك — ويمكنك تغيير رتبتك من "جندي عادي" إلى "ملك" بقلم. أمين الأرشيف (PAM) يتحقق من كلمة مرورك لكنه لا يتحقق من السجل الأصلي، فقط من النسخة التي أمامك. أنت ملك.

>= ~2017 بدون تصحيح CVE-2026-31431algif_aead متاحة وقابلة للتحميليمكن تخطي هذا فعلياً وتجربة أحد الاستغلالات مباشرة، لكنه صالح أيضاً إذا لم نرغب في المخاطرة برفعها أو إنشائها ونريد فقط معرفة ما إذا كانت تعمل، لكن الاستغلالات لها وظيفتها للتحقق مما إذا كان النظام المعني عرضة للثغرة.
# عرض إصدار النواة
uname -a
# التحقق من توفر الخوارزمية
grep -i authencesn /proc/crypto
# التحقق من تحميل الوحدة
lsmod | grep alg
إذا أعاد grep -i authencesn /proc/crypto الناتج authencesn(hmac(sha256),cbc(aes))، فإن النظام عرضة للثغرة.
| اللغة | المتطلب على الهدف | الترجمة المسبقة |
|---|---|---|
| C | لا شيء (ملف ثنائي ثابت) | gcc على جهاز الترجمة |
| Python | Python 3.10+ | لا |
| Rust | لا شيء (ملف ثنائي ثابت) | rustc على جهاز الترجمة |
| Go | لا شيء (ملف ثنائي ثابت) | go على جهاز الترجمة |
| Ruby | Ruby + gem fiddle (مضمن افتراضياً) | لا |
| Perl | Perl 5 (مضمن في كل لينكس تقريباً) | لا |
يحتوي هذا المستودع على الاستغلال مطبقاً في 6 لغات، جميعها متكافئة وظيفياً، مع تعليقات تعليمية باللغة الإسبانية.
copy_fail_exploit.c → C — ملف ثنائي ثابت، صفر تبعيات
copy_fail_exploit.py → Python — الأكثر قابلية للقراءة، مثالي للتعلم
copy_fail_exploit.rs → Rust — السخرية: لغة "آمنة" تستغل النواة
copy_fail_exploit.go → Go — ملف ثنائي ثابت، قابل للنقل بدرجة كبيرة
copy_fail_exploit.rb → Ruby — موجود في كل مكان على خوادم Rails
copy_fail_exploit.pl → Perl — الأكثر صمتاً، موجود في كل لينكس
test_cve_2026_31431.py → كاشف — يتحقق من الثغرة دون استغلال أي شيء
python3 test_cve_2026_31431.py
# الترجمة
gcc copy_fail_exploit.c -o copy_fail_c
# تشغيل تجريبي (ينظف عند الخروج، لا يترك أثراً)
./copy_fail_c
# استغلال كامل
./copy_fail_c --shell
# تشغيل تجريبي
python3 copy_fail_exploit.py
# استغلال كامل
python3 copy_fail_exploit.py --shell
# الترجمة
rustc copy_fail_exploit.rs -o copy_fail_rs
# تشغيل تجريبي
./copy_fail_rs
# استغلال كامل
./copy_fail_rs --shell
# الترجمة
go build -o copy_fail_go copy_fail_exploit.go
# تشغيل تجريبي
./copy_fail_go
# استغلال كامل
./copy_fail_go --shell
# تشغيل تجريبي
ruby copy_fail_exploit.rb
# استغلال كامل
ruby copy_fail_exploit.rb --shell
# تشغيل تجريبي
perl copy_fail_exploit.pl
# استغلال كامل
perl copy_fail_exploit.pl --shell
# Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source ~/.cargo/env
# Go
apt install golang-go
# Ruby (عادةً مثبت مسبقاً في Kali)
apt install ruby
# Perl (موجود دائماً تقريباً)
perl --version
بمجرد تشغيل الاستغلال (قبل su)، يمكنك التحقق بصرياً من التغيير في page cache باستخدام: