Ret2esp / Ret2reg
Ret2esp
क्योंकि ESP (स्टैक पॉइंटर) हमेशा स्टैक के शीर्ष पर पॉइंट करता है, इस तकनीक में EIP (इंस्ट्रक्शन पॉइंटर) को jmp esp
या call esp
इंस्ट्रक्शन का पता बदलना शामिल है। इसके द्वारा, शैलकोड सीधे ओवरराइट किए गए EIP के बाद स्थापित होता है। जब ret
इंस्ट्रक्शन कार्यान्वित होता है, तो ESP अगले पते पर पॉइंट करता है, ठीक जहाँ शैलकोड संग्रहीत है।
अगर एड्रेस स्पेस लेआउट रैंडमाइज़ेशन (ASLR) विंडोज या लिनक्स में सक्षम नहीं है, तो साझा लाइब्रेरी में पाए गए jmp esp
या call esp
इंस्ट्रक्शन का उपयोग संभव है। हालांकि, ASLR सक्रिय होने पर, इन इंस्ट्रक्शन्स के लिए विकल्पीय कार्यक्रम के भीतर देखने की आवश्यकता हो सकती है (और आपको PIE को परास्त करने की आवश्यकता हो सकती है)।
इसके अतिरिक्त, EIP को करप्शन के बाद शैलकोड स्थापित करने की क्षमता, स्टैक के बीच में नहीं, सुनिश्चित करती है कि किसी भी push
या pop
इंस्ट्रक्शन जो कार्यक्रम के संचालन के दौरान कार्यान्वित होते हैं, शैलकोड के साथ हस्तक्षेप नहीं करते। यह हस्तक्षेप हो सकता है अगर शैलकोड कार्यक्रम के स्टैक के बीच में स्थापित होता।
स्थान की कमी
अगर आप RIP को ओवरराइट करने के बाद लिखने के लिए स्थान की कमी है (शायद कुछ बाइट्स केवल), तो पहले jmp
शैलकोड जैसा एक आरंभिक लिखें:
और शेलकोड को स्टैक में पहले लिखें।
उदाहरण
आप इस तकनीक का उदाहरण https://ir0nstone.gitbook.io/notes/types/stack/reliable-shellcode/using-rsp में देख सकते हैं जिसमें एक अंतिम धोखाधड़ी शामिल है:
आप इस तकनीक का एक और उदाहरण देख सकते हैं https://guyinatuxedo.github.io/17-stack_pivot/xctf16_b0verflow/index.html. यहाँ एक बफर ओवरफ्लो बिना NX सक्षम किया गया है, इसमें एक गैजेट का उपयोग किया गया है जो $esp
का पता कम करता है और फिर jmp esp;
का उपयोग करके शेलकोड पर जाने के लिए:
Ret2reg
उसी तरह, अगर हमें पता है कि एक फ़ंक्शन वहाँ पता करता है जहाँ शेलकोड स्टोर है, तो हम call eax
या jmp eax
इंस्ट्रक्शन का उपयोग कर सकते हैं (ret2eax तकनीक के रूप में), हमारे शेलकोड को निष्पादित करने के लिए एक और विधि प्रदान करते हैं। eax की तरह, किसी भी अन्य रजिस्टर का उपयोग किया जा सकता है जिसमें दिलचस्प पता हो (ret2reg।)
उदाहरण
आप यहाँ कुछ उदाहरण पा सकते हैं:
strcpy
शेलकोड को स्टोर किए गए बफ़र का पताeax
में रखेगा औरeax
को अधिलिखित नहीं किया जा रहा है, इसलिएret2eax
का उपयोग संभव है।
ARM64
Ret2sp
ARM64 में SP रजिस्ट्री पर जाने की अनुमति देने वाले इंस्ट्रक्शन नहीं हैं। शायद किसी गैजेट को ढूंढना संभव हो कि sp को एक रजिस्ट्री में मूव करता है और फिर उस रजिस्ट्री पर जाता है, लेकिन मेरे काली की libc में मैंने ऐसा कोई गैजेट नहीं पाया:
मैंने केवल उन्हें खोजा जिन्होंने sp की कॉपी की गई रजिस्ट्री के मान को बदल दिया था जिससे उसका उपयोगहीन हो जाता है:
Ret2reg
यदि किसी रजिस्ट्री में एक दिलचस्प पता है तो उस पर जाने की संभावना है बस उचित निर्देश का पता लगाना है। आप कुछ इस प्रकार का उपयोग कर सकते हैं:
आरएम64 में, यह x0
है जो फ़ंक्शन के रिटर्न मान को संग्रहित करता है, इसलिए यह हो सकता है कि x0 उपयोक्ता द्वारा नियंत्रित बफ़र का पता संग्रहित करता है जिसमें एक शैलकोड को क्रियान्वित करने के लिए।
उदाहरण कोड:
फ़ंक्शन की disassembly की जाँच करने पर देखा जा सकता है कि बफर का पता (जो bof के लिए विकल्पी है और उपयोगकर्ता द्वारा नियंत्रित है) x0
में स्टोर किया गया है जब बफर ओवरफ्लो से वापस लौटा जाता है:
यह भी संभव है कि गैजेट br x0
को do_stuff
फ़ंक्शन में ढूंढा जा सकता है:
हम उस गैजेट का उपयोग करेंगे ताकि हम उस पर जाएं क्योंकि बाइनरी PIE के साथ कंपाइल नहीं है। पैटर्न का उपयोग करके देखा जा सकता है कि बफर ओवरफ्लो का ऑफसेट 80 है, इसलिए एक्स्प्लॉइट होगा:
यदि fgets
की जगह कुछ ऐसा read
का उपयोग होता, तो PIE को भी छलकर सकता था केवल वापसी के पते के अंतिम 2 बाइट को ओवरराइट करके br x0;
निर्देश को वापस लौटने के लिए पूरे पते को जानने की आवश्यकता नहीं होती।
fgets
के साथ यह काम नहीं करता क्योंकि यह अंत में नल (0x00) बाइट जोड़ता है।
सुरक्षा
NX: यदि स्टैक क्रियाशील नहीं है तो यह मदद नहीं करेगा क्योंकि हमें शेलकोड को स्टैक में रखना होगा और इसे निष्पादित करने के लिए उस पर जाने की आवश्यकता है।
संदर्भ
Last updated