
कुछ पुराने Qualcomm चिपसेट के हाइपरवाइज़र फर्मवेयर में सुरक्षा समस्या
CVE-2022-22063 कुछ पुराने Qualcomm चिपसेट के हाइपरवाइज़र फर्मवेयर में एक सुरक्षा समस्या है। एक असुरक्षित हार्डवेयर घटक ("बूट रीमैपर") का दुरुपयोग करके एक संशोधित ऑपरेटिंग सिस्टम से हाइपरवाइज़र तक पूर्ण पढ़ने/लिखने की पहुँच प्राप्त की जा सकती है (विशेषाधिकार वृद्धि)। प्रभावित प्लेटफार्मों पर इस समस्या का शोषण करना तुच्छ है, क्योंकि विशिष्ट फर्मवेयर संस्करण (जैसे पते या चर) के बारे में ज्ञान की आवश्यकता नहीं है।
नोट: हालाँकि Qualcomm ने ग्राहकों को सुधार प्रदान किए हैं (अपडेट जारी करने के लिए पर्याप्त समय के साथ) लेकिन कई प्रभावित उपकरण पहले से ही काफी पुराने हैं और विक्रेता से सुधार प्राप्त नहीं कर सकते हैं। इस समस्या का शोषण केवल एक संशोधित या समझौता किए गए ऑपरेटिंग सिस्टम (किसी अन्य सुरक्षा समस्या का उपयोग करके) से किया जा सकता है। ऑपरेटिंग सिस्टम को अद्यतित और सुरक्षित रखना पर्याप्त हो सकता है भले ही फर्मवेयर कमजोर हो।
CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:Hयह मुद्दा [Qualcomm के दिसंबर 2022 सुरक्षा बुलेटिन] में भी प्रकाशित किया गया था।
यह मुद्दा प्रभावित लक्ष्य पर चल रहे हार्डवेयर और सॉफ्टवेयर के संयोजन पर निर्भर करता है:
hyp विभाजन में एक ELF इमेज)।APCS_BOOT_START_ADDR_NSEC नामक हार्डवेयर रजिस्टर का उपयोग करके कॉन्फ़िगरेबल), जो हाइपरवाइज़र द्वारा संरक्षित नहीं है और इसलिए कम विशेषाधिकार प्राप्त ऑपरेटिंग सिस्टम कर्नेल (जैसे Linux) द्वारा सुलभ है।कई और चिपसेट हैं जिनमें संभवतः प्रभावित हार्डवेयर है (उदा. MSM8909 और MSM8953), लेकिन उनके पास एक अलग हाइपरवाइज़र फर्मवेयर नहीं है जिससे समझौता किया जा सके।
विशेषाधिकार वृद्धि: पहले से समझौता किए गए ऑपरेटिंग सिस्टम कर्नेल (जैसे Linux) को देखते हुए, यह मुद्दा हाइपरवाइज़र स्तर तक आसानी से विशेषाधिकार बढ़ाने की अनुमति देता है (ARM पर EL1 -> EL2)। हाइपरवाइज़र द्वारा प्रबंधित सभी मेमोरी को पढ़ा या लिखा जा सकता है। यह हाइपरवाइज़र द्वारा प्रबंधित विभिन्न सुरक्षा डोमेन या वर्चुअल मशीनों (यदि कोई हों, कॉन्फ़िगरेशन पर निर्भर) के अलगाव को तोड़ता है। (यह भी देखें: [Qualcomm Snapdragon प्लेटफार्मों पर पहुँच नियंत्रण का परिचय])
सुरक्षित बूट: उत्पादन में उपलब्ध अधिकांश Qualcomm डिवाइस फर्मवेयर के अनधिकृत संशोधन को रोकने के लिए सुरक्षित बूट का उपयोग करते हैं। फर्मवेयर क्रिप्टोग्राफ़िक रूप से हस्ताक्षरित होता है और बूट श्रृंखला द्वारा सत्यापित किया जाता है। यह मुद्दा एक संशोधित ऑपरेटिंग सिस्टम से रनटाइम पर लोड किए गए हाइपरवाइज़र फर्मवेयर को संशोधित करने या पूरी तरह से बदलने की अनुमति देता है (या तो आधिकारिक रूप से समर्थित "बूटलोडर अनलॉकिंग" या किसी अन्य एक्सप्लॉइट के माध्यम से)। (यह भी देखें: [Qualcomm सुरक्षित बूट और छवि प्रमाणीकरण तकनीकी अवलोकन (v1.0)] और (v2.0))
नोट: यह मुद्दा मूल रूप से Qualcomm Snapdragon 410 (MSM8916) प्लेटफॉर्म पर पाया गया था। निम्नलिखित में से कुछ स्पष्टीकरण MSM8916 के लिए विशिष्ट हो सकते हैं, उदा.:
हालाँकि, सामान्य अवधारणा सभी प्रभावित प्लेटफार्मों पर समान रूप से लागू होती है।
ARMv8-A 64-बिट आर्किटेक्चर 4 विशेषाधिकार स्तरों ("अपवाद स्तर", EL) को परिभाषित करता है। अलग-अलग स्तर होते हैं जो आमतौर पर एप्लिकेशन, ऑपरेटिंग सिस्टम कर्नेल और हाइपरवाइज़र के लिए उपयोग किए जाते हैं:
CPU अपवादों के दौरान स्तरों के बीच स्विच करता है, उदा. आने वाले इंटरप्ट के कारण। कुछ स्तरों के बीच विशेष निर्देशों का उपयोग करके स्विच करना भी संभव है, जैसे हाइपरवाइज़र कॉल (hvc)।
(यह भी देखें: AArch64 अपवाद मॉडल)
हाइपरवाइज़र एक या कई वर्चुअल मशीनों को अलग-अलग ऑपरेटिंग सिस्टम कर्नेल के साथ होस्ट कर सकता है। प्रत्येक वर्चुअल मशीन को स्टेज 2 ट्रांसलेशन का उपयोग करके मेमोरी का अपना दृश्य दिया जा सकता है। वर्चुअल मशीन से सभी मेमोरी एक्सेस दो ट्रांसलेशन चरणों से गुज़रते हैं: पहला (वर्चुअल) ऑपरेटिंग सिस्टम द्वारा प्रबंधित किया जाता है, जबकि दूसरा चरण हाइपरवाइज़र द्वारा प्रबंधित किया जाता है। हाइपरवाइज़र या अन्य वर्चुअल मशीनों द्वारा उपयोग की जाने वाली मेमोरी को ट्रांसलेशन तालिकाओं से हटाकर छिपाया जा सकता है। (यह भी देखें: [AArch64 वर्चुअलाइज़ेशन], AArch64 मेमोरी प्रबंधन)
Qualcomm का हाइपरवाइज़र फर्मवेयर EL2 में चलता है और EL1 (आमतौर पर Linux) में चलने वाले मुख्य ऑपरेटिंग सिस्टम कर्नेल से हाइपरवाइज़र मेमोरी तक पहुँच को अस्वीकार करने के लिए स्टेज 2 ट्रांसलेशन का उपयोग करता है। ध्यान दें कि इस सेटअप में स्टेज 2 ट्रांसलेशन का उपयोग मुख्य रूप से मेमोरी सुरक्षा के लिए किया जाता है, बिना पता अनुवाद के। मुख्य ऑपरेटिंग सिस्टम को मेमोरी-मैप्ड इनपुट/आउटपुट (MMIO) स्पेस में अधिकांश हार्डवेयर घटकों तक सीधी पहुँच मिलती है, उदा. SD कंट्रोलर या कैमरा सबसिस्टम। हाइपरवाइज़र/EL2 (hyp) और सिक्योर मॉनिटर/EL3 (tz का हिस्सा) से संबंधित मेमोरी तक पहुँच प्रतिबंधित है:
बूट रीमैपर वर्चुअलाइज़ेशन से संबंधित नहीं है: इसकी आवश्यकता CPU कोर के प्रारंभिक बूट के दौरान होती है। इस हार्डवेयर प्लेटफॉर्म पर CPU कोर हमेशा एड्रेस 0x0 पर निष्पादन शुरू करते हैं। बूट रीमैपर CPU के चारों ओर बना एक अतिरिक्त हार्डवेयर घटक है जो पहले 64 या 128 KiB (0x00000 - 0x20000) को एक कॉन्फ़िगरेबल मेमोरी क्षेत्र में रीमैप करता है।
डिफ़ॉल्ट रूप से बूट रीमैपर बूट ROM (पहला कोड जो डिवाइस शुरू होने पर चलता है) को इंगित करता है। बाद में मैपिंग बदल दी जाती है ताकि अन्य CPU कोर तुरंत EL3 फर्मवेयर (tz का हिस्सा) में निष्पादन शुरू करें जो RAM में लोड किया गया था:
ध्यान दें कि CPU द्वारा एक्सेस किया गया पता (tz के अंतर्गत) दो अलग-अलग भौतिक पतों का उपयोग करके सुलभ है: RAM में वास्तविक पता (0x8650xxxx) और बूट रीमैपर का उपयोग करके रीमैप किया गया पता (0x0000xxxx)।
वास्तव में बूट रीमैपर के दो अलग-अलग उदाहरण हैं:
APCS_BOOT_START_ADDR_SEC (= 0x0b010004) का उपयोग करके कॉन्फ़िगरेबल है लेकिन केवल सुरक्षित अवस्था में।APCS_BOOT_START_ADDR_NSEC (= 0x0b010008) का उपयोग करके कॉन्फ़िगरेबल है, यहाँ तक कि गैर-सुरक्षित अवस्था में भी।दोनों बूट रीमैपर उदाहरणों को एक मेमोरी रजिस्टर का उपयोग करके कॉन्फ़िगर किया जा सकता है जिसमें रीमैप किए गए क्षेत्र का आधार पता और दो कॉन्फ़िगरेशन बिट होते हैं: रीमैपिंग सक्षम करने के लिए REMAP_EN और केवल 64 KiB के बजाय पहले 128 KiB को रीमैप करने के लिए BOOT_128KB_EN।
(यह भी देखें: [Qualcomm Snapdragon 410E तकनीकी संदर्भ मैनुअल rev. D], पृष्ठ 85 और 116)
पिछले दो अनुभागों के ज्ञान का उपयोग करके मूल विचार सरल है: हाइपरवाइज़र की मेमोरी सुरक्षा (स्टेज 2 ट्रांसलेशन) को बायपास करने के लिए बूट रीमैपर का उपयोग करें।
बूट रीमैपर न केवल CPU स्टार्ट-अप के दौरान काम करता है। इसका उपयोग किसी भी समय किया जा सकता है और यह रीमैप किए गए क्षेत्र तक पूर्ण पढ़ने/लिखने/निष्पादित करने की पहुँच प्रदान करता है। इसके अलावा, Qualcomm का हाइपरवाइज़र प्रभावित उपकरणों पर बूट रीमैपर के गैर-सुरक्षित उदाहरण को कॉन्फ़िगर और एक्सेस करने से ऑपरेटिंग सिस्टम को रोकता नहीं दिखता (यह स्टेज 2 ट्रांसलेशन का उपयोग करके सुरक्षित नहीं है)। इसलिए, इस मुद्दे का शोषण करना आसान है:
hyp जो एड्रेस 0x8640xxxx पर शुरू होता है), उसके बादरीमैप किए गए क्षेत्र को गतिशील रूप से (ब्लॉक दर ब्लॉक) स्थानांतरित किया जा सकता है ताकि बूट रीमैपर के माध्यम से उपलब्ध 64/128 KiB से बड़े मेमोरी क्षेत्रों तक पहुँचा जा सके। इसका उपयोग हाइपरवाइज़र मेमोरी सुरक्षा को पूरी तरह से अक्षम करने के लिए भी किया जा सकता है (देखें प्रूफ ऑफ कॉन्सेप्ट)।
नोट: वही एक्सप्लॉइट सिक्योर वर्ल्ड फर्मवेयर (tz) के लिए काम नहीं करता है। जबकि बूट रीमैपर स्टेज 2 ट्रांसलेशन को बायपास करने की अनुमति देता है, DRAM में tz मेमोरी क्षेत्र एक अतिरिक्त हार्डवेयर घटक (CPU के बाहर) द्वारा संरक्षित प्रतीत होता है जो बूट रीमैपर से गुज़रने के बाद एक्सेस को अवरुद्ध करता है:
tz मेमोरी क्षेत्र संभवतः केवल सुरक्षित अवस्था में ही सुलभ है। एक्सप्लॉइट केवल हाइपरवाइज़र की मेमोरी सुरक्षा को बायपास करने की अनुमति देता है, हार्डवेयर के अन्य सुरक्षा तंत्र अभी भी मौजूद हैं।
बूट रीमैपर का उपयोग फर्मवेयर संस्करण के ज्ञान के बिना, रनटाइम पर मूल हाइपरवाइज़र फर्मवेयर को पूरी तरह से अक्षम और बदलने के लिए किया जा सकता है। विशेष रूप से, उन चरों और फ़ंक्शनों के मेमोरी पते प्राप्त करने के लिए रिवर्स इंजीनियरिंग का उपयोग करना आवश्यक नहीं है जिन्हें संशोधित किया जा सकता है। हाइपरवाइज़र फर्मवेयर के मोटे-मोटे मेमोरी क्षेत्र को जानना पर्याप्त है, उदा. ओपन-सोर्स Linux कोड में मेमोरी आरक्षण से या हाइपरवाइज़र फर्मवेयर बाइनरी (आंतरिक स्टोरेज पर hyp विभाजन में उपलब्ध) के ELF हेडर पढ़कर।
सामान्य विचार है:
hvc) करें।इसे लागू करने वाला कोड लंबा नहीं है, लेकिन इसमें कुछ निम्न-स्तरीय AArch64 असेंबली और CPU कैश के साथ सावधानीपूर्वक इंटरैक्शन शामिल है। हालाँकि, मुख्य प्रश्न अभी भी खुला है: कोड को किसी विशेष हाइपरवाइज़र फर्मवेयर संस्करण के लिए विशिष्ट बनाए बिना, शेल कोड वास्तव में कहाँ लिखा जाना चाहिए?
हाइपरवाइज़र कॉल (या सामान्यतः किसी भी अपवाद) के दौरान CPU निष्पादन एक विशेष मेमोरी पते पर मजबूर होता है: अपवाद वेक्टर। अपवाद वेक्टर एक बड़ी वेक्टर तालिका का हिस्सा होते हैं जिसमें विभिन्न प्रकार के अपवादों को संभालने वाला कोड होता है, जो वर्तमान या निचले अपवाद स्तरों से आते हैं:
प्रत्येक बॉक्स 32 असेंबली निर्देशों के लिए स्थान के साथ एक अपवाद वेक्टर का प्रतिनिधित्व करता है। यह पर्याप्त स्थान नहीं है इसलिए उनमें आमतौर पर शाखा निर्देश होते हैं जो अतिरिक्त कोड के लिए अधिक स्थान के साथ कहीं और कूद जाते हैं।
ऑफसेट वेक्टर बेस एड्रेस रजिस्टर (VBAR) के सापेक्ष होते हैं जो प्रत्येक अपवाद स्तर के लिए वेक्टर तालिका का आधार पता परिभाषित करता है। हाइपरवाइज़र VBAR_EL2 CPU रजिस्टर में आधार पता लिखता है।
हाइपरवाइज़र कॉल एक सिंक्रोनस अपवाद है जो निचले अपवाद स्तर (EL1 में चलने वाला ऑपरेटिंग सिस्टम कर्नेल से EL2 में हाइपरवाइज़र तक) से बनाया गया है। यदि ऑपरेटिंग सिस्टम कर्नेल 32-बिट मोड में चल रहा है, तो CPU VBAR_EL2+0x600 पर कूद जाएगा, या 64-बिट मोड में VBAR_EL2+0x400 पर। बूट रीमैपर का उपयोग करके इस पते पर कस्टम कोड लिखने और हाइपरवाइज़र कॉल करने के बाद CPU शेल कोड को निष्पादित करना शुरू कर देगा।
दुर्भाग्य से VBAR_EL2 EL1 में चलने वाले ऑपरेटिंग सिस्टम कर्नेल द्वारा पढ़ने योग्य नहीं है। यह केवल हाइपरवाइज़र (EL2) या उच्च स्तर से ही पढ़ने योग्य है। फिर भी, यह ज्ञान ब्रूट फोर्स का उपयोग करके प्रवेश पते का अनुमान लगाना बहुत आसान बनाता है: वेक्टर तालिका का आधार पता उसके आकार (0x800 = 2 KiB) के (गुणक में) संरेखित होना चाहिए। इसका मतलब है कि 128 KiB के क्षेत्र के अंदर केवल 64 संभावित स्थान हैं, या 1 MiB के क्षेत्र के अंदर 512:
लाल बॉक्स उन सभी संभावित स्थानों को दिखाते हैं जहाँ CPU हाइपरवाइज़र कॉल के दौरान कूद सकता है। इन सभी में शेल कोड लिखना एक विशेष फर्मवेयर संस्करण से स्वतंत्र दृष्टिकोण रखने के लिए पर्याप्त है (जिसमें वास्तव में एक विशेष पते पर वेक्टर तालिका होगी)।
इसे और बेहतर बनाया जा सकता है: बूट रीमैपर पढ़ने और लिखने दोनों की पहुँच की अनुमति देता है इसलिए मेमोरी स्थानों से पढ़े गए मौजूदा कोड/डेटा के आधार पर कुछ ह्यूरिस्टिक्स जोड़ना संभव होगा। इसमें मान्य AArch64 (A64) निर्देश और संभवतः कुछ दोहराए गए भरण बाइट जैसे NOP या शाखा निर्देश शामिल होने चाहिए। (प्रति अपवाद वेक्टर 32 निर्देशों का स्थान अक्सर केवल आंशिक रूप से उपयोग किया जाता है क्योंकि अधिक स्थान वाले उचित फ़ंक्शन पर शाखा लगाना आसान होता है।)
इस रिपॉजिटरी में शामिल प्रूफ ऑफ कॉन्सेप्ट कोड Snapdragon 410 (MSM8916/APQ8016) प्लेटफॉर्म के लिए Qualcomm के ओपन-सोर्स लिटिल कर्नेल (LK) बूटलोडर का एक संशोधन है, जो मूल रूप से DragonBoard 410c डेवलपमेंट बोर्ड के साथ परीक्षण के लिए था। यह सब सरलता के लिए चुना गया था, इस मुद्दे का शोषण अन्य ऑपरेटिंग सिस्टम (जैसे Linux), अन्य प्रभावित प्लेटफार्मों और यहाँ तक कि सुरक्षित बूट वाले उपकरणों से भी किया जा सकता है - जब तक ऑपरेटिंग सिस्टम कर्नेल के भीतर कस्टम कोड निष्पादित करने का कोई तरीका है।
कोड ऊपर वर्णित दृष्टिकोण को लागू करता है ताकि चल रहे हाइपरवाइज़र को पूरी तरह से अक्षम किया जा सके और फिर इसे एक अलग संस्करण से बदल दिया जाए। नया "हाइपरवाइज़र" किसी भी वर्चुअल मशीन का समर्थन नहीं करता है, लेकिन एक सरल हाइपरवाइज़र कॉल का उपयोग करके जीवन, ब्रह्मांड, और हर चीज़ के अंतिम प्रश्न का उत्तर देने में सक्षम है:``` $ fastboot oem CVE-2022-22063 < waiting for any device > (bootloader) Hypervisor, what is the Answer to The Ultimate Question of (bootloader) Life, the Universe and Everything? (bootloader) Old hypervisor returned answer: -2 (bootloader) Old non-secure boot remapper base address: 0x100000 (bootloader) Setting boot remapper to hypervisor memory (0x86400000) (bootloader) Using boot remapper to copy shell code to hypervisor memory (bootloader) Copying to all possible vector tables (starting at 0x600) (bootloader) Calling shell code to disable running hypervisor (bootloader) Found old EL2 vector base address at 0x86404000 (bootloader) Copying new code directly to hypervisor memory (0x86400000) (bootloader) Hypervisor, what is the Answer to The Ultimate Question of (bootloader) Life, the Universe and Everything? (bootloader) New hypervisor returned answer: 42 OKAY [ 0.015s] Finished. Total time: 0.015s
### परीक्षण
प्रूफ ऑफ कॉन्सेप्ट कोड को निम्नानुसार बनाया और परीक्षण किया जा सकता है:```shell
$ git clone https://git.codelinaro.org/clo/la/kernel/lk.git -b caf_migration/LA.BR.1.2.9.1_rb1.5
$ cp CVE-2022-22063.c lk/platform/msm8916/
$ git apply LK.diff
# Build LK for msm8916 and flash it to device
$ fastboot oem CVE-2022-22063
...
हालांकि, यह कॉन्फ़िगरेशन केवल DragonBoard 410c डेवलपमेंट बोर्ड और अन्य उन उपकरणों के लिए उपयुक्त है जिनमें सुरक्षित बूट नहीं है और जहां प्राथमिक बूटलोडर को आसानी से (और सुरक्षित रूप से) बदला जा सकता है। इस रिपॉजिटरी में कोड मुख्य रूप से संदर्भ के लिए प्रदान किया गया है, न कि आसान उपयोग/परीक्षण के लिए।
भविष्य में कोड को lk2nd के एक नए संस्करण में एकीकृत करने की योजना है, जिसका विभिन्न उपकरणों पर प्राथमिक बूटलोडर को बदले बिना अधिक आसानी से परीक्षण किया जा सकता है।
क्वालकॉम के अनुसार, यह समस्या स्टेज 2 ट्रांसलेशन का उपयोग करके बूट रीमैपर क्षेत्र तक पहुंच को अवरुद्ध करके ठीक की गई थी। बूट रीमैपर कॉन्फ़िगरेशन (APCS_BOOT_START_ADDR_NSEC रजिस्टर) अभी भी सुलभ है, लेकिन अब दोनों मेमोरी क्षेत्र अवरुद्ध हैं:
एक अन्य संभावित फिक्स हाइपरवाइज़र में APCS_BOOT_START_ADDR_NSEC रजिस्टर की सुरक्षा करना होगा। इस स्थिति में रीमैप्ड क्षेत्र सुलभ रह सकता है, क्योंकि ऑपरेटिंग सिस्टम के पास बूट रीमैपर को अन्य मेमोरी क्षेत्रों में पुन: कॉन्फ़िगर करने का कोई तरीका नहीं होगा।
क्वालकॉम के अनुसार, यह समस्या विशेष रूप से संभालना कठिन था क्योंकि उनके सामान्य स्वचालन उपकरणों का उपयोग नहीं किया जा सकता था। उन्हें अधिकांश समस्याएं सॉफ्टवेयर से संबंधित प्राप्त होती हैं, जहां स्रोत कोड की जांच करके प्रभावित उपकरणों की पहचान की जा सकती है। इस समस्या के लिए मैन्युअल रूप से हार्डवेयर और सॉफ्टवेयर दोनों की जांच करना आवश्यक था (यदि प्लेटफॉर्म में समस्याग्रस्त रजिस्टर है और यदि हाइपरवाइज़र असुरक्षित है)। दुर्भाग्य से, स्वचालन का उपयोग न करने का अर्थ यह भी था कि समस्या स्वचालित रूप से सुरक्षा बुलेटिन में शेड्यूल नहीं हुई। प्रतिबंध का दूसरा विस्तार ग्राहकों को सुरक्षा समस्या से अवगत कराने और उन्हें अपने उपकरणों को पैच करने का समय देने के लिए अनुरोध किया गया था। वे भविष्य की रिपोर्टों के लिए ऐसी समस्याओं से बचने के लिए प्रक्रिया में सुधार पर काम कर रहे हैं।
CVE-2022-22063 रिपोर्ट और आरेख © 2022 स्टीफन गेरहोल्ड द्वारा क्रिएटिव कॉमन्स एट्रिब्यूशन-शेयरअलाइक 4.0 इंटरनेशनल (CC BY-SA 4.0) के तहत लाइसेंस प्राप्त है।
प्रूफ ऑफ कॉन्सेप्ट कोड (CVE-2022-22063.c) MIT लाइसेंस के तहत प्रदान किया गया है।