R 3.4.4 में स्टैक-आधारित बफ़र ओवरफ़्लो। x86 पर पूर्ण शोषण, लेकिन प्रोग्राम बाधाओं के कारण x64 पर केवल गैजेट विश्लेषण के साथ RIP नियंत्रण। वही कमज़ोरी दो आर्किटेक्चरों में, जो अलग-अलग शोषण पथों की ओर ले जाती है।
R 3.4.4 में स्टैक-आधारित बफर ओवरफ़्लो। x86 पर पूर्ण शोषण, लेकिन x64 पर केवल RIP नियंत्रण गैजेट विश्लेषण के साथ प्रोग्राम बाधाओं के कारण। दो आर्किटेक्चर पर समान कमजोरी, जो अलग-अलग शोषण पथों की ओर ले जाती है।
यह रिपॉजिटरी उस सामग्री का हिस्सा है जिसका उपयोग मैं मेमोरी करप्शन शोषण सिखाते समय करता हूँ (अपने नियमित काम के अलावा, मैं विभिन्न साइबर सुरक्षा पाठ्यक्रमों में भी पढ़ाता हूँ जहाँ मैं रिवर्स इंजीनियरों की अगली पीढ़ी को प्रशिक्षित करने में मदद करता हूँ)।
CVE-2019-25485 वह मामला है जिसका उपयोग मैं तब करता हूँ जब मैं चाहता हूँ कि छात्र दो अलग-अलग आर्किटेक्चर पर समान कमजोरी पर काम करें और प्रत्यक्ष रूप से देखें कि उनके बीच क्या बदलता है। R 3.4.4 x86 और x64 दोनों संस्करणों में आता है, और दोनों में बिल्कुल वही ओवरफ़्लो मौजूद है, वही GUI फ़ील्ड, वही इनपुट हैंडलर, वही क्रैश। दोनों को यहाँ अलग-अलग अभ्यासों के रूप में दस्तावेज़ीकृत और शोषित किया गया है:
R 3.4.4 एक सांख्यिकीय कंप्यूटिंग एप्लिकेशन है, न कि कोई नेटवर्क सेवा या ब्राउज़र। ओवरफ़्लो डेस्कटॉप GUI फ़ील्ड के माध्यम से ट्रिगर होता है, जिसका अर्थ है कि हमला सतह मेरे द्वारा पढ़ाए जाने वाले हर दूसरे मामले से पूरी तरह से अलग है। इस मामले को शिक्षण के लिए उपयोगी बनाने वाली बातें:
R एक सांख्यिकीय कंप्यूटिंग और ग्राफिक्स वातावरण है जो Windows, macOS और Linux के लिए उपलब्ध है। कमजोरी GUI प्राथमिकताएँ संवाद में है, विशेष रूप से Language for menus and messages फ़ील्ड में, जो उपयोगकर्ता इनपुट को एक निश्चित आकार के स्टैक बफर में कॉपी करता है बिना इसकी लंबाई की जाँच किए।
प्रमुख तकनीकी विवरण:
R 3.4.4 Language for menus and messages फ़ील्ड को प्रोसेस करता है, आपूर्ति की गई स्ट्रिंग को एक निश्चित आकार के स्टैक बफर में कॉपी करके इसकी लंबाई की जाँच किए बिना। कमजोर लॉजिक का एक सरलीकृत संस्करण इस तरह दिखता है:
char language_buffer[256];
strcpy(language_buffer, user_input);
पर्याप्त लंबी स्ट्रिंग भेजने से कॉपी बफर के अंत से आगे लिखती है, स्टैक को दूषित करती है जब तक कि सहेजा गया रिटर्न पता अधिलेखित न हो जाए। जब फ़ंक्शन वापस आता है, CPU स्टैक से हमलावर-नियंत्रित मान को RIP में लोड करता है और उस पर कूदने का प्रयास करता है।
x64 पर, Windows किसी भी कूद से पहले कैननिकल पता सत्यापन लागू करता है। एक गैर-कैननिकल मान जैसे 0x4141414141414141 RIP लोड होने से पहले तत्काल एक्सेस उल्लंघन को ट्रिगर करता है, जिसका अर्थ है कि क्रैश x86 से अलग दिखता है, कोई साफ RIP = 4141414141414141 नहीं। ऑफसेट को RIP से सीधे पढ़ने के बजाय क्रैश के बाद स्टैक से चक्रीय पैटर्न पढ़कर पाया जाना चाहिए।
क्रैश को भाषा फ़ील्ड में एक लंबी स्ट्रिंग पेस्ट करके पुन: प्रस्तुत किया जा सकता है। किसी प्रमाणीकरण की आवश्यकता नहीं है। पेलोड उत्पन्न करने के लिए Python का उपयोग करने का उदाहरण:
import struct
payload = b'A' * 400
with open('payload.txt', 'wb') as f:
f.write(payload)
R 3.4.4 x64 खोलें Edit -> GUI प्राथमिकताएँ payload.txt की सामग्री को Language for menus and messages में पेस्ट करें OK पर क्लिक करें
इस रिपॉजिटरी का उद्देश्य केवल क्रैश प्रदर्शित करना नहीं है, बल्कि दोनों आर्किटेक्चर पर पूर्ण शोषण प्रक्रिया से गुजरना है, यह दस्तावेज़ीकृत करना कि x86 पर क्या काम करता है, x64 पर क्या टूटता है, और अधिक महत्वपूर्ण बात, क्यों।
मुख्य README को साफ रखने के लिए, विस्तृत शोषण नोट्स, स्क्रिप्ट और डीबगर चरण इस रिपॉजिटरी के Vulnerability 📂 फ़ोल्डर के अंदर रखे गए हैं, जो अलग-अलग x86 और x64 उपफ़ोल्डरों में व्यवस्थित हैं।
वहाँ आपको दोनों आर्किटेक्चर के लिए पूर्ण कार्यप्रवाह मिलेगा:
x86 - पूर्ण शोषण:
x64 - RIP नियंत्रण और शोषण विश्लेषण: