
إثبات مفهوم غير مميَّز لثغرة CVE-2026-74586، وهي ثغرة استخدام بعد التحرير (use-after-free) في نواة لينكس ضمن بروتوكول SCTP ASCONF. يوفر الأداة مُحفِّز حزم خام (raw-packet trigger)، ومقاييس موثوقية، وتحليلاً مفصلاً للاستغلال يشمل إزاحات البنى (struct offsets) وبدائيات الحقن (spray primitives).
PoC مستقل وغير مميز بصلاحيات لـ CVE-2026-74586، وهو ثغرة use-after-free في
معالجة SCTP ASCONF (إعادة تكوين العنوان الديناميكي) في نواة لينكس.
يعود الفضل في الثغرة نفسها إلى Qing Ming، الذي أبلغ عنها upstream؛
الإصلاح هو الالتزام beb33f8ee1ca ("sctp: clear new_transport when removing a
peer")، المدمج في 2026-08-12 مع Cc: stable — تصنّفها Red Hat على أنها مهمة،
وتضعها أدوات التتبع التابعة لجهات خارجية عند CVSS 9.8.
ما يضيفه هذا المستودع فوق النشرة الاستشارية:
تخزّن sctp_process_asconf_param() النقل الذي أنشأه معامل ADD-IP
في asoc->new_transport. إن DEL-IP لنفس العنوان في
نفس جزء ASCONF يحرر ذلك النقل عبر sctp_assoc_rm_peer()،
الذي (قبل الإصلاح) لا يمسح new_transport. عندما
تعود ، تتعامل مع المؤشر
القديم — على نواة قياسية يكون التأثير المرئي هو HEARTBEAT يُرسل
نحو عنوان النقل المُحرر للتو؛ تحت KASAN يكون تقرير
slab-use-after-free.
sctp_process_asconf()sctp_sf_do_asconf()جزء ASCONF واحد يكفي:
[Address Parameter L] [ADD-IP G] [DEL-IP G]
gcc -O2 -Wall -o poc poc.c
./poc
لا حاجة لصلاحيات root. يقوم الـ PoC بإلغاء مشاركة مساحة مستخدم + مساحة شبكة، ويضبط sysctls الخاصة بـ SCTP داخلها، ويُشغّل ارتباطًا متعدد الواجهات عبر loopback، ثم يحقن ASCONF المُصمم عبر مقبس خام.
المخرجات المتوقعة على نواة قابلة للاستغلال:
[+] Association established (no AUTH)
[+] server_vtag=0x... captured_tsn=0x...
[*] serial=0x... (= initial_tsn)
[+] Injected 60 bytes
[9222->9111 vt=...] ASCONF-ACK(0x80) len=8
[+] ASCONF-ACK -> server processed ADD-IP + DEL-IP
[9222->9111 vt=...] HB(0x04) len=60 <- kernel using freed transport
[9111->9222 vt=...] ABORT(0x06) len=8
[+] GhostTransport UAF TRIGGERED (ASCONF-ACK received)
[+] HEARTBEAT to ghost address observed (dangling transport USED)
الـ HEARTBEAT بعد الـ ACK هو الجزء المثير للاهتمام: هذه الحزمة
موجودة فقط لأن النواة سارت عبر new_transport المعلق. يقوم العميل
بإرسال ABORT بعدها مباشرة لأن الـ heartbeat عاد من خارج السياق.
لا شيء من هذا بحث جديد، إنه فقط غير موثق بما يكفي ليكلفك بعد ظهيرة كاملة، لذا إليك ذلك للشخص التالي:
sctp_rcv() من المجموع الاختباري وتُسقط
الحزمة عند عدم التطابق. احسب CRC32C (poly 0x82F63B78، منعكس) عبر
حزمة SCTP كاملة مع تصفير حقل المجموع الاختباري.sctp_auth_recv_cid() في مسار
الإدخال قبل آلة الحالة وتُسقط ASCONF غير المصادق عليه حتى
عندما يكون addip_noauth_enable=1 — ذلك sysctl يخفف الفحص فقط
داخل sctp_sf_do_asconf(). المخرج هو عدم التفاوض على AUTH
على مستوى المقبس من الأساس (بدون setsockopt لـ SCTP_AUTH_SUPPORTED)،
لذا يبقى peer.auth_capable خاطئًا ويمر كلا الفحصين.وسم Fixes: على الالتزام upstream هو 6af29ccc223b ("sctp: Bundle
HEARTBEAT into ASCONF_ACK")، لذا فإن الكود قديم. مُصلح في mainline
ومرحّل إلى سلسلة stable (متعقب Debian: مُصلح من 7.1.9-1 في
sid، و6.12.107 في trixie-security). يشحن Kali rolling اعتبارًا من 2026-09-09
الإصدار 7.1.5-1kali1 في كل suite، وهو يسبق كل ذلك — هذه هي
الأهمية العملية الرئيسية لهذا الـ PoC.
لأي شخص يريد المضي قدمًا — مُقاسًا ضد 7.1.5 في QEMU،
إزاحات من objdump -d لملف sctp.ko المُرفق:
| field | offset |
|---|---|
| flowi (88 bytes) | 0x30 |
| ipaddr | 0x88 |
| af_specific | 0xa8 |
| asoc | 0xb0 |
| dst | 0xe0 |
| state | 0x15c |
| rcu | 0x2b0 |
يقع sctp_association->new_transport عند 0x6b0. يأتي الجدول من
pahole -C sctp_transport /sys/kernel/btf/vmlinux على النواة قيد التشغيل —
نسخة سابقة من هذا الجدول حملت إزاحة ipaddr خاطئة (0x68،
من عد خاطئ لـ flowi)؛ BTF هو الحقيقة الأساسية.
sctp_transport_destroy_rcu)، لا يوجد
double-free على هذا المسار. إذا كنت تأمل في إغلاق مقبس
والحصول على تحريرين — sctp_association_free() يسير فقط عبر قائمة
النقل، وrm_peer() قام بالفعل بإلغاء ربط الشبح. لا تقضِ
أمسية في ذلك.sctp_outq_select_transport() الحقل state عند +0x15c من
chunk->transport عند +0xe8 من الجزء. كائن مستصلَح
مُرشّش بـ state=1 (ACTIVE) يغير سلوك النواة بعد التحرير —
يتم استشارة الكائن.sctp_outq_select_transport() وهو يقرأ state=0xFFFF (قمامة slab)
من مؤشر نقل قديم في لحظة الحقن تمامًا. النتيجة: يجب أن
يُجهز الرش ذاكرة التخزين المؤقت قبل المشغل، وليس بعده —
يُقرأ الكائن قبل انتهاء فترة السماح أبدًا على هذا المسار.*(p+0x288) بـ p+0x288. هذا مؤشر ذاتي. لا يمكنك
الرش لتجاوزه دون معرفة عنوان slab، أي
أن هذه الثغرة تحتاج إلى تسريب معلومات قبل أن يتحول التحكم في af_specific
إلى تحكم في مؤشر التعليمات. af_specific نفسه موقع استدعاء غير مباشر
(*(af_specific+0x18) مع rdi = transport)، لذا فهذا هو الهدف
بمجرد وجود تسريب.setsockopt(SCTP_AUTH_KEY) بمفتاح 800 بايت
يهبط في نفس ذاكرة kmalloc-1k. تذكر أن الترويسة هي
struct sctp_authkey { assoc_id; keynumber; keylength; key[] } و
يحتاج AUTH إلى التفعيل لكل مقبس أولاً عبر SCTP_AUTH_SUPPORTED مع
sctp_assoc_value — int عادي يعطي EINVAL.هذا PoC للمشغل/الانهيار. ليس تصعيد صلاحيات وهذا المستودع لا يدعي ذلك. شغّله ضد أنوية خاصة بك في جهاز افتراضي.
مُختبر على: 7.1.5+kali-amd64 (Kali rolling) و7.0.12+kali-amd64.
GPL-2.0 للأجزاء المشتقة من النواة في المنطق؛ افعل ما تشاء بالباقي. للاختبار الأمني المصرح به والبحث فقط.