
EDK II UEFI PXE ICMP त्रुटि ओवरफ़्लो (CVE-2026-97631) के लिए एक्सप्लॉइट टूलिंग: स्पूफ़्ड ICMP पैकेट तैयार करता है, एक नकली EFI_EVENT स्थापित करता है, और UART के माध्यम से DXE मेमोरी डंप करता है।
EDK II PXE Base Code ड्राइवर ICMP त्रुटि ओवरफ़्लो के लिए टूलिंग
(NetworkPkg/UefiPxeBcDxe, GHSA-99cj-7hg9-mp4m, CVSS 4.0 9.5)।
PXE बूट के दौरान ड्राइवर एक ICMP त्रुटि संदेश को एक निश्चित 504-बाइट
बफ़र में कॉपी करता है। इससे लंबा संदेश उस बफ़र से आगे, DXE
पूल में, एक रैखिक राइट बन जाता है। चूँकि राइट गंतव्य बफ़र का ही पता है, पेलोड
स्थिति-स्वतंत्र (position independent) है: डेटाग्राम का बाइट i &Mode->IcmpError + i पर पहुँचता है।
ओवरफ़्लो एक नकली EFI_EVENT स्थापित करता है; DXE कोर इसे
सामान्य CoreSignalEvent पथ के माध्यम से डिस्पैच करता है; पेलोड एक
स्नैपशॉट से इवेंट को पुनर्स्थापित करता है, ऑपरेटर द्वारा चुनी गई मेमोरी रेंजों को ट्रैवर्स करता है, और EFI_SUCCESS लौटाता है ताकि
बूट जारी रहे।
प्रभाव-क्षेत्र (Blast radius) फ़र्मवेयर की अपनी DXE मेमोरी के भीतर ही रहता है। कोई फ़्लैश राइट नहीं, कोई स्थायित्व (persistence) तंत्र नहीं, कोई OS आर्टिफ़ैक्ट नहीं।
include/pxe_layout.h EFI_PXE_BASE_CODE_ICMP_ERROR, IEVENT offsets, wire structs
include/craft.h one packet = one primitive
include/graft.h counterfeit event + payload parameter block
include/layout.h the overflow region (single source of truth)
src/payload.S ring-0 payload: restore, walk ranges, stream out
src/craft.c packet construction, IPv4 + IPv6
src/graft.c IEVENT overlay, parameter block
src/layout.c overflow assembly, shared by sender and simulator
src/main.c pxeinj: sniff xid, probe, send
src/net.c raw L3 transport, DHCP xid sniffer
src/recv.c pxerecv: serial collector, dump + map
sim/sim.c host harness that proves the chain
tools/fw_offsets.py pool offsets from a debug firmware build
पेलोड:
as --64 -o build/payload.o src/payload.S
ld -Ttext=0 -e payload_start --oformat elf64-x86-64 -o build/payload.elf build/payload.o
objcopy -O binary --only-section=.text build/payload.elf build/payload.bin
परिणाम 378 बाइट्स है, स्थिति-स्वतंत्र, कोई पुनर्स्थापन नहीं।
प्रेषक और प्राप्तकर्ता POSIX (AF_PACKET, IP_HDRINCL, termios) हैं और Linux पर make के साथ बनते हैं। सिम्युलेटर Makefile.win के माध्यम से MSVC के साथ बनता है:
cl /nologo /W3 /O2 /Iinclude /Fe:build\sim.exe sim\sim.c src\craft.c src\graft.c src\layout.c
build/sim.exe एक नकली पूल पेज को मैप करता है, ओवरफ़्लो को वहाँ लिखता है जहाँ कमज़ोर
memcpy लिखता, जाँचता है कि परिणामी IEVENT पेलोड को डिस्पैच करेगा, पेलोड को वास्तविक मशीन कोड के रूप में कॉल करता है, और फिर सत्यापित करता है:
लेआउट, ABI, फ़्रेमिंग और पैकेट निर्माण पर 26 जाँचें। यह सिद्ध करता है कि भाग एक-दूसरे से सहमत हैं। यह किसी विशिष्ट फ़र्मवेयर के पूल पते को सिद्ध नहीं करता, जो एक रनटाइम आवंटन है।
दो मोड, क्रम में उपयोग किए जाते हैं।
प्रोब: केवल वैध पथ, कोई आउट-ऑफ़-बाउंड्स राइट नहीं।
pxeinj --target 10.0.0.50 --spoof 10.0.0.1 --sniff --probe --send
एक 504-बाइट, सुगठित ICMP त्रुटि। वही spoof, वही एम्बेडेड BOOTP ट्रांज़ैक्शन, वही सब कुछ। यदि क्लाइंट बूट होता रहता है, तो त्रुटि स्वीकार कर ली गई और कमज़ोर कॉपी लूप तक पहुँच गया। गैर-विनाशकारी पुष्टि, और इसे किसी pool पते की आवश्यकता नहीं है।
Overflow: तीन चीज़ें मौजूद होने तक बनाने से इनकार करता है: pool आधार
(tools/fw_offsets.py), प्राचीन इवेंट बाइट्स (--shadow), और कम से कम एक
रेंज।
pxeinj --target 10.0.0.50 --spoof 10.0.0.1 --xid 0xdeadbeef \
--pool-base 0x7f12345000 --payload build/payload.bin \
--ranges ranges.txt --shadow shadow.bin --uart 0x3f8 --send
pxerecv -d /dev/ttyUSB0 -o dump.bin -m dump.map
ranges.txt में प्रति पंक्ति एक START-END होता है, हेक्स में बिना 0x के; आकार और समय बजट के लिए
ranges.example.txt देखें। v6 ओवरफ़्लो पथ अक्षम है: प्रोब v6 पर काम करता है, लेकिन राइट नहीं करता, जब तक कि
पैच किए गए स्रोत से v6 कॉपी बाउंड को फिर से प्राप्त न किया जाए।
EFI_SUCCESS लौटाता है, इसलिए बूट आगे बढ़ता हैSignalLink स्व-संगत है, इसलिए सूची वॉक असर्ट नहीं करताअवशिष्ट निशान इस बग में अंतर्निहित हैं: इवेंट को उस समय सिग्नल किया गया जब सामान्य रूप से नहीं किया जाता, पूल पेज गंदा रहता है, और यदि प्लेटफ़ॉर्म TPM के साथ DXE को मापता है तो PCR मान वही रहता है जो बूट शुरू होने पर था। इससे आगे कुछ भी इस बग की विशेषता नहीं है।
--send आवश्यक है; डिफ़ॉल्ट एक ड्राई रन है--pool-base, --payload, --shadow और एक गैर-रिक्त रेंज सूची के बिना बिल्ड होने से इंकार करता है। इनमें से प्रत्येक के पास फर्मवेयर को भ्रष्ट करने का एक विशिष्ट तरीका है यदि अनुमान लगाया जाए, इसलिए कोई भी वैकल्पिक नहीं है--shadow में अपेक्षित ऑफ़सेट पर एक EFI_EVENT सिग्नेचर होना चाहिए, जो एक ही जाँच में शून्य-भरे फ़ाइल और गलत --event-off को पकड़ लेता है, डिस्पैच समय पर नहींMode->IcmpError का पूल पता एक रनटाइम आवंटन है और प्रति फर्मवेयर बिल्ड भिन्न होता है। इसे लिंक मैप से प्राप्त नहीं किया जा सकता। tools/fw_offsets.py ऑफ़सेट देता है; बेस को लक्ष्य फर्मवेयर पर मापा जाना चाहिए, उदाहरण के लिए DEBUG_POOL ट्रेस से, और फिर कैश किया जाना चाहिए।sizeof(EFI_PXE_BASE_CODE_MODE) और offsetof(..., IcmpError) edk2 रिलीज़ के बीच बदलते हैं। tools/fw_offsets.py में डिफ़ॉल्ट प्रारंभिक बिंदु हैं, भरोसेमंद मान नहीं।DpcHandle फ़ंक्शन पढ़ें।CoreSignalEvent चलता है। इस कारण से टूल --shadow के बिना बिल्ड होने से इंकार करता है।