WWW2Exec - .dtors & .fini_array
.dtors
आजकल किसी भी बाइनरी में .dtors सेक्शन के साथ एक बहुत अजीब चीज है!
डिस्ट्रक्टर्स वे फ़ंक्शन हैं जो प्रोग्राम समाप्त होने से पहले (जब main
फ़ंक्शन वापस लौटता है) क्रियान्वित होते हैं।
इन फ़ंक्शनों के पते बाइनरी के .dtors
सेक्शन में संग्रहीत होते हैं और इसलिए, यदि आप __DTOR_END__
में एक शैलकोड के पते को लिखने में सफल होते हैं, तो वह प्रोग्राम समाप्त होने से पहले क्रियान्वित हो जाएगा।
इस सेक्शन का पता प्राप्त करें:
.fini_array
मौलिक रूप से यह एक संरचना है जिसमें फ़ंक्शन होते हैं जो कार्यक्रम समाप्त होने से पहले कॉल किए जाएंगे, जैसे .dtors
। यह दिलचस्प है अगर आप अपने शैलकोड को एक पते पर जाकर कॉल कर सकते हैं, या उन मामलों में जहां आपको दोबारा main
पर जाने की आवश्यकता होती है ताकि आप सुरक्षा दोष का दूसरी बार शार्ट कर सकें।
ध्यान दें कि जब .fini_array
से एक फ़ंक्शन को निष्पादित किया जाता है, तो यह अगले फ़ंक्शन पर जाता है, इसलिए यह कई बार नहीं निष्पादित होगा (अनंत लूप को रोकना), लेकिन यह आपको यहाँ एक फ़ंक्शन के निष्पादन का केवल 1 बार देगा।
.fini_array
में प्रविष्टियों को उल्टे क्रम में बुलाया जाता है, इसलिए आपको संभावित रूप से आखिरी से लिखना चाहिए।
अनंत लूप
अनंत लूप प्राप्त करने के लिए .fini_array
का दुरुपयोग करने के लिए आप यहाँ क्या किया गया था देखें: यदि आपके पास कम से कम 2 प्रविष्टियाँ .fini_array
में हैं, तो आप:
अपनी पहली लेखन का उपयोग करें विकल्पी लेखन फ़ंक्शन को बुलाने के लिए फिर से
फिर,
__libc_csu_fini
द्वारा संग्रहित स्टैक में वापसी पता करें (जो सभी.fini_array
फ़ंक्शनों को बुलाने वाला फ़ंक्शन है) और वहाँ__libc_csu_fini
का पता डालेंयह
__libc_csu_fini
को फिर से बुलाएगा और.fini_array
फ़ंक्शनों को फिर से निष्पादित करेगा जो विकल्पी WWW फ़ंक्शन को 2 बार बुलाएगा: एक बार के लिए विकल्पी लेखन और एक और बार__libc_csu_fini
के वापसी पते को फिर से ओवरराइट करने के लिए स्टैक पर अपने आप को बुलाने के लिए।
ध्यान दें कि पूर्ण RELRO** के साथ, खंड .fini_array
को केवल पढ़ने योग्य बनाया जाता है।
link_map
जैसा कि इस पोस्ट में समझाया गया है, यदि कार्यक्रम return
या exit()
का उपयोग करके बाहर निकलता है, तो यह __run_exit_handlers()
को चलाएगा जो पंजीकृत नाशकों को बुलाएगा।
यदि कार्यक्रम _exit()
फ़ंक्शन का उपयोग करके बाहर निकलता है, तो यह exit
सिस्टम कॉल को बुलाएगा और बाहर निकालने वाले हैंडलर निष्पादित नहीं होंगे। इसलिए, __run_exit_handlers()
को निष्पादित होने की पुष्टि करने के लिए आप उस पर एक ब्रेकपॉइंट सेट कर सकते हैं।
महत्वपूर्ण कोड है (स्रोत):
नोट करें कि map -> l_addr + fini_array -> d_un.d_ptr
का उपयोग फ़ंक्शन के एरे की स्थिति की गणना के लिए किया जाता है।
कुछ विकल्प हैं:
map->l_addr
के मान को ओवरराइट करें ताकि यह एक नकलीfini_array
की ओर पहुंचे जिसमें अनियंत्रित कोड को निष्पादित करने के निर्देश हों।l_info[DT_FINI_ARRAY]
औरl_info[DT_FINI_ARRAYSZ]
प्रविष्टियों के मान को ओवरराइट करें (जो स्मृति में अधिकांशत: संयुक्त हैं), ताकि वे फिर से एक जालीElf64_Dyn
संरचना की ओर पहुंचें जो फिर सेarray
को एक स्मृति क्षेत्र की ओर दिखाए जिसे हमलावर नियंत्रित करता है।
पिछले कोड के अनुसरन आपको एक और दिलचस्प खंड मिलेगा जिसमें कोड है:
इस मामले में map->l_info[DT_FINI]
के मान को ओवरराइट करना संभव होगा जो एक जाली ElfW(Dyn)
संरचना को दिखा रहा है। यहाँ अधिक जानकारी प्राप्त करें.
__run_exit_handlers
में TLS-स्टोरेज dtor_list ओवरराइट
__run_exit_handlers
में TLS-स्टोरेज dtor_list ओवरराइटजैसा यहाँ स्पष्ट किया गया है, अगर कोई प्रोग्राम return
या exit()
के माध्यम से बंद होता है, तो यह __run_exit_handlers()
को निष्पादित करेगा जो किसी भी नष्टकर्ता कार्य को कॉल करेगा जो पंजीकृत है।
कोड _run_exit_handlers()
से:
कोड से __call_tls_dtors()
:
हर पंजीकृत फ़ंक्शन के लिए tls_dtor_list
में, यह cur->func
से पॉइंटर को डीमैंगल करेगा और इसे cur->obj
के साथ कॉल करेगा।
इस GEF के fork से tls
फ़ंक्शन का उपयोग करके, यह संभव है कि वास्तव में dtor_list
बहुत क्लोज है stack canary और PTR_MANGLE cookie के पास। इसलिए, इस पर ओवरफ़्लो होने पर cookie और stack canary को ओवरराइट किया जा सकता है।
PTR_MANGLE कुकी को ओवरराइट करने से, PTR_DEMANLE
फ़ंक्शन को बाईपास किया जा सकता है क्योंकि इसे 0x00 पर सेट करने से यह अर्थ होगा कि वास्तविक पता प्राप्त करने के लिए उपयोग किया गया xor
केवल पता कॉन्फ़िगर किया गया है। फिर, dtor_list
पर लिखने से यह संभव है कि फ़ंक्शन पता और इसके विवाद के साथ कई फ़ंक्शनों को चेन किया जा सकता है।
अंत में ध्यान दें कि स्टोर किया गया पॉइंटर केवल कुकी के साथ xored होने वाला है बल्कि 17 बिट घुमाया जाएगा:
So you need to take this into account before adding a new address.
Find an example in the original post.
अन्य मैंगल्ड पॉइंटर __run_exit_handlers
में
__run_exit_handlers
मेंयह तकनीक यहाँ समझाई गई है और फिर से कार्यक्रम return
या exit()
को बुलाकर बाहर निकलने पर निर्भर है ताकि __run_exit_handlers()
को बुलाया जाए।
इस फ़ंक्शन को और अधिक कोड देखते हैं:
चर f
initial
संरचना को दर्शाता है और f->flavor
के मान के आधार पर विभिन्न फ़ंक्शन को कॉल किया जाएगा।
मान के आधार पर, कॉल करने के लिए फ़ंक्शन का पता एक विभिन्न स्थान पर होगा, लेकिन यह हमेशा demangled होगा।
इसके अतिरिक्त, विकल्प ef_on
और ef_cxa
में एक आर्ग्यूमेंट को भी नियंत्रित किया जा सकता है।
डीबगिंग सत्र में GEF चलाते समय gef> p initial
के साथ initial
संरचना की जांच की जा सकती है।
इसे उपयोग करने के लिए आपको या तो PTR_MANGLE
कुकी को लीक करना होगा या मिटाना होगा और फिर system('/bin/sh')
के साथ cxa
प्रविष्टि को ओवरराइट करना होगा।
आप इसका एक उदाहरण तकनीक के बारे में मूल ब्लॉग पोस्ट में देख सकते हैं।
Last updated