Ret2esp / Ret2reg
Ret2esp
क्योंकि ESP (स्टैक पॉइंटर) हमेशा स्टैक के शीर्ष पर पॉइंट करता है, इस तकनीक में EIP (इंस्ट्रक्शन पॉइंटर) को jmp esp
या call esp
इंस्ट्रक्शन का पता बदलना शामिल है। इसके द्वारा, शैलकोड सीधे ओवरराइट किए गए EIP के बाद स्थापित होता है। जब ret
इंस्ट्रक्शन कार्यान्वित होता है, तो ESP अगले पते को पॉइंट करता है, ठीक वहाँ जहाँ शैलकोड संग्रहित है।
यदि Address Space Layout Randomization (ASLR) Windows या Linux में सक्षम नहीं है, तो साझा लाइब्रेरी में पाए गए 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. यहाँ एनएक्स सक्षम नहीं है, एक गैजेट का उपयोग किया गया है जिससे $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
में स्टोर किया गया है जब बफर ओवरफ्लो से वापस लौटा जाता है:
यह भी संभव है कि do_stuff
फ़ंक्शन में br x0
गैजेट मिल सकता है:
हम उस गैजेट का उपयोग करेंगे ताकि हम उस पर जाएं क्योंकि बाइनरी PIE के साथ कंपाइल नहीं है। पैटर्न का उपयोग करके देखा जा सकता है कि बफर ओवरफ्लो का ऑफसेट 80 है, इसलिए एक्सप्लॉइट होगा:
अगर fgets
की जगह कुछ ऐसा read
का उपयोग होता, तो PIE को भी छलकर सकता था केवल वापसी के पते के अंतिम 2 बाइट को ओवरराइट करके br x0;
निर्देश को वापस लौटने के लिए पूरे पते की आवश्यकता नहीं होती।
fgets
के साथ यह काम नहीं करता क्योंकि यह अंत में एक नल (0x00) बाइट जोड़ता है।
सुरक्षा
NX: यदि स्टैक को क्रियाशील नहीं किया गया है तो यह मदद नहीं करेगा क्योंकि हमें शेलकोड को स्टैक में रखना है और इसे निष्पादित करने के लिए जानपद्द करना है।
संदर्भ
Last updated