Ret2csu
ret2csu एक हैकिंग तकनीक है जब आप किसी प्रोग्राम के नियंत्रण पर कब्जा पाने की कोशिश कर रहे हो लेकिन आपको सामान्य रूप से प्रोग्राम के व्यवहार को बदलने के लिए उपयोग किए जाने वाले गैजेट्स नहीं मिल रहे हैं।
जब एक प्रोग्राम किसी विशेष पुस्तकालय (जैसे libc) का उपयोग करता है, तो इसमें कुछ स्थापित फ़ंक्शन होते हैं जो विभिन्न प्रोग्राम के अंशों के बीच कैसे बातचीत करें को प्रबंधित करने के लिए होते हैं। इन फ़ंक्शनों में हमारे गुम होने वाले गैजेट्स के रूप में काम कर सकने वाले कुछ छुपे हुए गहने होते हैं, खासकर एक जिसे __libc_csu_init
कहा जाता है।
__libc_csu_init में जादूगर गैजेट्स
__libc_csu_init
में, दो इंस्ट्रक्शनों (गैजेट्स) के दो अनुक्रम हैं जिन्हें हाइलाइट किया जा सकता है:
पहला अनुक्रम हमें कई रजिस्टर्स (rbx, rbp, r12, r13, r14, r15) में मान सेट करने की अनुमति देता है। ये वे स्लॉट हैं जहां हम बाद में उपयोग करने के लिए संख्याएँ या पते संग्रहित कर सकते हैं।
यह गैजेट हमें इन रजिस्टरों को नियंत्रित करने की अनुमति देता है, जिन्हें हम स्टैक से बाहर निकालकर उनमें डाल सकते हैं।
दूसरी क्रमश: उन मानों का उपयोग करता है जिन्हें हमने सेट किया है ताकि हम कुछ काम कर सकें:
विशिष्ट मानों को अन्य रजिस्टर में ले जाएं, जिन्हें हम फ़ंक्शन में पैरामीटर के रूप में उपयोग करने के लिए तैयार कर सकते हैं।
r15 और rbx में मानों को जोड़कर निर्धारित स्थान पर कॉल करें, फिर rbx को 8 से गुणा करें।
शायद आपको वहाँ लिखने के लिए कोई पता न हो और आपको एक
ret
इंस्ट्रक्शन की आवश्यकता हो। ध्यान दें कि दूसरा गैजेट भी एकret
में समाप्त होगा, लेकिन आपको उस तक पहुंचने के लिए कुछ शर्तों को पूरा करना होगा:
शर्तें होंगी:
[r12 + rbx*8]
को कॉल करने वाले फ़ंक्शन का पता होना चाहिए (अगर कोई विचार नहीं है और कोई pie नहीं है, तो आप सिर्फ_init
फ़ंक्शन का उपयोग कर सकते हैं):यदि _init
0x400560
पर है, GEF का उपयोग करके इसके लिए मेमोरी में एक पॉइंटर खोजें और[r12 + rbx*8]
को पॉइंटर के साथ पता होने वाला पता बनाएं:
rbp
औरrbx
को एक ही मान रखना चाहिए ताकि जंप से बचा जा सकेआपको ध्यान में रखने योग्य कुछ छूटे हुए pops हैं
RDI और RSI
रिट२सीएसयू गैजेट से rdi
और rsi
को नियंत्रित करने का एक और तरीका है उसके विशिष्ट offsets तक पहुंचकर:
अधिक जानकारी के लिए इस पेज की जाँच करें:
pageBROP - Blind Return Oriented Programmingउदाहरण
कॉल का उपयोग
सोचिए आप एक सिस्टम कॉल करना चाहते हैं या write()
जैसे फ़ंक्शन को कॉल करना चाहते हैं लेकिन rdx
और rsi
रजिस्टर में पैरामीटर के रूप में विशिष्ट मान चाहिए। सामान्य रूप से, आप उन रजिस्टरों को सीधे सेट करने वाले गैजेट्स खोजेंगे, लेकिन आप कोई भी नहीं मिलता।
यहाँ ret2csu काम में आता है:
रजिस्टर सेट करें: पहले जादूगर गैजेट का उपयोग करें ताकि आप स्टैक से मानों को रीड करके rbx, rbp, r12 (edi), r13 (rsi), r14 (rdx), और r15 में डाल सकें।
दूसरे गैजेट का उपयोग करें: उन रजिस्टरों को सेट करके, आप दूसरे गैजेट का उपयोग करते हैं। इससे आप अपने चुने हुए मानों को
rdx
औरrsi
में ले जा सकते हैं (r14 और r13 से अनुकूलित करके), फ़ंक्शन कॉल के लिए पैरामीटर तैयार कर सकते हैं। इसके अतिरिक्त,r15
औरrbx
को नियंत्रित करके, आप प्रोग्राम को एक फ़ंक्शन कॉल करने के लिए पता किए गए पते पर फ़ंक्शन को कॉल करा सकते हैं और[r15 + rbx*8]
में रख सकते हैं।
आपके पास इस तकनीक का उपयोग करने और इसे समझाने का उदाहरण है, और यह उसने उपयोग किया गया अंतिम उत्पीड़न है:
ध्यान दें कि पिछला एक्सप्लॉइट RCE
करने के लिए नहीं है, यह केवल एक फ़ंक्शन को बुलाने के लिए है जिसका नाम win
है (ROP श्रृंखला में gets
को कॉल करके win
का पता stdin से लेते हुए और इसे r15 में स्टोर करते हुए) तीसरे तर्क के साथ जिसका मान 0xdeadbeefcafed00d
है।
कॉल को छोड़कर और रिट तक पहुंचना
निम्नलिखित एक्सप्लॉइट इस पेज से निकाला गया था जहां ret2csu का उपयोग किया गया था लेकिन कॉल का उपयोग करने की बजाय, तुलनाएँ छोड़कर ret
तक पहुंच रहा है:
क्यों न केवल libc का प्रयोग करें?
सामान्यत: ये मामले ret2plt + ret2lib के लिए भी संवेदनशील होते हैं, लेकिन कभी-कभी आपको उन सभी पैरामीटरों को नियंत्रित करने की आवश्यकता होती है जो आपको libc में सीधे मिलने वाले गैजेट्स के साथ आसानी से नियंत्रित नहीं किया जा सकता है। उदाहरण के लिए, write()
फ़ंक्शन को तीन पैरामीटर की आवश्यकता होती है, और इन सभी को सीधे सेट करने के लिए गैजेट्स खोजना संभव नहीं हो सकता।
Last updated