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