Leaking libc address with ROP
त्वरित सारांश
ओवरफ्लो ऑफसेट खोजें
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
ROP - LIBC पता लगाने का टेम्पलेट
एक्सप्लॉइट डाउनलोड करें और इसे विकल्पी बाइनरी के समान निर्देशिका में रखें और स्क्रिप्ट को आवश्यक डेटा दें:
pageLeaking libc - template1- ऑफसेट खोजना
टेम्पलेट को एक ऑफसेट की आवश्यकता है जिसके बाद एक्सप्लॉइट के साथ जारी रखने के लिए। यदि कोई प्रदान किया जाता है तो यह उसे खोजने के लिए आवश्यक कोड का निष्पादन करेगा (डिफ़ॉल्ट रूप से OFFSET = ""
):
क्रियान्वित python template.py
एक GDB कन्सोल खुलेगा जिसमें कार्यक्रम क्रैश हो जाएगा। उस GDB कन्सोल में x/wx $rsp
क्रियान्वित करें ताकि RIP को ओवरराइट करने वाले बाइट्स प्राप्त हों। अंततः एक python कन्सोल का उपयोग करके ऑफसेट प्राप्त करें:
ऑफसेट (इस मामले में 40) पाने के बाद, उस मान का उपयोग करके टेम्पलेट के अंदर OFFSET वेरिएबल को बदलें।
OFFSET = "A" * 40
एक और तरीका हो सकता है: pattern create 1000
-- रिटर्न तक चलाएं -- pattern seach $rsp
GEF से।
2- गैजेट्स खोजना
अब हमें बाइनरी के अंदर ROP गैजेट्स खोजने की आवश्यकता है। ये ROP गैजेट्स puts
को कॉल करने के लिए उपयोगी होंगे libc को खोजने के लिए, और बाद में अंतिम धोखाधड़ी को लॉन्च करने के लिए।
PUTS_PLT
को फ़ंक्शन puts को कॉल करने के लिए आवश्यक है। MAIN_PLT
को मुख्य फ़ंक्शन को फिर से कॉल करने के लिए आवश्यक है एक इंटरेक्शन के बाद ओवरफ़्लो को फिर से शांत करने के लिए (असीमित दौरों के लिए शोषण)। हर ROP के अंत में प्रोग्राम को फिर से कॉल करने के लिए इस्तेमाल किया जाता है। POP_RDI को बुलाए गए फ़ंक्शन को पैरामीटर पास करने के लिए आवश्यक है।
इस चरण में आपको कुछ भी नहीं चलाने की आवश्यकता है क्योंकि पूटूल्स द्वारा निष्पादन के दौरान सभी चीजें मिल जाएंगी।
3- लिबसी पुस्तकालय खोजना
अब समय है पता लगाने का कि कौन सी libc पुस्तकालय का संस्करण उपयोग किया जा रहा है। इसके लिए हमें मेमोरी में फ़ंक्शन puts
का पता लगाना होगा और फिर हमें इस पते में कौन सा पुस्तकालय संस्करण है उसे खोजना होगा।
इसे करने के लिए, निष्पादित कोड की सबसे महत्वपूर्ण लाइन है:
यह कुछ बाइट भेजेगा जब तक RIP को ओवरराइट करना संभव हो: OFFSET
।
फिर, यह गैजेट POP_RDI
का पता सेट करेगा ताकि अगला पता (FUNC_GOT
) RDI रजिस्ट्री में सहेजा जाए। यह इसलिए है क्योंकि हमें puts को बुलाना है जिसे हम पास कर रहे हैं PUTS_GOT
का पता जैसे ही मेमोरी में puts फ़ंक्शन का पता PUTS_GOT
द्वारा पॉइंट करने वाले पते में सहेजा जाता है।
उसके बाद, PUTS_PLT
को बुलाया जाएगा (PUTS_GOT
के अंदर RDI के साथ) ताकि puts PUTS_GOT के अंदर कंटेंट पढ़ सके (मेमोरी में puts फ़ंक्शन का पता) और इसे प्रिंट करेगा।
अंत में, मुख्य फ़ंक्शन को फिर से बुलाया जाता है ताकि हम फिर से ओवरफ़्लो का शोषण कर सकें।
इस तरह हमने puts फ़ंक्शन को धोखा दिया है कि वह मेमोरी में puts फ़ंक्शन का पता प्रिंट करे (जो libc पुस्तकालय के अंदर है)। अब हमारे पास उस पते के साथ है तो हम खोज सकते हैं कि कौन सी libc संस्करण का उपयोग हो रहा है।
हम किसी स्थानीय बाइनरी का शोषण कर रहे हैं इसलिए यह आवश्यक नहीं है कि हमें यह जानने की आवश्यकता है कि कौन सा libc संस्करण उपयोग हो रहा है (केवल /lib/x86_64-linux-gnu/libc.so.6
में पुस्तकालय खोजें)।
लेकिन, दूरस्थ शोषण मामले में मैं यहाँ विवरण दूंगा कि आप इसे कैसे खोज सकते हैं:
3.1- libc संस्करण की खोज (1)
आप वेब पृष्ठ पर खोज सकते हैं कि कौन सी पुस्तकालय का उपयोग हो रहा है: https://libc.blukat.me/ यह आपको libc के खोजे गए संस्करण को डाउनलोड करने की भी अनुमति देगा।
3.2- libc संस्करण की खोज (2)
आप भी कर सकते हैं:
$ git clone https://github.com/niklasb/libc-database.git
$ cd libc-database
$ ./get
इसमें कुछ समय लगेगा, धैर्य रखें। इसके लिए काम करने के लिए हमें चाहिए:
Libc सिम्बल नाम:
puts
लीकेड libc पता:
0x7ff629878690
हम यह तय कर सकते हैं कि कौन सी libc उपयोग की जा रही है।
हमें 2 मैच मिलते हैं (अगर पहला काम नहीं कर रहा है तो आपको दूसरा प्रयास करना चाहिए)। पहला डाउनलोड करें:
3.3- लीक करने के लिए अन्य फ़ंक्शन
libs/libc6_2.23-0ubuntu10_amd64/libc-2.23.so
से libc की कॉपी हमारे काम करने के निर्देशिका में करें।
4- आधारित libc पता लगाना और उसका शोषण करना
इस बिंअरी का उपयोग करते समय हमें लिब्सी पुस्तकालय का पता होना चाहिए। मैं बस यहाँ प्रयोग करूंगा: /lib/x86_64-linux-gnu/libc.so.6
इसलिए, template.py
के शुरू में libc चर को बदलें: libc = ELF("/lib/x86_64-linux-gnu/libc.so.6") #Set library path when know it
libc पुस्तकालय के पथ देने से शोषण का शेष भाग स्वचालित रूप से होगा।
get_addr
फ़ंक्शन के भीतर libc का आधार पता लगाया जाएगा:
ध्यान दें कि अंतिम libc बेस पता 00 में समाप्त होना चाहिए। यदि ऐसा नहीं है तो आपने गलत पुस्तकालय का लीक किया हो सकता है।
फिर, सिस्टम फ़ंक्शन के पते और "/bin/sh" स्ट्रिंग के पते को गणना किया जाएगा libc के बेस पते से और दिए गए libc पुस्तकालय।
अंत में, /bin/sh निष्पादन उत्पीड़न तैयार किया जा रहा है भेजने के लिए:
Let's explain this final ROP.
आखिरी ROP (rop1
) फिर से मुख्य फ़ंक्शन को बुलाकर समाप्त हुआ, तो हम फिर से शोषण कर सकते हैं ओवरफ्लो (इसलिए OFFSET
यहाँ फिर से है)। फिर, हम "/bin/sh" के पते (BINSH
) को दिखाने के लिए POP_RDI
को बुलाना चाहते हैं और सिस्टम फ़ंक्शन (SYSTEM
) को बुलाना चाहते हैं क्योंकि "/bin/sh" का पता पैरामीटर के रूप में पास किया जाएगा।
अंत में, एग्ज़िट फ़ंक्शन का पता बुलाया जाता है ताकि प्रक्रिया अच्छे से समाप्त हो और कोई चेतावनी उत्पन्न न हो।
इस तरह शोषण एक _/bin/sh_** शैली को निष्पादित करेगा।**
4(2)- एक ONE_GADGET का उपयोग
आप ONE_GADGET का उपयोग करके एक शैली प्राप्त करने के लिए सिस्टम और "/bin/sh" का उपयोग करने की बजाय एक शैली प्राप्त कर सकते हैं। ONE_GADGET लिबीसी पुस्तकालय के अंदर एक ROP पता का उपयोग करके केवल एक शैली प्राप्त करने के लिए कुछ तरीका खोजेगा।
हालांकि, सामान्यत: कुछ प्रतिबंध होते हैं, सबसे सामान्य और आसान टालने वाले तरीके हैं जैसे [rsp+0x30] == NULL
जैसे आप RSP के मान को नियंत्रित करते हैं तो आपको और कुछ NULL मान भेजना होगा ताकि प्रतिबंध टाल दिया जाए।
एक्सप्लॉइट फ़ाइल
आप इस सुरक्षा दोष का शार्टकट यहाँ पा सकते हैं:
pageLeaking libc - templateसामान्य समस्याएँ
MAIN_PLT = elf.symbols['main'] नहीं मिला
यदि "main" प्रतीक मौजूद नहीं है। तो आप यहाँ मुख्य कोड कहाँ है पा सकते हैं:
और पता मैन्युअल रूप से सेट करें:
Puts नहीं मिला
यदि बाइनरी 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
यदि आप इस त्रुटि को पाते हैं जब आप सभी एक्सप्लॉइट बनाने के बाद: sh: 1: %s%s%s%s%s%s%s%s: not found
तो कोशिश करें "/bin/sh" के पते में 64 बाइट कम करें:
Last updated