
سكربتات Shell تتحقق من مضيفات Linux بحثًا عن CVE-2026-98432 وتطبّق قاعدة iptables u32 مؤقتة تُسقط حزم IPv4 TCP التي تحتوي على خيارات IP، مع وحدة systemd واختبار ذاتي وتراجع.
يحتوي هذا المستودع على ثلاثة نصوص برمجية تفحص مضيف Linux بحثًا عن CVE-2026-98432، وحيث لا تتوفر نواة مُصلَّحة، تُسقِط حزم IPv4 TCP التي تحمل خيارات IP بقاعدة iptables واحدة. وهو النظير بـ iptables لـ typhoon1217/cve-2026-98432-mitigation، الذي يفعل الشيء نفسه باستخدام nftables. إنه تخفيف مؤقت، وليس إصلاحًا. لم يُختبر ضد استغلال حقيقي (لا يوجد PoC عام)، ولا يتبنّاه أي مورّد. المؤلف مسؤول فردي، وليس مورّدًا.
هذا مخصص للمضيفين الذين لا يمكنهم الحصول على نواة مُصلَّحة ولا يمكنهم تشغيل نسخة nftables:
5.15.0-203، وبالنسبة لـ 24.04 لـ 6.8.0-149. إلى أن يتم إقلاع تلك النواة، يسدّ التخفيف الفجوة.iptables لكن بدون nft، أو لديهم nft قديم جدًا لـ ip hdrlength.وهو ليس مخصصًا لمضيفي Proxmox VE، الذين لديهم نواتهم المُصلَّحة الخاصة (7.0.14-25-pve وما بعده) وحركة مرور جسرية تحتاج إلى قاعدة الجسر من مستودع nftables. وهو ليس مخصصًا للمضيفين الذين يستخدمون SELinux أو Smack NetLabel CIPSO labeling، والذين يمكنهم الوصول إلى الشيفرة المعرّضة للخطر دون خيارات IP. وهو ليس مخصصًا للأنوية الأقدم من 4.4، التي لا تحتوي على الخطأ.
إذا كانت توزيعتك توفّر نواة مُصلَّحة، فثبّتها، وأعد التشغيل، وشغّل cve-98432-revert-iptables.sh إذا كنت قد طبّقت هذا.
CVE-2026-98432 هو حالة تسابق (race) في إعداد اتصال IPv4 TCP. تحتفظ النواة بخيارات IP الخاصة بـ SYN الوارد في ireq_opt، وفي التوقيت المناسب تُحرّر إحدى وحدات المعالجة (CPU) ذلك الكائن بينما لا تزال أخرى تقرأه. في الشيفرة الرئيسية (mainline)، لا يُضبط ireq_opt إلا عندما يحمل SYN خيارات ترويسة IPv4، أي أن ترويسة IP أطول من 20 بايت (IHL > 5)، أو عبر CIPSO labeling. وبدون خيارات لا يوجد شيء لتحريره أو قراءته. لذا تُسقِط القاعدة كل حزمة IPv4 TCP تكون ترويستها أطول من 20 بايت:
iptables -t raw -I PREROUTING -p tcp -m u32 --u32 "0>>24&0xF=6:15" -j DROP
مطابقة u32 تقرأ أول أربعة بايتات من ترويسة IP، وتُزيح البايت الأول للأسفل وتُبقي النيبل المنخفض منه، وهو حقل IHL بوحدات الكلمات ذات 32 بت. تطابق 6:15 كل قيمة أكبر من 5. يعمل خطاف PREROUTING في جدول raw قبل أن تُحلّل النواة الخيارات، وقبل conntrack. تمرّ حركة loopback عبر الخطاف نفسه، وهو ما يعتمد عليه الاختبار الذاتي.
في نطاق شبكة (network namespace) مع مستمع loopback، نجح اتصال SYN عادي بينما انتهت مهلة SYN يحمل خيار Record Route، مع وصول عدّاد القاعدة إلى حزمتين (SYN وإعادة إرسال واحدة). وقد سلكت قاعدة nftables ip hdrlength gt 5 السلوك نفسه. جرى اختبار كلٍّ من iptables-legacy وiptables-nft.
حركة TCP المشروعة التي تحمل خيارات IP نادرة. على تسعة مضيفات إنتاجية (mail وDNS وweb وXMPP) بقي العدّاد عند حزم الاختبار الذاتي طوال نافذة المراقبة.
cve-98432-check.sh. فهو للقراءة فقط. انظر إلى status وkernel_upstream_base وkernel_changelog_cve. تحمل نوى المورّد الإصلاح تحت أرقام إصداراتها الخاصة، لذا عندما يذكر سجل تغييرات النواة قيد التشغيل اسم CVE، فإن ذلك يتقدّم على مقارنة الإصدارات.iptables_u32_probe. يجب أن يقول ok. يشغّل الفحص الأمر iptables -C، الذي يسأل فقط عمّا إذا كانت القاعدة موجودة وبالتالي لا يضيف شيئًا؛ وتخبر الإجابة عمّا إذا كانت مطابقة u32 وجدول raw قابلين للاستخدام على هذه النواة.selftest_ipopt. تعني CONNECTED أن SYN الذي يحمل خيارات IP يمرّ حاليًا. وتعني FAIL أنه يُسقَط بالفعل.bash، وiptables مع xt_u32 وiptable_raw، وsystemd. وPython 2 أو 3 للاختبار الذاتي. المضيفات التي لا تعمل بـ systemd غير مشمولة.جُرّب على Debian 9 (iptables 1.6.0، legacy)، وDebian 10 و11 (iptables 1.8.x، خلفية nf_tables) وUbuntu 22.04 (iptables 1.8.7). وجُرّب مسار الإقلاع على Debian 10.
تُرسَل السكربتات إلى المضيف عبر SSH على المدخل القياسي، لذا لا يلزم نسخ أي شيء أولًا.
ssh root@HOST 'bash -s' < cve-98432-check.sh
ssh root@HOST 'bash -s' < cve-98432-apply-iptables.sh
إنه عديم الأثر عند التكرار (idempotent). يثبّت /usr/local/sbin/cve-2026-98432-mitigation (start|stop|status)، ووحدة systemd من نوع oneshot باسم cve-2026-98432-mitigation.service تُحمّل القاعدة قبل network-pre.target، وفقط عندما تعرف النواة MPTCP، يثبّت /etc/sysctl.d/99-cve-2026-98432.conf مع net.mptcp.enabled = 0. يخرج قبل تغيير أي شيء إذا لم يكن المستخدم root، أو إذا كان iptables أو systemd مفقودًا، أو إذا فشل فحص u32.host=... svc=active enabled=enabled mptcp=n/a
-A PREROUTING -p tcp -m u32 --u32 "0x0>>0x18&0xf=0x6:0xf" -j DROP
selftest_plain=CONNECTED
selftest_ipopt=FAIL TimeoutError
mptcp=0 على النوى 5.6 وما بعدها. تطبع إصدارات Python الأقدم FAIL timeout، وهي النتيجة نفسها.ssh root@HOST 'systemctl is-active cve-2026-98432-mitigation; /usr/local/sbin/cve-2026-98432-mitigation status'
while read -r h; do echo "##### $h"; ssh root@$h 'bash -s' < cve-98432-apply-iptables.sh; done < hosts.txt
شغّل الفحص مرة أخرى على كل مضيف تم تخفيفه وانظر إلى حقلين:
| الحقل | المتوقع |
|---|---|
cve_service | enabled/active |
selftest_ipopt | FAIL ... (تم إسقاط SYN الخاص بخيارات IP) |
يستخدم الاختبار الذاتي واجهة loopback. تمر حركة المرور من الشبكة عبر نفس خطاف PREROUTING، لذا تنتقل النتيجة. إذا أردت التأكيد من الخارج، فإن check-blocked.py وverify-synack.sh من مستودع nftables يعملان دون تغيير ضد مضيف تم تخفيفه بهذه الطريقة.
لمراقبة العدادات:
while read -r h; do
printf '%-28s ' "$h"
ssh -n root@$h '/usr/local/sbin/cve-2026-98432-mitigation status' 2>&1 | awk '{print "pkts="$1, "bytes="$2}'
done < hosts.txt
كل اختبار ذاتي يضيف حزمتين. العداد الذي ينمو إلى ما يتجاوز ذلك يعني أن حركة مرور حقيقية مع خيارات IP تصل إلى المضيف؛ انظر إلى ذلك قبل أن تقرر أي شيء. الأمر -n مهم: فبدونه يقرأ ssh بقية قائمة المضيفين من الإدخال القياسي وتتوقف الحلقة بعد أول مضيف.
العَرَض هو اتصال TCP يتعلّق (تنتهي مهلته) بدلًا من أن يُرفض، مع عداد متزايد.
| الأمر | التأثير |
|---|---|
systemctl stop cve-2026-98432-mitigation | إيقاف فوري، ويعود عند إعادة التشغيل |
systemctl disable --now cve-2026-98432-mitigation | إيقاف الآن وعبر عمليات إعادة التشغيل |
التوافق المقاس على المضيفين المختبَرين: تقع القاعدة في جدول raw، الذي لا يمسّه fail2ban. تم فحص ufw في الشيفرة المصدرية: إذ إن flush_builtins فيه داخل ufw-init-functions يفرّغ filter وmangle وnat فقط، لذا يترك ufw reload وufw disable القاعدة في مكانها. أي سكربت جدار حماية خاص بك يشغّل iptables -t raw -F سيزيلها؛ أعد تشغيل سكربت التطبيق أو systemctl restart cve-2026-98432-mitigation بعد ذلك.
uname -r، أو شغّل الفحص وابحث عن status=FIXED.ssh root@HOST 'bash -s' < cve-98432-revert-iptables.sh
أضف --mptcp إذا كان MPTCP مُفعَّلًا من قبل وتريد إعادته.remaining_u32_rules=0.