
अविशेषाधिकार प्राप्त (unprivileged) प्रूफ-ऑफ-कॉन्सेप्ट CVE-2026-74586 के लिए, जो Linux कर्नेल SCTP ASCONF use-after-free है। इसमें रॉ-पैकेट ट्रिगर, विश्वसनीयता मेट्रिक्स, और struct ऑफसेट तथा स्प्रे प्रिमिटिव सहित विस्तृत वेपनाइज़ेशन विश्लेषण शामिल है।
CVE-2026-74586 के लिए एक स्व-निहित, विशेषाधिकार-रहित PoC, जो Linux कर्नेल के SCTP ASCONF (गतिशील पता पुनर्विन्यास) हैंडलिंग में उपयोग-के-बाद-मुक्त (use-after-free) है। बग का श्रेय स्वयं Qing Ming को जाता है, जिन्होंने इसे अपस्ट्रीम रिपोर्ट किया; फिक्स कमिट beb33f8ee1ca ("sctp: clear new_transport when removing a peer") है, जो 2026-08-12 को Cc: stable के साथ मर्ज किया गया — Red Hat इसे महत्वपूर्ण (important) दर्जा देता है, तृतीय-पक्ष ट्रैकर्स इसे CVSS 9.8 पर रखते हैं।
यह रिपॉजिटरी एडवाइजरी के ऊपर जो जोड़ती है:
sctp_process_asconf_param() ADD-IP पैरामीटर द्वारा बनाए गए ट्रांसपोर्ट को asoc->new_transport में संग्रहीत करता है। उसी ASCONF चंक में उसी पते के लिए एक DEL-IP उस ट्रांसपोर्ट को sctp_assoc_rm_peer() के माध्यम से मुक्त करता है, जो (फिक्स से पहले) को साफ़ नहीं करता है। जब लौटता है, तो पुराने (stale) पॉइंटर पर कार्य करता है — स्टॉक कर्नेल पर दृश्य प्रभाव अभी-अभी मुक्त किए गए ट्रांसपोर्ट के पते की ओर उत्सर्जित एक HEARTBEAT है; KASAN के तहत यह एक slab-use-after-free रिपोर्ट है।
new_transportsctp_process_asconf()sctp_sf_do_asconf()एक ASCONF चंक पर्याप्त है:
[Address Parameter L] [ADD-IP G] [DEL-IP G]
gcc -O2 -Wall -o poc poc.c
./poc
कोई रूट नहीं। PoC एक यूज़र + नेटवर्क नेमस्पेस को अनशेयर करता है, उसमें SCTP sysctl सेट करता है, लूपबैक पर एक मल्टी-होम्ड एसोसिएशन स्थापित करता है, फिर रॉ सॉकेट के साथ तैयार किया गया 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)
ACK के बाद का HEARTBEAT दिलचस्प हिस्सा है: वह पैकेट केवल इसलिए मौजूद है क्योंकि कर्नेल ने लटकते (dangling) new_transport पर चला। क्लाइंट उसके तुरंत बाद ABORT करता है क्योंकि हार्टबीट आउट-ऑफ-द-ब्लू वापस आया।
इनमें से कोई भी नया शोध नहीं है, यह केवल इतना अप्रलेखित है कि एक दोपहर खर्च हो जाती है, इसलिए अगले व्यक्ति के लिए यहाँ है:
sctp_rcv() चेकसम सत्यापित करता है और बेमेल होने पर छोड़ देता है। चेकसम फ़ील्ड को शून्य करके पूरे SCTP पैकेट पर CRC32C (poly 0x82F63B78, reflected) की गणना करें।sctp_auth_recv_cid() स्टेट मशीन से पहले इनपुट पथ में चलता है और अनप्रमाणित ASCONF को छोड़ देता है, भले ही addip_noauth_enable=1 हो — वह sysctl केवल sctp_sf_do_asconf() के अंदर की जाँच को शिथिल करता है। बाहर निकलने का रास्ता यह है कि पहले स्थान पर सॉकेट स्तर पर AUTH को कभी बातचीत (negotiate) न करें (कोई SCTP_AUTH_SUPPORTED setsockopt नहीं), ताकि peer.auth_capable गलत (false) रहे और दोनों जाँचें पास हों।अपस्ट्रीम कमिट पर Fixes: टैग 6af29ccc223b ("sctp: Bundle HEARTBEAT into ASCONF_ACK") है, इसलिए कोड पुराना है। मेनलाइन में फिक्स्ड और स्थिर (stable) श्रृंखला में बैकपोर्ट किया गया (Debian ट्रैकर: sid में 7.1.9-1 से, trixie-security में 6.12.107 से फिक्स्ड)। 2026-09-09 तक Kali rolling हर सुइट में 7.1.5-1kali1 भेजता है, जो इन सभी से पहले का है — यही इस PoC की मुख्य व्यावहारिक प्रासंगिकता है।
इसे आगे ले जाने वालों के लिए — QEMU में 7.1.5 के विरुद्ध मापा गया, शिप किए गए sctp.ko के objdump -d से ऑफसेट:
| 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), इस पथ पर कोई डबल-फ्री नहीं है। यदि आप एक सॉकेट बंद करके दो फ्री पाने की उम्मीद कर रहे थे — sctp_association_free() केवल ट्रांसपोर्ट सूची पर चलता है, और rm_peer() पहले ही घोस्ट को अनलिंक कर चुका है। उस पर एक शाम बर्बाद न करें।sctp_outq_select_transport() चंक के +0xe8 पर chunk->transport से +0x15c पर state पढ़ता है। state=1 (ACTIVE) के साथ स्प्रे किया गया एक पुनःप्राप्त (reclaimed) ऑब्जेक्ट फ्री के बाद कर्नेल व्यवहार बदल देता है — ऑब्जेक्ट से परामर्श लिया जा रहा है।state=0xFFFF (slab कचरा) पढ़ते हुए sctp_outq_select_transport() को पकड़ा। परिणाम: स्प्रे को ट्रिगर से पहले कैश को पहले से ग्रूम करना होगा, बाद में नहीं — इस पथ पर ग्रेस पीरियड समाप्त होने से पहले ही ऑब्जेक्ट पढ़ा जाता है।*(p+0x288) की तुलना p+0x288 से करता है। यह एक सेल्फ-पॉइंटर है। आप स्लैब पता जाने बिना उसके पार स्प्रे नहीं कर सकते, अर्थात इस बग को af_specific नियंत्रण के इंस्ट्रक्शन-पॉइंटर नियंत्रण में बदलने से पहले एक सूचना लीक (info leak) की आवश्यकता है। af_specific स्वयं एक अप्रत्यक्ष कॉल साइट है (*(af_specific+0x18) जिसमें rdi = transport है), इसलिए लीक मौजूद होने पर यही पुरस्कार है।setsockopt(SCTP_AUTH_KEY) उसी kmalloc-1k कैश में उतरता है। याद रखें हेडर struct sctp_authkey { assoc_id; keynumber; keylength; key[] } है और AUTH को पहले प्रति-सॉकेट SCTP_AUTH_SUPPORTED के साथ sctp_assoc_value के माध्यम से सक्षम करने की आवश्यकता है — एक सादा int EINVAL देता है।यह एक ट्रिगर/क्रैश PoC है। यह विशेषाधिकार वृद्धि नहीं है और यह रिपॉजिटरी किसी का दावा नहीं करती। इसे VM में अपने स्वयं के कर्नेल के विरुद्ध चलाएँ।
परीक्षित: 7.1.5+kali-amd64 (Kali rolling) और 7.0.12+kali-amd64।
तर्क के कर्नेल-व्युत्पन्न भागों के लिए GPL-2.0; बाकी के साथ जो चाहें करें। केवल अधिकृत सुरक्षा परीक्षण और शोध के लिए।