Ret2csu
https://www.scs.stanford.edu/brop/bittau-brop.pdfमौलिक जानकारी
ret2csu एक हैकिंग तकनीक है जिसका उपयोग तब किया जाता है जब आप किसी प्रोग्राम के नियंत्रण पर कब्जा पाने की कोशिश कर रहे हों लेकिन आपको उस प्रोग्राम के व्यवहार को बदलने के लिए सामान्य रूप से उपयोग किए जाने वाले गैजेट्स नहीं मिल रहे हैं।
जब एक प्रोग्राम किसी विशेष पुस्तकालय (जैसे libc) का उपयोग करता है, तो उसमें कुछ ऐसे निर्देशिका समावेश होते हैं जो विभिन्न टुकड़ों के बीच कैसे बातचीत करें को प्रबंधित करने के लिए निर्मित फ़ंक्शन होते हैं। इन फ़ंक्शनों में से कुछ छुपे हुए गहने होते हैं जो हमारे गुमशुदा गैजेट्स के रूप में काम कर सकते हैं, खासकर एक जिसे __libc_csu_init
कहा जाता है।
__libc_csu_init में जादूगर गैजेट्स
__libc_csu_init
में, दो निर्देशिका अनुक्रम हैं (गैजेट्स) जिन्हें हाइलाइट किया जाएगा:
पहला अनुक्रम हमें कई रजिस्टर्स (rbx, rbp, r12, r13, r14, r15) में मान सेट करने की अनुमति देता है। ये स्लॉट्स की तरह हैं जहाँ हम बाद में उपयोग करने के लिए संख्याएँ या पते संग्रहित कर सकते हैं।
यह गैजेट हमें इन रजिस्टरों को नियंत्रित करने की अनुमति देता है, जिन्हें हम स्टैक से बाहर निकालकर उनमें डाल सकते हैं।
दूसरी क्रमश: उन मानों का उपयोग करने के लिए उपयोग करता है जिन्हें हमने सेट किया है कुछ काम करने के लिए:
विशिष्ट मानों को अन्य रजिस्टर में ले जाएं, जिन्हें हम फ़ंक्शन में पैरामीटर के रूप में उपयोग करने के लिए तैयार करते हैं।
एक स्थान पर कॉल करें जिसे r15 और rbx में मानों को जोड़कर निर्धारित किया गया है, फिर rbx को 8 से गुणा करके।
शायद आपको वहाँ लिखने के लिए कोई पता न हो और आपको एक
ret
इंस्ट्रक्शन की आवश्यकता हो। ध्यान दें कि दूसरा गैजेट भी एकret
में समाप्त होगा, लेकिन आपको उस तक पहुंचने के लिए कुछ शर्तें पूरी करनी होंगी:
The conditions will be:
[r12 + rbx*8]
कोई पता करने वाले फ़ंक्शन को स्टोर करने वाले पते पर प्वाइंट करना चाहिए (अगर कोई विचार नहीं है और कोई पाई नहीं है, तो आप सिर्फ_init
फ़ंक्शन का उपयोग कर सकते हैं):यदि _init
0x400560
पर है, GEF का उपयोग करके इसके लिए मेमोरी में एक पॉइंटर खोजें और[r12 + rbx*8]
को पॉइंटर के साथ पते का पता होना चाहिए:
rbp
औरrbx
का एक ही मान होना चाहिए ताकि जंप से बचा जा सकेआपको ध्यान में रखने योग्य कुछ छूटे हुए पॉप्स हैं
RDI और RSI
रेट2सीएसयू गैजेट से rdi
और rsi
को नियंत्रित करने का एक और तरीका यह है कि आप इसके विशिष्ट ऑफसेट तक पहुंचें:
अधिक जानकारी के लिए इस पेज की जाँच करें:
BROP - 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
कहा जाता है (gets में win
का पता stdin से लेते हुए ROP श्रृंखला में और इसे r15 में स्टोर करते हुए) तीसरे तर्क के साथ एक मान 0xdeadbeefcafed00d
के साथ।
कॉल को छोड़कर और रिट तक पहुंचना
निम्नलिखित एक्सप्लॉइट इस पेज से निकाला गया था जहां ret2csu का उपयोग किया गया था लेकिन कॉल का उपयोग करने की बजाय, तुलनाएँ छोड़कर और कॉल के बाद रिट
तक पहुंचने की कोशिश की गई थी:
क्यों न केवल libc का प्रयोग करें?
सामान्यत: ये मामले ret2plt + ret2lib के लिए भी संवेदनशील होते हैं, लेकिन कभी-कभी आपको उन सभी पैरामीटरों को नियंत्रित करने की आवश्यकता होती है जो आपको सीधे libc में पाए जाने वाले गैजेट्स के साथ आसानी से नियंत्रित नहीं किया जा सकता है। उदाहरण के लिए, write()
फ़ंक्शन को तीन पैरामीटर की आवश्यकता होती है, और इन सभी को सीधे सेट करने के लिए गैजेट्स खोजना संभव नहीं हो सकता।
Last updated