
CVE-2019-5700
दुर्भाग्यवश, मेरे पास इस कमजोरी का कोई ट्रेंडी और चतुर नाम नहीं है। यह बग शोषण करने में काफी सरल है। मैंने वास्तव में काफी समय तक इसे रोके रखा जब तक मुझे एहसास नहीं हुआ कि यह मेरे शुरुआती अनुमान से अधिक उपकरणों को प्रभावित कर सकता है।
यह बग Nvidia Tegra t114-t210 SoCs को प्रभावित करता है जो Android बूट इमेज बूट करते हैं, हालांकि एक महत्वपूर्ण अंतर करना है:
t114 आधारित उपकरण अधिक गंभीर रूप से प्रभावित होते हैं क्योंकि उनका यूनिफाइड बूटलोडर TOS (TLK - Nvidia का सुरक्षित मॉनिटर) भी लोड करता है, जिसका अर्थ है कि बूटलोडर पहले से ही सुरक्षित संदर्भ में चल रहा है...
t124+ उपकरणों पर, Nvidia अब nvtboot का उपयोग एक प्रारंभिक चरण के बूटलोडर के रूप में करता है जो कमजोर बूटलोडर के निष्पादित होने से पहले TOS लोड करता है, जो कर्नेल को लोड और निष्पादित करता है। इसका मतलब है कि हम गैर-सुरक्षित संदर्भ में चल रहे हैं।
आइए Android बूट इमेज हैडर (v1 - Android 9 से पहले) पर एक नज़र डालते हैं:
struct boot_img_hdr
{
uint8_t magic[BOOT_MAGIC_SIZE];
uint32_t kernel_size; /* size in bytes */
uint32_t kernel_addr; /* physical load addr */
uint32_t ramdisk_size; /* size in bytes */
uint32_t ramdisk_addr; /* physical load addr */
uint32_t second_size; /* size in bytes */
uint32_t second_addr; /* physical load addr */
uint32_t tags_addr; /* physical addr for kernel tags */
uint32_t page_size; /* flash page size we assume */
uint32_t unused;
uint32_t os_version;
uint8_t name[BOOT_NAME_SIZE]; /* asciiz product name */
uint8_t cmdline[BOOT_ARGS_SIZE];
uint32_t id[8]; /* timestamp / checksum / sha1 / etc */
uint8_t extra_cmdline[BOOT_EXTRA_ARGS_SIZE];
};
हम कुछ परिचित इमेज के लिए फ़ील्ड देखते हैं: kernel, ramdisk:
uint32_t kernel_size; /* size in bytes */
uint32_t kernel_addr; /* physical load addr */
uint32_t ramdisk_size; /* size in bytes */
uint32_t ramdisk_addr; /* physical load addr */
और कभी-कभी tags (जो अक्सर डिवाइस ट्री या ATAGS के लिए उपयोग होता है)
uint32_t tags_addr; /* physical addr for kernel tags */
uint32_t page_size; /* flash page size we assume */
'second' फ़ील्ड के बारे में क्या?
uint32_t second_size; /* size in bytes */
uint32_t second_addr; /* physical load addr */
जबकि मैंने व्यक्तिगत रूप से कभी किसी प्रोडक्शन डिवाइस पर इसका उपयोग नहीं देखा, मेरी समझ में 'second' इमेज का उपयोग दूसरे चरण के बूटलोडर या एक अतिरिक्त इमेज के लिए किया जा सकता है जिसे लोड करने की आवश्यकता है। मेरे शोध के अनुभव में, अधिकांश अन्य OEMs के बूटलोडर इस फ़ील्ड को अनदेखा कर देंगे - क्योंकि इसका उपयोग नहीं किया जाता है - या वे आकार और पते पर सैनिटी जांच लागू करेंगे।
Nvidia का बूटलोडर kernel, ramdisk, और dtb पर सैनिटी जांच लागू करता है - इन सभी के पास हार्डकोडेड लोडिंग पते होते हैं जिसका अर्थ है कि हैडर में लोडिंग पतों को अनदेखा किया जाता है। हालांकि, ऐसा लगता है कि Nvidia शायद इस अधिकतर भूली हुई इमेज के बारे में भूल गया... इसे पते या आकार पर कोई सैनिटी जांच के बिना मनमाने ढंग से लोड करते हुए। यह सही है - आप किसी भी आकार की किसी भी इमेज को किसी भी सुलभ मेमोरी पते पर (t114 पर सब कुछ, t124+ पर गैर-सुरक्षित मेमोरी) मनमाने ढंग से लोड कर सकते हैं।
इसका मतलब है कि हम अपनी आवश्यकता के अनुसार मेमोरी में बूटलोडर को स्वतंत्र रूप से पैच कर सकते हैं। चाहे हम हस्ताक्षर सत्यापन को छोड़ना चाहें (जो सभी इमेज को लोड करने के तुरंत बाद आता है), t114 पर TOS लोडिंग को हाईजैक करके सुरक्षित संदर्भ कोड निष्पादन प्राप्त करना चाहें, या संवेदनशील जानकारी डंप करने के लिए कुछ शेलकोड लोड करना चाहें।
शोषण उतना ही सरल है जितना कि द्वितीयक इमेज के रूप में आपके पेलोड/शेलकोड के साथ एक बूट इमेज बनाना और addr/len फ़ील्ड को आपके पेलोड के आकार और जहाँ आप इसे रखना चाहते हैं, उसके अनुसार उचित रूप से सेट करना। इमेज 4-बाइट जितनी छोटी हो सकती है।
t124+ उपकरणों पर हमारे पास सुरक्षित संदर्भ नहीं है, क्योंकि nvtboot ने बूटिंग के एक पहले चरण में TOS लोड कर लिया है जो फिर बाद के चरण के बूटलोडर (EBT) को निष्पादन सौंपता है, लेकिन हम अभी भी मेमोरी में इस बाद के चरण के बूटलोडर पर स्वतंत्र रूप से लिख सकते हैं। कमजोर बूटलोडर वह है जो कर्नेल लोड करता है, इसलिए यदि आप मनमाना अहस्ताक्षरित कोड निष्पादित करना चाहते हैं तो यह अभी भी काफी मूल्यवान है।
न केवल लोडिंग पता सत्यापित नहीं होता, बल्कि आकार भी नहीं होता, जो CVE-2019-5699 का द्वार खोलता है क्योंकि हम एक दुर्भावनापूर्ण secondary_size फ़ील्ड बनाकर विभिन्न चर/पॉइंटर्स को ओवरफ्लो कर सकते हैं। हालांकि मैं इसका श्रेय नहीं ले सकता क्योंकि मुझे इसका एहसास प्रारंभिक सुरक्षा बुलेटिन प्रकाशित होने के बाद ही हुआ। ऐसा भी लगता है कि यह बहुत अधिक काम है...
t114:
IROM->BCT->EBT->TOS->KERNEL
t124+ (नए 64-बिट SoC के लिए थोड़ा भिन्न हो सकता है):
IROM->BCT->NVTBOOT->TOS->EBT->KERNEL
यह मुद्दा प्रारंभ में 29 जुलाई, 2019 को Nvidia के PSIRT (उत्पाद सुरक्षा घटना प्रतिक्रिया टीम) को सूचित किया गया था। उन्होंने विनम्रतापूर्वक अनुरोध किया कि जब तक सभी प्रासंगिक ग्राहकों को सूचित नहीं किया जाता और फिक्स जारी नहीं किए जाते, तब तक मैं खुलासा स्थगित कर दूं - जिसका मैंने खुशी-खुशी अनुपालन किया। उन्होंने पूरी प्रक्रिया के दौरान संचार बनाए रखा और उनके साथ काम करना सुखद था। आज (5 दिसंबर, 2019) Nvidia ने अंततः प्रभावित कोड में फिक्स जारी करना समाप्त कर दिया है और इस मुद्दे को दर्शाते हुए दो अलग-अलग सुरक्षा बुलेटिन पोस्ट किए हैं, साथ ही मुझे खुलासे के लिए हरी झंडी दी है।
https://nvidia.custhelp.com/app/answers/detail/a_id/4875
https://nvidia.custhelp.com/app/answers/detail/a_id/4910
balika011
beaups
npjohnson
djrbliss/Dan Rosenberg ने मुझे यह सुनिश्चित करने के लिए प्रेरित किया कि बूटलोडर बूट इमेज हैडर को कैसे पार्स करते हैं, इसकी बारीकी से जांच करूं।