- rhboot/shim के commit
0226b56ने CVE-2023-40547 को fix किया, जो file receive करने की प्रक्रिया में HTTP header के size value पर सीधे भरोसा करने से पैदा हुआ था - अगर manipulated header असल received data से छोटा size specify करता है, तो shim ज़रूरी buffer से कम space allocate कर सकता है
- पुराने code में allocation के लिए header value और copy के लिए protocol metadata इस्तेमाल किया जाता था, जिससे out-of-bounds write हो सकता था
- patch ने
httpboot.cकेreceive_http_response()में*buf_size < rx_message.BodyLengthcheck जोड़ा, और fail होने पर इसेEFI_BAD_BUFFER_SIZEऔरInvalid Content-Lengthके रूप में handle किया - बदलाव का scope
httpboot.cकी 1 file में 7 lines added और 1 line deleted है, औरContent-Lenghttypo को भीContent-Lengthमें सुधारा गया
Vulnerability होने का flow
- CVE-2023-40547 एक issue है जो तब होता है जब shim HTTP या related protocols से file fetch करता है
- received data store करने के लिए buffer allocate करते समय HTTP header का size value इस्तेमाल किया जाता है
- HTTP header manipulate किया जा सकता है, और वह असल received data से छोटा size specify कर सकता है
- पुराने flow में buffer allocation के लिए header value इस्तेमाल होती थी, और rx buffer से data copy करते समय basis protocol metadata होता था
- इस difference के कारण allocated buffer से बड़ा data copy हो सकता था, और परिणामस्वरूप out-of-bounds write हो सकता था
Patch details
- patch ने
httpboot.cकेreceive_http_response(EFI_HTTP_PROTOCOL *http, VOID **buffer, UINT64 *buf_size)में defensive check जोड़ा - जब
*buf_size == 0हो, तो existing error message का typo ठीक करता है औरgoto errorपर जाता हैFailed to get Content-Lenght→Failed to get Content-Length
- नया check
*buf_size < rx_message.BodyLengthcondition verify करता है- अगर condition true है, तो
efi_status = EFI_BAD_BUFFER_SIZEset करता है Invalid Content-Lengtherror output करता है- इसके बाद
goto errorपर जाता है
- अगर condition true है, तो
Change scope
- बदली गई file सिर्फ
httpboot.cहै - बदलाव की मात्रा 7 lines added, 1 line deleted है
- core logic यह check करना है कि received body length
rx_message.BodyLength, allocation size*buf_sizeसे बड़ा है या नहीं
Related records
- यह commit CVE-2023-40547 को resolve करने वाला change बताया गया है
- commit message साफ बताता है कि issue HTTP header पर गलत भरोसे से आया था
- vulnerability reporter Microsoft Security Response Center के Bill Demirkapi दर्ज हैं
1 टिप्पणियां
Hacker News की राय
shim एक EFI bootloader है, जिसे Secure Boot चालू करना चाहने वाले Linux distributions में आम तौर पर इस्तेमाल किया जाता है
distribution के नज़रिए से वे चाहते हैं कि user खुद key register करने के बजाय, पहले से मौजूद Microsoft-signed key के साथ Secure Boot आसानी से चालू कर सके
लेकिन Microsoft आम तौर पर GRUB जैसे GPL bootloaders को sign नहीं करता, इसलिए ऐसा shim बनाया गया जिसे Microsoft key से sign किया जा सके, और shim अपने boot target के signature को Machine Owner Key, यानी MOK, नाम की अलग key से verify करता है
shim में boot करने के लिए EFI binary specify करते समय HTTP URL दिया जा सकता है, और इस स्थिति में अगर HTTP server malicious हो तो out-of-bounds write कराया जा सकता है
हालांकि आम तौर पर इसका इस्तेमाल GRUB जैसे local second-stage bootloader को boot करने के लिए होता है, इसलिए ज़्यादातर installs में इसके समस्या बनने की संभावना कम लगती है
Secure Boot को शुरू से ही ऐसा design किया गया था कि पहले से signed binaries को भी DBX list के जरिए revoke किया जा सके, और इस list को UEFI में डालने पर valid signature होने के बावजूद वह binary reject कर दी जाती है
अगर इस bug वाले पुराने shim binaries के signatures list में जोड़ दिए जाते हैं, तो लोग अपने-अपने devices पर list update कर सकते हैं; यह LVFS जैसे capsule updates के रूप में distribute भी हो सकती है, और अगर आप Secure Boot keys और variables सीधे manage करते हैं, तो https://uefi.org/revocationlistfile से list download करके register भी कर सकते हैं
अगर ऐसा होता तो इसे Critical rating नहीं मिली होती
इस bug को local privileged malware द्वारा EFI partition overwrite किए जाने पर, PXE booting enabled वाले adjacent network में man-in-the-middle attack के दौरान, और HTTP booting इस्तेमाल करते समय remote man-in-the-middle attack से exploit किया जा सकता है
अगर कोई unprivileged remote attacker man-in-the-middle position में है और victim machine HTTP booting इस्तेमाल करती है, तो direct access के बिना भी इसे exploit किया जा सकता है
अगर remote attacker ने victim machine पर privileges और code execution हासिल कर लिया है, तो victim HTTP booting न भी इस्तेमाल करे, लेकिन firmware HTTP support करता हो, तब भी वह Secure Boot bypass कर सकता है
उदाहरण के लिए, boot order variable बदलकर attacker-controlled server specify किया जा सकता है, या EFI partition के bootloader को valid shim और GRUB2 image से overwrite करने के बाद
grub.cfgमें HTTP के जरिए नया shim chainload कराया जा सकता हैक्योंकि GRUB2 का device syntax HTTP समेत supported devices specify कर सकता है
साथ ही, अगर कोई unprivileged adjacent attacker man-in-the-middle position में है और victim machine PXE booting इस्तेमाल करती है, तो PXE के shim → PXE के GRUB2 → HTTP के shim की तरह chain बनाकर exploit किया जा सकता है
स्रोत: https://techcommunity.microsoft.com/t5/hardware-dev-center/u...
अगर GPLv3 का anti-Tivoization clause Secure Boot signing key उपलब्ध कराने की मांग कर सकता है, तो क्या MOK signing key भी request करने पर उपलब्ध नहीं करानी चाहिए?
अगर ऐसा है, तो इसका मतलब है कि कोई भी ऐसी key हासिल कर सकता है जिससे वह arbitrary code sign कर सके जो Secure Boot के जरिए indirectly boot होगा; मुझे नहीं पता कि यह Microsoft द्वारा GRUB जैसे GPLv3 projects को सीधे signing key जारी करने के नतीजे से meaningful तौर पर अलग कैसे है
पुराने BIOS machines पर मैंने WBM से GRUB chainload कराया था, लेकिन UEFI machines पर अभी तक नहीं किया, इसलिए नहीं जानता कि कोई blocking point है या नहीं
अगर आप सोच रहे हों, “अविश्वसनीय या compromised server से boot क्यों करना?”, या “अगर server compromised है तो वह सीधे malicious binary भेज देगा, फिर इसका क्या मतलब?”, तो संक्षेप में: shim जिस binary को अंत में boot करता है, उसे MOK से signed होना चाहिए
इसलिए चाहे compromised network के अंदर boot किया जाए, HTTP से boot किया जाए, या compromised server से boot किया जाए, HTTPS हो या न हो, वही security guarantee बनी रहनी चाहिए
Secure Boot downgrade को नहीं रोकता, इसलिए compromised server का downgrade attack में इस्तेमाल हो सकना इस vulnerability से अलग बात है
downgrade attack prevention को वैसे भी अलग से, अधिक मजबूत तरीके से implement करना होगा
हालांकि मुझे नहीं पता कि shim को सीधे HTTP booting support करने की जरूरत क्यों है
इसे MOK-signed second local EFI binary में handle किया जा सकता था, लेकिन शायद इसे implement करने में अपेक्षाकृत आसान feature माना गया होगा
समझ नहीं आता कि यह code body length को दो अलग-अलग आधारों पर क्यों संभालता है
RFC के हिसाब से HTTP/1.1 में Content-Length HTTP request/response body की length के लिए authoritative जानकारी है
उस length से आगे wire पर मौजूद data, परिभाषा के अनुसार किसी दूसरे message का हिस्सा है
उल्टा, अगर Content-Length
rx_message.BodyLengthसे बड़ा है, तो इसका मतलब है कि अभी पूरा message नहीं मिला है, इसलिए और इंतज़ार करना चाहिए या timeout error देना चाहिएकिसी भी स्थिति में, अगर यह guarantee नहीं है कि
rx_message.BodyLengthContent-Length के बराबर है, तो वह गलत value हैअगर इसे ज़्यादा lenient तरीके से handle करना है, तो Content-Length header देखने की कोई वजह नहीं है; बस
rx_message.BodyLengthको buffer size मानकर wire पर मौजूद सारे data को received message के रूप में interpret कर लेंमौजूदा code बेवजह complex है, और इसी तरह bug घुसता है
आसपास का code https://github.com/rhboot/shim/blob/0226b56513b2b8bd5fd281bc... देखें तो loop के अंदर data chunks receive करते हुए हर बार check करता है कि नया data Content-Length से तय buffer capacity से ज़्यादा तो नहीं हो रहा
लेकिन पहले loop के बाहर की पहली read के लिए वह check नहीं था, और वही bug था
हालांकि downloaded size
*buf_size, यानी Content-Length के बराबर है या नहीं, इसकी final check करने वाला code नहीं दिखताअगर यह condition टूटती है तो यह connection के बहुत जल्दी बंद हो जाने का संकेत हो सकता है
यह साफ तौर पर bug है और अच्छा है कि fix हो गया, लेकिन सोचता हूँ कि अविश्वसनीय host से अपनी machine boot कौन करता है
अगर attacker ने malicious header भेजने लायक HTTP service पर control पा लिया है, तो इस overflow से बचना सबसे छोटी समस्या है; certificate भी compromise हो चुका होगा और वह spec-compliant payload में malware डालकर भेज सकता है
bug तो है, लेकिन यह Critical है या नहीं, इस पर यकीन नहीं
वे सचमुच ऐसी security strategy पर भरोसा करते हैं जिसमें संभावित रूप से compromise हो सकने वाली हर चीज Secure Boot से signed नहीं होनी चाहिए
अगर कोई एक भी vulnerable signed चीज मौजूद है, तो उसका इस्तेमाल करके सबके Secure Boot+TPM encrypted disks को decrypt किया जा सकता है
यह approach valid security model क्यों मानी गई, समझना मुश्किल है, और ऐसी vulnerabilities पहले से बहुत सारी हैं
ऊपर से कमरे में मौजूद हाथी यानी Windows को पूरी तरह ignore कर देते हैं
ऐसी सोच का उदाहरण: https://lkml.org/lkml/2018/4/3/767
Linus की चिंताओं के बावजूद, कई distros में Secure Boot से boot करने पर सच में integrity mode चालू हो जाता है
शायद इसकी वजह Microsoft policy और यह स्थिति हो सकती है कि distros को Microsoft UEFI signature पाने के लिए उस thread में बताए गए procedure का पालन करने के लिए मजबूर किया जाता है
नतीजा यह है कि Secure Boot चालू करने पर आमतौर पर distro functionality सीमित हो जाती है, जैसे hibernation इस्तेमाल नहीं कर पाते
जब कोई अहम काम हो, तो HTTP का S इस्तेमाल करना चाहिए
device booting भी इसमें शामिल है, और HTTPS headers हमेशा encrypted रहे हैं
फिर भी bug अच्छी तरह खोजा गया है
गलत header दोनों में भेजा जा सकता है
क्योंकि encryption के लिए सही time और date चाहिए होते हैं
RTC valid हो सकता है, लेकिन time zones ठीक से handle होते हैं या नहीं पता नहीं, और वैसे भी समय गलत हो सकता है
लगता है आपने problem सही से समझी नहीं
Content-lengthअसली body length नहीं, बल्कि Content-encoding के बाद की length हैक्या इन shim builds में httpboot शामिल है?
मेरी जानकारी में shim तो सिर्फ disk पर मौजूद दूसरे EFI binaries चलाने के लिए होता है, और shim की network boot functionality सच में इस्तेमाल होते मैंने शायद नहीं देखी
शायद मुझे ठीक से पता न हो, लेकिन मुझे लगा था कि ज्यादातर HTTP clients सिर्फ specified Content-Length तक ही पढ़ते हैं, और अगर पढ़े गए bytes Content-Length से कम हों तो उसे error मानते हैं
मेरी नज़र में UEFI spec यह साफ-साफ define नहीं करती कि Content-Length header और response body length match न होने पर behavior क्या होना चाहिए
इसलिए कुछ implementations बस
connection:closerequest बनाती हों और Content-Length check न करती हों, इसकी पूरी संभावना हैयह vulnerability MSRC ने report की थी और CVE description में actual exploitation के बारे में कुछ नहीं है
बाद में public हो सकता है, या यह theoretical issue भी हो सकता है
क्या बता सकते हैं कि actual body length से कम पढ़ना खतरनाक क्यों है?
मुझे तो उम्मीद थी कि उल्टा case खतरनाक होगा
लेकिन size manipulable HTTP header से लिया जाता है, और attacker received data से छोटा size specify कर सकता है
इस case में code allocation के लिए header value इस्तेमाल करता है, और receive buffer से copy करते समय protocol metadata का size इस्तेमाल करता है, जिससे out-of-bounds write हो जाती है