ओपन सोर्स लाइब्रेरीज़ में वल्नरेबिलिटी डिस्कवरी: CVE-2020-11863 का विश्लेषण

ओपन सोर्स प्रोजेक्ट्स किसी भी सॉफ्टवेयर डेवलपमेंट प्रोसेस के बिल्डिंग ब्लॉक्स हैं। जैसा कि हमने अपने पिछले ब्लॉग में संकेत दिया था, क्योंकि अधिक से अधिक उत्पाद खुले स्रोत कोड का उपयोग करते हैं, समग्र हमले की सतह में वृद्धि अपरिहार्य है, खासकर जब खुले स्रोत कोड का उपयोग करने से पहले ऑडिट नहीं किया जाता है। इसलिए इसे संभावित कमजोरियों के लिए पूरी तरह से जांचने और डेवलपर्स के साथ मिलकर उन्हें ठीक करने के लिए, अंततः हमलों को कम करने की सिफारिश की जाती है। हमने यह भी संकेत दिया कि हम विंडोज और लिनक्स में ग्राफिक्स लाइब्रेरी पर शोध कर रहे थे, विंडोज जीडीआई में कई कमजोरियों के साथ-साथ लिनक्स वेक्टर ग्राफिक्स लाइब्रेरी एफबीआईएफएफ की रिपोर्टिंग कर रहे थे। हम अभी भी कई अन्य लिनक्स ग्राफिक्स पुस्तकालयों का ऑडिट कर रहे हैं क्योंकि ये विरासत कोड हैं और पहले कड़ाई से परीक्षण नहीं किया गया है।

इस ब्लॉग श्रृंखला के भाग 1 में, हमने ओपनवर्क रिसर्च के महत्व का विस्तार से वर्णन किया है, जो हमने libEMF लाइब्रेरी में रिपोर्ट की गई कमजोरियों को रेखांकित करते हुए किया है। हमने मेमोरी सैनिटाइज़र के साथ कोड को संकलित करने के महत्व पर भी प्रकाश डाला है और यह विभिन्न प्रकार के मेमोरी करप्शन बग्स का पता लगाने में मदद कर सकता है। सारांश में, एड्रेस सैनिटाइज़र (ASAN) मेमोरी आवंटन / डीललोकेशन फ़ंक्शंस जैसे कि मॉलॉक () / फ्री () को स्वीकार करता है और संबंधित फिल बाइट्स (malloc_fill_byte / free_fit_byte) के साथ मेमोरी को भरता है। यह इन मेमोरी स्थानों पर पढ़ने और लिखने की निगरानी भी करता है, जिससे रन समय के दौरान गलत उपयोग का पता लगाने में मदद मिलती है।

इस ब्लॉग में, हम रिपोर्ट किए गए भेद्यताओं में से एक के लिए एक अधिक विस्तृत विश्लेषण प्रदान करते हैं, CVE-2020-11863, जो कि एकतरफा स्मृति के उपयोग के कारण था। यह भेद्यता CVO-2020-11865 से संबंधित है, GlobalObject :: Find () फंक्शन में libEMF में सीमा से बाहर एक वैश्विक ऑब्जेक्ट वेक्टर। हालांकि, क्रैश कॉल स्टैक अलग-अलग निकला, यही कारण है कि हमने इस पर आगे की जांच करने और इस गहरे गोता ब्लॉग का उत्पादन करने का फैसला किया।

एएसएएन द्वारा प्रदान की गई जानकारी फजर के बाहर भेद्यता दुर्घटना को पुन: उत्पन्न करने के लिए पर्याप्त थी। ASAN जानकारी से, भेद्यता एक अशक्त सूचक विक्षेप प्रतीत होती है, लेकिन यह वास्तविक मूल कारण नहीं था, जैसा कि हम नीचे चर्चा करेंगे।

कॉल स्टैक को देखते हुए, ऐसा प्रतीत होता है कि एप्लिकेशन गतिशील रूप से ऑब्जेक्ट को कास्टिंग करते समय क्रैश हो गया, जिसके लिए कई कारण हो सकते हैं। उन संभावित कारणों में से, जो संभव प्रतीत होते हैं, या तो एप्लिकेशन ने गैर-मौजूद वर्चुअल टेबल पॉइंटर तक पहुंचने का प्रयास किया, या एप्लिकेशन के क्रैश होने पर फ़ंक्शन से लौटाए गए ऑब्जेक्ट पते को एक जंगली पता एक्सेस किया गया था। इस दुर्घटना के बारे में अधिक संदर्भ प्राप्त करते हुए, हमने डिबगिंग करते समय एक दिलचस्प रजिस्टर मान दिया। नीचे दिखाया गया है कि गैर-मौजूद मेमोरी एक्सेस का संकेत करने वाले डिसएस्पेशन में क्रैश पॉइंट।

यदि हम क्रैश बिंदु पर रजिस्टरों की स्थिति को देखते हैं, तो यह ध्यान रखना दिलचस्प है कि रजिस्टर RDI 0xbebebebebebebe का एक असामान्य मूल्य है। हम यह जांचने के लिए थोड़ा गहरा खोदना चाहते थे कि यह मूल्य रजिस्टर में कैसे मिला, जिसके परिणामस्वरूप वाइल्ड मेमोरी एक्सेस है। चूँकि हमारे पास पुस्तकालय का स्रोत था, हम तुरंत जाँच सकते हैं कि यह रजिस्टर वस्तुओं को स्मृति में पहुँचाने के संदर्भ में क्या था।

एड्रेस सेनिटाइज़र डॉक्यूमेंट का जिक्र करते हुए, यह पता चलता है कि ASAN लिखता है 0xbe डिफ़ॉल्ट रूप से नई आवंटित स्मृति के लिए, अनिवार्य रूप से अर्थ यह 64-बिट मान लिखा गया था, लेकिन स्मृति को प्रारंभ नहीं किया गया था। ASAN इसे कहता है malloc_fill_byte। यह भी जब यह मुक्त हो जाता है free_fill_byte के साथ मेमोरी को भरने के द्वारा ही करता है। यह अंततः मेमोरी एक्सेस त्रुटियों की पहचान करने में मदद करता है

ASAN की इस प्रकृति को यहाँ के libsanitizer स्रोत में भी सत्यापित किया जा सकता है। नीचे स्रोत फ़ाइल से एक अंश है।

नीचे दिखाए गए अनुसार दुर्घटना बिंदु पर स्टैक ट्रेस को देखकर, SelectObject () फ़ंक्शन में क्रैश हुआ। कोड का यह हिस्सा एन्हांस्ड मेटा फ़ाइल (EMF) फ़ाइल के EMR_SELECTOBJECT रिकॉर्ड संरचना को संसाधित करने के लिए ज़िम्मेदार है और फ़ंक्शन को दिया गया ग्राफिक्स ऑब्जेक्ट हैंडल 0x80000018 है। हम यह जांचने के लिए कोड के प्रवाह की जांच करना चाहते हैं कि क्या यह कुछ ऐसा है जो सीधे इनपुट EMF फ़ाइल से आता है और इसे एक हमलावर द्वारा नियंत्रित किया जा सकता है।

SelectObject () फ़ंक्शन में, EMR_SELECTOBJECT रिकॉर्ड संरचना को संसाधित करते समय, GDI ऑब्जेक्ट को हैंडल GlobalObjects.find () को ऊपर दिए गए कोड स्निपेट में दिखाया गया है, जो वैश्विक रूप से बदल जाता है। स्टॉक वस्तु वेक्टर GDI ऑब्जेक्ट हैंडल से उच्च क्रम बिट मास्किंग करके और इसे इंडेक्स में परिवर्तित करके, अंततः परिवर्तित किए गए इंडेक्स नंबर का उपयोग करके ऑब्जेक्ट वेक्टर से स्टॉक ऑब्जेक्ट संदर्भ लौटाता है। स्टॉक ऑब्जेक्ट एन्यूमरेशन पूर्वनिर्धारित तार्किक ग्राफिक्स ऑब्जेक्ट्स के इंडेक्स को निर्दिष्ट करता है जो कि एमएस प्रलेखन में प्रलेखित ग्राफिक्स संचालन में उपयोग किया जा सकता है। उदाहरण के लिए, यदि ऑब्जेक्ट हैंडल 0x8000018 है, तो यह 0x7FFFFFFF के साथ एंडेड होगा, जिसके परिणामस्वरूप 0x18 होगा, जिसे वैश्विक स्टॉक ऑब्जेक्ट वेक्टर के सूचकांक के रूप में उपयोग किया जाएगा। यह स्टॉक ऑब्जेक्ट संदर्भ फिर गतिशील रूप से ग्राफिक्स ऑब्जेक्ट में डाला जाता है, जिसके बाद EMF :: GRAPHICSOBJECT सदस्य फ़ंक्शन getType () ग्राफिक्स ऑब्जेक्ट के प्रकार को निर्धारित करने के लिए कहा जाता है और फिर, बाद में इस फ़ंक्शन में, इसे फिर से एक उपयुक्त ग्राफिक्स ऑब्जेक्ट (BRUSH, PEN, FONT, PALETTE, EXTPEN) में डाला जाता है, जैसा कि नीचे दिए गए कोड स्निपेट में दिखाया गया है।

EMF :: GRAPHICSOBJECT EMF :: OBJECT से व्युत्पन्न वर्ग है और EMF :: OBJECT वर्ग का वंशानुक्रम चित्र नीचे दिखाया गया है।

हालाँकि, जैसा कि पहले उल्लेख किया गया था, हमें यह जानने में दिलचस्पी थी कि क्या वस्तु संभालती है, एक तर्क के रूप में पारित हुई SelectObject फ़ंक्शन, एक हमलावर द्वारा नियंत्रित किया जा सकता है। इस पर संदर्भ प्राप्त करने में सक्षम होने के लिए, हम नीचे दिखाए गए अनुसार EMR_SELECTOBJECT रिकॉर्ड के प्रारूप को देखें।

जैसा कि हमने यहां देखा, ihObject 4-बाइट अहस्ताक्षरित पूर्णांक है जो सूचकांक को स्टॉक ऑब्जेक्ट एन्यूमरेशन को निर्दिष्ट करता है। इस मामले में वैश्विक ऑब्जेक्ट वेक्टर में स्टॉक ऑब्जेक्ट संदर्भ बनाए रखा जाता है। यहां, 0x80000018 के ऑब्जेक्ट हैंडल का अर्थ है कि वैश्विक स्टॉक ऑब्जेक्ट वेक्टर तक पहुंचने के लिए इंडेक्स 0x18 का उपयोग किया जाएगा। यदि, इस समय के दौरान, ऑब्जेक्ट वेक्टर की लंबाई कम है तो 0x18 और लंबाई की जांच ऑब्जेक्ट वेक्टर तक पहुंचने से पहले नहीं की जाती है, इसके परिणामस्वरूप सीमा मेमोरी एक्सेस से बाहर हो जाएगा।

नीचे EMR_SELECTOBJECT मेटाफ़ाइल रिकॉर्ड के प्रसंस्करण का दृश्य प्रतिनिधित्व है।

इस समस्या को डीबग करते हुए, हम GlobalObjects.find पर एक विराम बिंदु सक्षम करते हैं () और तब तक जारी रखते हैं जब तक हमारे पास ऑब्जेक्ट हैंडल 0x800x018 नहीं है; अनिवार्य रूप से, हम उस बिंदु पर पहुंच जाते हैं, जहां ऊपर हाइलाइट किया गया EMR_SELECTOBJECT रिकॉर्ड संसाधित किया जा रहा है। जैसा कि नीचे दिखाया गया है, ऑब्जेक्ट हैंडल को आकार के ऑब्जेक्ट वेक्टर (0x16 = 22) तक पहुंचने के लिए इंडेक्स (0x18 = 24) में परिवर्तित किया जाता है, जिसके परिणामस्वरूप सीमा पहुंच से बाहर हो जाता है, जिसे हमने CVE-2020-11865 के रूप में रिपोर्ट किया है।

कोड में आगे बढ़ते हुए, यह STL वेक्टर लाइब्रेरी stl_vector.h में प्रवेश करता है, जो std के गतिशील विस्तार को लागू करता है :: वैक्टर। चूँकि इस समय वेक्टर ऑब्जेक्ट्स में केवल 22 तत्व होते हैं, इसलिए STL वेक्टर, वेक्टर द्वारा दर्शाए गए आकार के वेक्टर का विस्तार करेगा, वेक्टर को पास इंडेक्स द्वारा एक्सेस करेगा, और उस ऑब्जेक्ट संदर्भ में मान लौटाएगा, जैसा कि में दिखाया गया है नीचे दिए गए कोड स्निपेट, जो बाहर आता है 0xbebebebebebebebe ASAN द्वारा भरा गया है।

कोड का उपयोग करता है एसटीडी: संभाजक वेक्टर मेमोरी का प्रबंधन मुख्य रूप से मेमोरी आवंटन और डीलक्लोकेशन के लिए किया जाता है। आगे के विश्लेषण पर, यह पता चला है कि इस मामले में, 0xbebebebebebebe लौटाया गया मान, गैर-मौजूद स्टॉक ऑब्जेक्ट का वर्चुअल पॉइंटर है, जिसे डायनेमिक कास्टिंग के दौरान डिरेल किया जाता है, जिसके परिणामस्वरूप क्रैश होता है।

जैसा कि हमारे पहले के ब्लॉग में उल्लेख किया गया है, पुस्तकालय के सुधार बाद के संस्करण में जारी किए गए हैं, जो यहां उपलब्ध हैं।

निष्कर्ष

उत्पादों में तीसरे पक्ष के कोड का उपयोग करने से निश्चित रूप से समय की बचत होती है और विकास की गति में वृद्धि होती है, यह संभावित रूप से कमजोरियों की मात्रा में वृद्धि के साथ आता है, खासकर जब कोड बिना परीक्षण किए बिना उत्पादों में एकीकृत और एकीकृत रहता है। उपयोग किए गए खुले स्रोत पुस्तकालयों का फ़्यूज़ परीक्षण करना बेहद महत्वपूर्ण है, जो विकास चक्र में पहले कमजोरियों की खोज करने में मदद कर सकता है और उत्पाद को भेजने से पहले उन्हें ठीक करने का अवसर प्रदान करता है, परिणामस्वरूप हमलों को कम करना। हालांकि, जैसा कि हमने अपने पिछले ब्लॉग में जोर दिया था, जिम्मेदार शोधकर्ताओं को खुला खुलासा करने के लिए भेद्यता शोधकर्ताओं और खुले स्रोत समुदाय के बीच सहयोग को मजबूत करना महत्वपूर्ण है, जिससे कोड के रखवाले उन्हें समय पर फैशन में संबोधित कर सकें।