
CVE-2019-11932 के लिए तकनीकी लेख और शोषण कोड, जो Android के लिए WhatsApp में एक डबल-फ्री भेद्यता है, जो एक निर्मित GIF फ़ाइल के माध्यम से दूरस्थ कोड निष्पादन की ओर ले जाती है।
मैं एक डबल-फ्री भेद्यता के बारे में साझा करने जा रहा हूँ जो मुझे Android के लिए WhatsApp में मिली, और मैंने इसे RCE में कैसे बदला। मैंने इसकी सूचना Facebook को दी। Facebook ने इसे स्वीकार किया और WhatsApp संस्करण 2.19.244 में आधिकारिक रूप से इसे पैच किया। Facebook ने इस मुद्दे के लिए CVE-2019-11932 आरक्षित करने में मदद की।
WhatsApp उपयोगकर्ताओं, कृपया इस बग से सुरक्षित रहने के लिए नवीनतम WhatsApp संस्करण (2.19.244 या उससे ऊपर) में अपडेट करें।
चरण इस प्रकार हैं:
उनमें से एक WhatsApp के माध्यम से दस्तावेज़ के रूप में हो सकता है (अर्थात Paper Clip बटन दबाकर और दूषित GIF भेजने के लिए Document चुनें) यदि हमलावर उपयोगकर्ता की संपर्क सूची में है (अर्थात एक मित्र), तो दूषित GIF बिना किसी उपयोगकर्ता इंटरैक्शन के स्वचालित रूप से डाउनलोड हो जाती है।
ध्यान दें कि उपयोगकर्ता को कुछ भी भेजने की आवश्यकता नहीं है क्योंकि केवल WhatsApp Gallery खोलने से बग ट्रिगर हो जाएगा। WhatsApp Gallery दबाने के बाद कोई अतिरिक्त स्पर्श आवश्यक नहीं है।
जब कोई WhatsApp उपयोगकर्ता मीडिया फ़ाइल भेजने के लिए WhatsApp में Gallery दृश्य खोलता है, तो WhatsApp GIF फ़ाइल का पूर्वावलोकन उत्पन्न करने के लिए libpl_droidsonroids_gif.so नामक एक नेटिव लाइब्रेरी के साथ इसे पार्स करता है। libpl_droidsonroids_gif.so एक ओपन-सोर्स लाइब्रेरी है जिसका स्रोत कोड https://github.com/koral–/android-gif-drawable/tree/dev/android-gif-drawable/src/main/c पर उपलब्ध है।
एक GIF फ़ाइल में कई एन्कोडेड फ्रेम होते हैं। डिकोड किए गए फ्रेमों को संग्रहीत करने के लिए, rasterBits नामक एक बफर का उपयोग किया जाता है। यदि सभी फ्रेमों का आकार समान है, तो rasterBits का पुन: आवंटन किए बिना डिकोड किए गए फ्रेमों को संग्रहीत करने के लिए पुन: उपयोग किया जाता है। हालांकि, यदि नीचे दी गई तीन शर्तों में से एक पूरी होती है, तो rasterBits का पुन: आवंटन किया जाएगा:
पुन: आवंटन free और malloc का संयोजन है। यदि पुन: आवंटन का आकार 0 है, तो यह केवल एक free है। मान लीजिए हमारे पास एक GIF फ़ाइल है जिसमें 3 फ्रेम हैं जिनके आकार 100, 0 और 0 हैं।
इसके परिणामस्वरूप एक डबल-फ्री भेद्यता होती है। ट्रिगरिंग स्थान decoding.c में पाया जा सकता है:
int_fast32_t widthOverflow = gifFilePtr->Image.Width - info->originalWidth; int_fast32_t heightOverflow = gifFilePtr->Image.Height - info->originalHeight; const uint_fast32_t newRasterSize = gifFilePtr->Image.Width * gifFilePtr->Image.Height; if (newRasterSize > info->rasterSize || widthOverflow > 0 || heightOverflow > 0) { void *tmpRasterBits = reallocarray(info->rasterBits, newRasterSize, <<-- double-free here sizeof(GifPixelType)); if (tmpRasterBits == NULL) { gifFilePtr->Error = D_GIF_ERR_NOT_ENOUGH_MEM; break; } info->rasterBits = tmpRasterBits; info->rasterSize = newRasterSize; }
14 मिनट का पढ़ना इस पृष्ठ पर डेमो डबल-फ्री भेद्यता libpl_droidsonroids_gif के decoding.c में DDGifSlurp में PC रजिस्टर को नियंत्रित करना ASLR और W^X से निपटना सब कुछ एक साथ रखना प्रभावित संस्करण हमले के वेक्टर इस ब्लॉग पोस्ट में, मैं एक डबल-फ्री भेद्यता के बारे में साझा करने जा रहा हूँ जो मुझे Android के लिए WhatsApp में मिली, और मैंने इसे RCE में कैसे बदला। मैंने इसकी सूचना Facebook को दी। Facebook ने इसे स्वीकार किया और WhatsApp संस्करण 2.19.244 में आधिकारिक रूप से इसे पैच किया। Facebook ने इस मुद्दे के लिए CVE-2019-11932 आरक्षित करने में मदद की।
WhatsApp उपयोगकर्ताओं, कृपया इस बग से सुरक्षित रहने के लिए नवीनतम WhatsApp संस्करण (2.19.244 या उससे ऊपर) में अपडेट करें।
डेमो https://drive.google.com/file/d/1T-v5XG8yQuiPojeMpOAG6UGr2TYpocIj/view
Google Drive लिंक डाउनलोड करने के लिए यदि उपरोक्त लिंक सुलभ नहीं है https://drive.google.com/open?id=1X9nBlf5oj5ef2UoYGOfusjxAiow8nKEK
चरण इस प्रकार हैं:
0:16 हमलावर किसी भी चैनल के माध्यम से उपयोगकर्ता को GIF फ़ाइल भेजता है उनमें से एक WhatsApp के माध्यम से दस्तावेज़ के रूप में हो सकता है (अर्थात Paper Clip बटन दबाकर और दूषित GIF भेजने के लिए Document चुनें) यदि हमलावर उपयोगकर्ता की संपर्क सूची में है (अर्थात एक मित्र), तो दूषित GIF बिना किसी उपयोगकर्ता इंटरैक्शन के स्वचालित रूप से डाउनलोड हो जाती है। 0:24 उपयोगकर्ता अपने किसी WhatsApp मित्र को एक मीडिया फ़ाइल भेजना चाहता है। इसलिए उपयोगकर्ता Paper clip बटन दबाता है और अपने मित्र को भेजने के लिए एक मीडिया फ़ाइल चुनने के लिए WhatsApp Gallery खोलता है। ध्यान दें कि उपयोगकर्ता को कुछ भी भेजने की आवश्यकता नहीं है क्योंकि केवल WhatsApp Gallery खोलने से बग ट्रिगर हो जाएगा। WhatsApp Gallery दबाने के बाद कोई अतिरिक्त स्पर्श आवश्यक नहीं है। 0:30 चूंकि WhatsApp प्रत्येक मीडिया का पूर्वावलोकन दिखाता है (प्राप्त GIF फ़ाइल सहित), यह डबल-फ्री बग और हमारे RCE शोषण को ट्रिगर करेगा। libpl_droidsonroids_gif के decoding.c में DDGifSlurp में डबल-फ्री भेद्यता जब कोई WhatsApp उपयोगकर्ता मीडिया फ़ाइल भेजने के लिए WhatsApp में Gallery दृश्य खोलता है, तो WhatsApp GIF फ़ाइल का पूर्वावलोकन उत्पन्न करने के लिए libpl_droidsonroids_gif.so नामक एक नेटिव लाइब्रेरी के साथ इसे पार्स करता है। libpl_droidsonroids_gif.so एक ओपन-सोर्स लाइब्रेरी है जिसका स्रोत कोड https://github.com/koral–/android-gif-drawable/tree/dev/android-gif-drawable/src/main/c पर उपलब्ध है।
एक GIF फ़ाइल में कई एन्कोडेड फ्रेम होते हैं। डिकोड किए गए फ्रेमों को संग्रहीत करने के लिए, rasterBits नामक एक बफर का उपयोग किया जाता है। यदि सभी फ्रेमों का आकार समान है, तो rasterBits का पुन: आवंटन किए बिना डिकोड किए गए फ्रेमों को संग्रहीत करने के लिए पुन: उपयोग किया जाता है। हालांकि, यदि नीचे दी गई तीन शर्तों में से एक पूरी होती है, तो rasterBits का पुन: आवंटन किया जाएगा:
width * height > originalWidth * originalHeight width - originalWidth > 0 height - originalHeight > 0 पुन: आवंटन free और malloc का संयोजन है। यदि पुन: आवंटन का आकार 0 है, तो यह केवल एक free है। मान लीजिए हमारे पास एक GIF फ़ाइल है जिसमें 3 फ्रेम हैं जिनके आकार 100, 0 और 0 हैं।
पहले पुन: आवंटन के बाद, हमारे पास आकार 100 का info->rasterBits बफर है। 0 के दूसरे पुन: आवंटन में, info->rasterBits बफर freed हो जाता है। 0 के तीसरे पुन: आवंटन में, info->rasterBits फिर से freed हो जाता है। इसके परिणामस्वरूप एक डबल-फ्री भेद्यता होती है। ट्रिगरिंग स्थान decoding.c में पाया जा सकता है:
int_fast32_t widthOverflow = gifFilePtr->Image.Width - info->originalWidth; int_fast32_t heightOverflow = gifFilePtr->Image.Height - info->originalHeight; const uint_fast32_t newRasterSize = gifFilePtr->Image.Width * gifFilePtr->Image.Height; if (newRasterSize > info->rasterSize || widthOverflow > 0 || heightOverflow > 0) { void *tmpRasterBits = reallocarray(info->rasterBits, newRasterSize, <<-- double-free here sizeof(GifPixelType)); if (tmpRasterBits == NULL) { gifFilePtr->Error = D_GIF_ERR_NOT_ENOUGH_MEM; break; } info->rasterBits = tmpRasterBits; info->rasterSize = newRasterSize; } Android में, आकार N की मेमोरी का डबल-फ्री करने से आकार N के दो बाद के मेमोरी-आवंटन एक ही पता लौटाते हैं।