
Ansible playbook لكشف وتطبيق تخفيف سطر أوامر النواة لثغرة CVE-2026-31431 (Copy Fail) عبر أساطيل Debian/Ubuntu/RHEL، مع كشف للقراءة فقط وتطبيق غير متكرر الأثر.
اكتشف وطبّق تخفيف سطر أوامر النواة لثغرة CVE-2026-31431 ("Copy Fail") عبر أسطول أنظمة Debian / Ubuntu / عائلة RHEL باستخدام Ansible.
الثغرة هي خلل في تصعيد الامتيازات المحلية في واجهة algif_aead من نوع AF_ALG في نواة لينكس. أي مستخدم محلي غير مميَّز — بما في ذلك حسابات الخدمات مثل www-data أو mysql أو العمليات داخل تطبيق ويب مخترق عبر RCE — يمكنه ربطها بالجذر في بضع استدعاءات نظام. تؤثر الثغرة على كل توزيعة رئيسية صدرت منذ عام 2017.
initcall_blacklist=algif_aead_init
بسطر أوامر النواة — عند استدعائها مع -e apply_mitigation=true.تعمل قائمة الحظر في سطر أوامر النواة على كلٍّ من الإعدادات المدمجة (عائلة RHEL) والوحدات النمطية (Debian/Ubuntu)، وهو ما لا يفعله الحل البديل الشائع الاستشهاد به modprobe blacklist algif_aead.
algif_aead_init() هي دالة النواة التي تسجّل خوارزمية aead من نوع AF_ALG مع نظام مآخذ التشفير عند الإقلاع. معامل سطر الأوامر initcall_blacklist=algif_aead_init يوجّه النواة لتخطي ذلك الاستدعاء التهيئي. لا يزال الكود الضعيف موجودًا في ثنائي النواة، لكن socket(AF_ALG, ..., "aead") يُرجع ENOENT، لذا يفشل أول استدعاء نظام للاستغلال. لا سطح يمكن الوصول إليه، لا تصعيد امتيازات.
بمجرد أن توفّر البائعون أنوية مصححة وتعيد التشغيل إليها، لم يعد التخفيف ضروريًا ويمكن إزالته.
# 1. الكشف (للقراءة فقط) — يُنتج تقرير حالة لكل مضيف
ansible-playbook -i inventory check_cve_2026_31431.yml
# 2. مرحلة التخفيف على مضيف واحد أولًا (بدون إعادة تشغيل تلقائية)
ansible-playbook -i inventory --limit <ip-or-host> \
-e apply_mitigation=true check_cve_2026_31431.yml
# 3. أعد تشغيل ذلك المضيف عبر آليتك المعتادة
# 4. أعد الكشف؛ تأكد من "Mitigation active: yes"
# 5. انشر على بقية الأسطول على دفعات
يبدو تقرير المضيف الضعيف هكذا:
═══════════════════════════════════════════
Host: 192.168.1.42
Distro: Ubuntu 24.04
Kernel: 6.8.0-60-generic
Mitigation active: no
Mitigation staged: no
═══════════════════════════════════════════
⚠️ 192.168.1.42: CVE-2026-31431 mitigation is NOT active.
خارج نطاق هذه الوصفة. أوامر يدوية:
# Debian / Ubuntu
sudo sed -i 's/ initcall_blacklist=algif_aead_init//' /etc/default/grub
sudo update-grub
sudo reboot
# عائلة RHEL
sudo grubby --update-kernel=ALL --remove-args="initcall_blacklist=algif_aead_init"
sudo reboot
مسار الكشف للقراءة فقط بشكل صارم (uname، قراءة /proc/cmdline،
قراءة /etc/default/grub، grubby --info=ALL). تستخدم الفحوصات
failed_when: false بحيث لا يوقف الإخراج غير المتوقع التشغيل أبدًا.
ignore_unreachable: true تعني أن المضيفات التي لا يمكن الوصول إليها تحصل على تحذير واضح "UNREACHABLE — treat as VULNERABLE" بدلًا من إفشال التشغيل.
مسار التطبيق مغلّف في block/rescue بحيث لا يوقف مضيف سيئ واحد بقية المضيفات أبدًا. تعديل grub غير حتمي ومقيَّد بـ mitigation_staged بحيث تكون عمليات إعادة التشغيل بلا تأثير.
bash tests/run-checks.sh all
المراحل: lint (yamllint + ansible-lint) → syntax
(ansible-playbook --syntax-check) → dry-run (تنفيذ دليل التشغيل في
وضع --check ضد localhost مع -c local، لكلٍّ من مساري الكشف والتطبيق). يُستدعى نفس السكربت بواسطة مصفوفة GitHub Actions عبر حاويات debian:12 وubuntu:22.04 وubuntu:24.04 وalmalinux:9 عند كل push وpull request.
ما لا يتحقق منه التشغيل الجاف:
update-grub، ولا يطلق إعادة تشغيل./proc/cmdline داخل حاوية CI يُظهر سطر أوامر مضيف التشغيل،
وليس سطر أوامر الحاوية، لذا فإن mitigation_active في مخرجات CI بلا معنى.
يثبت CI أن دليل التشغيل يعمل بنظافة؛ ولا يثبت أن المضيف مخفَّف.انظر tests/README.md للمزيد.
الثغرة اكتشفها Taeyang Lee (Theori) وحُوّلت إلى سلسلة استغلال كاملة بواسطة Xint Code Research Team، الذين يستحقون الفضل في جعل مجتمع الأمن ينتبه. هذه الوصفة فقط تؤتمت التخفيف الذي أوصوا به.
Beerware. انظر LICENSE. الخلاصة: افعل ما تشاء بهذا؛
إذا التقينا يومًا، اشترِ لي بيرة.
AESTECHNO — Hugues Orgitello — دار تصميم إلكترونيات، مونبلييه، فرنسا.