WWW2Exec - atexit()
Last updated
Last updated
AWS हैकिंग सीखें और प्रैक्टिस करें:HackTricks प्रशिक्षण AWS रेड टीम एक्सपर्ट (ARTE) GCP हैकिंग सीखें और प्रैक्टिस करें: HackTricks प्रशिक्षण GCP रेड टीम एक्सपर्ट (GRTE)
आजकल इसे एक्सप्लॉइट करना बहुत अजीब है!
atexit()
एक कार्य है जिसमें अन्य कार्यों को पैरामीटर के रूप में पास किया जाता है। ये कार्य एक exit()
या मुख्य के वापसी को चलाएगा।
यदि आप किसी भी इन कार्यों के पते को एक शैलकोड पर पॉइंट करने के लिए संशोधित कर सकते हैं, तो आप प्रक्रिया का नियंत्रण प्राप्त करेंगे, लेकिन यह वर्तमान में अधिक जटिल है।
वर्तमान में कार्यों के पतों को निष्क्रिय करने के लिए कई संरचनाओं के पीछे छिपा हुआ है और अंत में जिस पते पर यह पॉइंट करता है, वह कार्यों के पतों के पते नहीं हैं, बल्कि XOR और एक रैंडम कुंजी के साथ एन्क्रिप्टेड हैं। इसलिए वर्तमान में यह हमला वेक्टर कम उपयोगी है कम से कम x86 और x64_86 पर।
एन्क्रिप्शन कार्य है PTR_MANGLE
। अन्य आर्किटेक्चर जैसे m68k, mips32, mips64, aarch64, arm, hppa... इस एन्क्रिप्शन कार्य को लागू नहीं करते क्योंकि यह वही वापस उसे प्राप्त हुआ जैसा इनपुट था। इसलिए इन आर्किटेक्चर्स पर यह वेक्टर से हमला किया जा सकता है।
आप इसके काम करने की गहराई में व्याख्या https://m101.github.io/binholic/2017/05/20/notes-on-abusing-exit-handlers.html में पा सकते हैं।
जैसा कि इस पोस्ट में स्पष्ट किया गया है, यदि कार्यक्रम 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
को एक स्मृति क्षेत्र पर प्वाइंट करेगी जिसे हमलावर नियंत्रित करता है।
इस व्रिटअप l_info[DT_FINI_ARRAY]
को एक नियंत्रित स्मृति में स्थित .bss
में एक जाली fini_array
के पते के साथ ओवरराइट करता है। यह जाली अर्रे में पहले एक वन गैजेट पता शामिल है जो निष्पादित किया जाएगा और फिर इस जाली अर्रे और map->l_addr
के मान के बीच का अंतर जिससे *array
नकली अर्रे पर प्वाइंट करेगा।
इस तकनीक के मुख्य पोस्ट और इस व्रिटअप के अनुसार ld.so एक पॉइंटर को स्टैक पर छोड़ देता है जो ld.so में बाइनरी link_map
की ओर पॉइंट करता है। एक अर्बिट्रेरी राइट के साथ इसे ओवरराइट करना संभव है और इसे एक हमलावर द्वारा नियंत्रित नकली fini_array
की ओर पॉइंट करना है जिसमें एक वन गैजेट के पते को उदाहरण के लिए।
पिछले कोड के अनुसरण में आप एक और दिलचस्प खंड पा सकते हैं जिसमें कोड है:
इस मामले में map->l_info[DT_FINI]
के मान को ओवरराइट करना संभव होगा जो एक जाली ElfW(Dyn)
संरचना को दर्शाता है। यहाँ अधिक जानकारी प्राप्त करें.
__run_exit_handlers
जैसा यहाँ स्पष्ट किया गया है, यदि कोई प्रोग्राम 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 कुकी को ओवरराइट करने से, इसे 0x00 पर सेट करके PTR_DEMANLE
फ़ंक्शन को बाईपास किया जा सकता है, जिससे कि वास्तविक पता प्राप्त करने के लिए उपयोग किया गया 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
में अन्य मैंगल्ड पॉइंटरयह तकनीक यहाँ समझाई गई है और फिर से कार्यक्रम 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
प्रविष्टि को ओवरराइट करना होगा।
आप इसका एक उदाहरण तकनीक के बारे में मूल ब्लॉग पोस्ट में देख सकते हैं।