
إثبات مفهوم غير مميَّز لثغرة CVE-2026-74586، وهي ثغرة استخدام بعد التحرير (use-after-free) في نواة لينكس ضمن بروتوكول SCTP ASCONF. يوفر الأداة مُحفِّز حزم خام (raw-packet trigger)، ومقاييس موثوقية، وتحليلاً مفصلاً للاستغلال يشمل إزاحات البنى (struct offsets) وبدائيات الحقن (spray primitives).
إثبات مفهوم (PoC) مكتفٍ ذاتيًا وغير مميّز لـ CVE-2026-74586، وهو use-after-free في
معالجة SCTP ASCONF (إعادة التهيئة الديناميكية للعناوين) في نواة Linux.
يعود الفضل في الخطأ نفسه إلى Qing Ming، الذي أبلغ عنه في المنبع؛
والإصلاح هو الالتزام beb33f8ee1ca ("sctp: clear new_transport when removing a
peer")، الذي دُمج في 2026-08-12 مع Cc: stable — تصنّفه Red Hat بأنه مهم،
وتضعه أدوات التتبع الخارجية عند CVSS 9.8.
ما يضيفه هذا المستودع فوق الإشعار:
تخزّن sctp_process_asconf_param() النقل (transport) الذي أنشأته معلمة ADD-IP
في asoc->new_transport. أما DEL-IP لنفس العنوان في نفس
قطعة ASCONF فيحرّر ذلك النقل عبر sctp_assoc_rm_peer()،
والتي (قبل الإصلاح) لا تُفرّغ new_transport. وعندما
تعود sctp_process_asconf()، تتعامل sctp_sf_do_asconf() مع
المؤشر القديم — وعلى نواة قياسية يكون الأثر المرئي هو إرسال HEARTBEAT
نحو عنوان النقل المحرَّر للتو؛ وتحت KASAN يكون تقرير
slab-use-after-free.
قطعة ASCONF واحدة تكفي:
[Address Parameter L] [ADD-IP G] [DEL-IP G]
gcc -O2 -Wall -o poc poc.c
./poc
لا جذر. يقوم الـ PoC بفك مشاركة مساحة اسم المستخدم + الشبكة، ويضبط إعدادات SCTP sysctls داخلها، ويقيم ارتباطًا متعدد المنافذ عبر loopback، ثم يحقن ASCONF المصمم باستخدام raw socket.
المخرجات المتوقعة على نواة مصابة بالثغرة:
[+] 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 مباشرة بعد ذلك لأن نبضة القلب عادت من العدم.
لا شيء من هذا بحث جديد، إنه فقط غير موثّق بما يكفي ليكلّفك فترة بعد الظهيرة، لذا ها هو للشخص التالي:
sctp_rcv() من checksum ويُسقط عند
عدم التطابق. احسب CRC32C (متعدد الحدود 0x82F63B78، معكوس) على
حزمة SCTP بأكملها مع تصفير حقل checksum.sctp_auth_recv_cid() في مسار
الإدخال قبل آلة الحالة ويُسقط ASCONF غير الموثّق حتى
عندما يكون addip_noauth_enable=1 — ذلك sysctl يخفف الفحص فقط
داخل sctp_sf_do_asconf(). المخرج هو عدم التفاوض على AUTH
على مستوى المقبس من الأساس (بدون SCTP_AUTH_SUPPORTED
setsockopt)، لذا يبقى peer.auth_capable false ويمرّ الفحصان.وسم Fixes: على الـ commit upstream هو 6af29ccc223b ("sctp: Bundle
HEARTBEAT into ASCONF_ACK")، لذا الكود قديم. أُصلح في mainline
وأُعيد نقله إلى السلسلة المستقرة (متتبع Debian: مُصلح من 7.1.9-1 في
sid، و6.12.107 في trixie-security). Kali rolling اعتبارًا من 2026-09-09 يشحن
7.1.5-1kali1 في كل المجموعات، وهو يسبق كل ذلك — هذه هي الأهمية
العملية الرئيسية لهذا PoC.
لمن يريد المضي قدمًا — مقيسًا مقابل 7.1.5 في QEMU، الإزاحات
من objdump -d لـ sctp.ko المشحون:
| الحقل | الإزاحة |
|---|---|
| flowi (88 بايت) | 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)، لا يوجد
تحرير مزدوج على هذا المسار. إذا كنت تأمل في إغلاق مقبس
والحصول على تحريرين — فإن sctp_association_free() يمشي فقط على قائمة
النقل، وrm_peer() قد فصل الشبح بالفعل. لا تُنفق
أمسية كاملة على ذلك.sctp_outq_select_transport() الحقل state عند +0x15c من
chunk->transport عند +0xe8 من الـ chunk. كائن مُستعاد م sprayed
بـ state=1 (ACTIVE) يغيّر سلوك النواة بعد التحرير — فالكائن
يُستشار.sctp_outq_select_transport() وهي تقرأ state=0xFFFF (قمامة slab)
من مؤشر نقل قديم تماماً عند لحظة الحقن. النتيجة: يجب أن يقوم
الرشّ بتهيئة الـ cache مسبقاً قبل الزناد، لا بعده —
فالكائن يُقرأ قبل أن تنتهي فترة السماح أصلاً على هذا المسار.*(p+0x288) مع p+0x288. هذا مؤشر ذاتي. لا
يمكنك الرشّ لتجاوزه دون معرفة عنوان الـ slab، أي أن
هذا العيب يحتاج إلى تسريب معلومات قبل أن يتحول التحكم في af_specific
إلى تحكم في مؤشر التعليمات. af_specific نفسه موقع استدعاء غير مباشر
(*(af_specific+0x18) مع rdi = transport)، فذلك هو الجائزة
بمجرد وجود تسريب.setsockopt(SCTP_AUTH_KEY) بمفتاح بحجم 800 بايت
يهبط في نفس cache الـ 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 للأجزاء المشتقة من النواة في المنطق؛ افعل ما تشاء بالباقي. للاختبار الأمني المصرّح به والبحث فقط.
acklock.c — قفل ناعم في ASCONF-ACK (غير مُصلح في كل إصدارات 7.1.x)عيب ثانٍ غير مُرقّع في النواة في نفس مسار الشيفرة، موضّح على
7.1.5: يقبل sctp_verify_asconf() قيمة TLV من نوع ERR_CAUSE بلا حد أدنى
للطول ويمشي على المعاملات بمحاذاة PAD4، بينما
يتقدم sctp_get_asconf_response() (مستهلك ASCONF-ACK) بالطول
الخام. ASCONF-ACK مصنوع يدوياً بحيث يكون طول TLV الخاص بـ ERR_CAUSE فيه 5
يزيح المستهلك بمقدار 3 بايتات؛ ثم تُقرأ الـ 4 بايتات التالية كـ
ترويسة معامل بـ length = 0، وasconf_ack_len -= 0 يدور
إلى الأبد — حلقة لا نهائية في softirq (ksoftirqd مثبّت عند 100%، والمعالج
يتضور، مؤكَّد بمهلات clocksource-watchdog في 3/3 من تشغيلات المختبر على
7.1.5).
أُصلح في mainline بواسطة 2cb0b0b1ed69 ("sctp: fix soft lockup from unpadded
ASCONF-ACK parameter iteration"، 2026-08-30) — غائب عن linux-7.1.y
عند HEAD (7.1.13)، لذا كل نواة 7.1.x مُصدَرة، بما في ذلك أحدث
نواة في Kali، متأثرة. عن بُعد، يتطلب ارتباطاً قائماً و
net.sctp.addip_noauth_enable=1 (أو تجاوز AUTH في نفس
النافذة). ابنِ وشغّل مثل poc.c:
gcc -O2 -Wall -o acklock acklock.c && ./acklock
راقب الجهاز الافتراضي: يتوقف المعالج خلال ثوانٍ من إقرار السم
(مهلة مراقب مصدر الساعة؛ مع نواة ممكّنة لمراقب NMI الخاص بـ perf
تحصل على تحذير BUG: soft lockup الكلاسيكي في sctp_get_asconf_response).