Leaking libc address with ROP
Last updated
Last updated
AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE) GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE)
ओवरफ्लो ऑफसेट खोजें
POP_RDI
गैजेट, PUTS_PLT
और MAIN
गैजेट खोजें
पिछले गैजेट्स का उपयोग करके puts या अन्य libc फ़ंक्शन का मेमोरी पता लीक करें और libc संस्करण खोजें (डाउनलोड करें)
पुस्तकालय के साथ, ROP की गणना करें और इसका शोषण करें
यह ट्यूटोरियल इस ट्यूटोरियल में प्रस्तावित कोड/बाइनरी का शोषण करने जा रहा है: https://tasteofsecurity.com/security/ret2libc-unknown-libc/ अन्य उपयोगी ट्यूटोरियल: https://made0x78.com/bseries-ret2libc/, https://guyinatuxedo.github.io/08-bof_dynamic/csaw19_babyboi/index.html
फाइल का नाम: vuln.c
एक्सप्लॉइट डाउनलोड करें और इसे कमजोर बाइनरी के समान निर्देशिका में रखें और स्क्रिप्ट को आवश्यक डेटा दें:
टेम्पलेट को एक्सप्लॉइट के साथ आगे बढ़ने से पहले एक ऑफसेट की आवश्यकता होती है। यदि कोई प्रदान किया गया है, तो यह इसे खोजने के लिए आवश्यक कोड निष्पादित करेगा (डिफ़ॉल्ट रूप से OFFSET = ""
):
Execute python template.py
एक GDB कंसोल खोला जाएगा जिसमें प्रोग्राम क्रैश हो रहा है। उस GDB कंसोल के अंदर x/wx $rsp
चलाएँ ताकि bytes प्राप्त कर सकें जो RIP को ओवरराइट करने वाले थे। अंत में एक python कंसोल का उपयोग करके offset प्राप्त करें:
ऑफसेट (इस मामले में 40) खोजने के बाद, उस मान का उपयोग करके टेम्पलेट के अंदर OFFSET चर को बदलें।
OFFSET = "A" * 40
एक और तरीका होगा: pattern create 1000
-- ret तक निष्पादित करें -- pattern seach $rsp
GEF से।
अब हमें बाइनरी के अंदर ROP गैजेट्स खोजने की आवश्यकता है। ये ROP गैजेट्स puts
को कॉल करने के लिए उपयोगी होंगे ताकि libc का पता लगाया जा सके, और बाद में अंतिम हमले को लॉन्च करने के लिए।
The PUTS_PLT
फंक्शन puts को कॉल करने के लिए आवश्यक है।
The MAIN_PLT
मुख्य फंक्शन को फिर से कॉल करने के लिए आवश्यक है एक इंटरैक्शन के बाद overflow को फिर से exploits करने के लिए (exploitation के अनंत राउंड)। यह प्रत्येक ROP के अंत में प्रोग्राम को फिर से कॉल करने के लिए उपयोग किया जाता है।
The POP_RDI को कॉल किए गए फंक्शन को पैरामीटर पास करने के लिए आवश्यक है।
इस चरण में आपको कुछ भी निष्पादित करने की आवश्यकता नहीं है क्योंकि सब कुछ pwntools द्वारा निष्पादन के दौरान पाया जाएगा।
अब यह पता लगाने का समय है कि कौन सी libc लाइब्रेरी का संस्करण उपयोग किया जा रहा है। ऐसा करने के लिए हम फंक्शन puts
के मेमोरी में पता को leak करने जा रहे हैं और फिर हम यह खोजने जा रहे हैं कि उस पते में puts संस्करण किस लाइब्रेरी संस्करण में है।
इसको करने के लिए, निष्पादित कोड की सबसे महत्वपूर्ण पंक्ति है:
यह कुछ बाइट्स भेजेगा जब तक कि RIP को overwriting करना संभव न हो: OFFSET
.
फिर, यह address को सेट करेगा gadget POP_RDI
का ताकि अगला address (FUNC_GOT
) RDI रजिस्ट्रि में सहेजा जा सके। इसका कारण यह है कि हम puts को call करना चाहते हैं passing करते हुए इसे PUTS_GOT
का address क्योंकि मेमोरी में puts फ़ंक्शन का address PUTS_GOT
द्वारा इंगित address में सहेजा गया है।
इसके बाद, PUTS_PLT
को कॉल किया जाएगा (जिसमें PUTS_GOT
RDI के अंदर है) ताकि puts read the content करे PUTS_GOT
के अंदर (मेमोरी में puts फ़ंक्शन का address) और इसे print out करे।
अंत में, main function को फिर से कॉल किया जाता है ताकि हम फिर से overflow का फायदा उठा सकें।
इस तरह हमने puts function को print करने के लिए trick किया है memory में फ़ंक्शन puts का address (जो libc लाइब्रेरी के अंदर है)। अब जब हमारे पास वह address है, हम search कर सकते हैं कि कौन सा libc संस्करण उपयोग में है।
चूंकि हम कुछ local बाइनरी का exploiting कर रहे हैं, इसलिए यह नहीं आवश्यक है कि यह पता लगाया जाए कि कौन सा libc संस्करण उपयोग में है (बस /lib/x86_64-linux-gnu/libc.so.6
में लाइब्रेरी खोजें)।
लेकिन, एक दूरस्थ exploit मामले में मैं यहाँ बताऊंगा कि आप इसे कैसे खोज सकते हैं:
आप वेब पृष्ठ पर देख सकते हैं कि कौन सी लाइब्रेरी उपयोग में है: https://libc.blukat.me/ यह आपको खोजी गई libc के संस्करण को डाउनलोड करने की भी अनुमति देगा।
आप यह भी कर सकते हैं:
$ git clone https://github.com/niklasb/libc-database.git
$ cd libc-database
$ ./get
इसमें कुछ समय लगेगा, धैर्य रखें। इसके काम करने के लिए हमें आवश्यकता है:
Libc प्रतीक नाम: puts
लीक किया गया libc address: 0x7ff629878690
हम यह पता लगा सकते हैं कि कौन सा libc सबसे अधिक संभावना है कि उपयोग किया जा रहा है।
हमें 2 मैच मिलते हैं (यदि पहला काम नहीं कर रहा है तो आपको दूसरे को आजमाना चाहिए)। पहला डाउनलोड करें:
libs/libc6_2.23-0ubuntu10_amd64/libc-2.23.so
से libc को हमारी कार्यशील निर्देशिका में कॉपी करें।
इस बिंदु पर हमें उपयोग की जाने वाली libc पुस्तकालय के बारे में पता होना चाहिए। चूंकि हम एक स्थानीय बाइनरी का शोषण कर रहे हैं, मैं बस उपयोग करूंगा: /lib/x86_64-linux-gnu/libc.so.6
तो, template.py
की शुरुआत में libc वेरिएबल को बदलें: libc = ELF("/lib/x86_64-linux-gnu/libc.so.6") #जब पता हो तो पुस्तकालय का पथ सेट करें
libc पुस्तकालय को पथ देने से शेष शोषण स्वचालित रूप से गणना किया जाएगा।
get_addr
फ़ंक्शन के अंदर libc का आधार पता गणना किया जाएगा:
ध्यान दें कि अंतिम libc बेस पता 00 पर समाप्त होना चाहिए। यदि ऐसा नहीं है, तो आप एक गलत पुस्तकालय लीक कर सकते हैं।
फिर, फ़ंक्शन system
का पता और स्ट्रिंग "/bin/sh" का पता libc के बेस पते से गणना किया जाएगा और libc पुस्तकालय दिया जाएगा।
अंत में, /bin/sh निष्पादन शोषण तैयार किया जा रहा है:
चलो इस अंतिम ROP को समझाते हैं।
अंतिम ROP (rop1
) ने फिर से मुख्य फ़ंक्शन को कॉल किया, फिर हम फिर से शोषण कर सकते हैं ओवरफ्लो (इसलिए OFFSET
यहाँ फिर से है)। फिर, हम POP_RDI
को कॉल करना चाहते हैं जो "/bin/sh" (BINSH
) के पते की ओर इशारा करता है और system फ़ंक्शन (SYSTEM
) को कॉल करते हैं क्योंकि "/bin/sh" का पता एक पैरामीटर के रूप में पास किया जाएगा।
अंत में, exit फ़ंक्शन का पता कॉल किया जाता है ताकि प्रक्रिया अच्छी तरह से समाप्त हो और कोई अलर्ट उत्पन्न न हो।
इस तरह शोषण एक _/bin/sh_** शेल को निष्पादित करेगा।**
आप ONE_GADGET का उपयोग करके system और "/bin/sh" के बजाय एक शेल प्राप्त कर सकते हैं। ONE_GADGET libc पुस्तकालय के अंदर एक शेल प्राप्त करने का एक तरीका खोजेगा जो केवल एक ROP पता का उपयोग करता है।
हालांकि, सामान्यतः कुछ सीमाएँ होती हैं, सबसे सामान्य और आसानी से बचने वाली सीमाएँ जैसे [rsp+0x30] == NULL
। चूंकि आप RSP के अंदर के मानों को नियंत्रित करते हैं, इसलिए आपको कुछ और NULL मान भेजने की आवश्यकता है ताकि सीमा से बचा जा सके।
आप इस कमजोरियों का फायदा उठाने के लिए एक टेम्पलेट यहाँ पा सकते हैं:
यदि "main" प्रतीक मौजूद नहीं है। तो आप यह पता कर सकते हैं कि मुख्य कोड कहाँ है:
और पते को मैन्युअल रूप से सेट करें:
यदि बाइनरी Puts का उपयोग नहीं कर रही है, तो आपको यह जांचना चाहिए कि क्या यह उपयोग कर रही है
sh: 1: %s%s%s%s%s%s%s%s: not found
यदि आप सभी एक्सप्लॉइट बनाने के बाद यह त्रुटि पाते हैं: sh: 1: %s%s%s%s%s%s%s%s: not found
तो "/bin/sh" के पते से 64 बाइट घटाने की कोशिश करें:
सीखें और AWS हैकिंग का अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE) सीखें और GCP हैकिंग का अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE)