GNU obstack function-pointer hijack

Tip

Ucz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Ucz się i ćwicz Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Wsparcie dla HackTricks

Przegląd

GNU obstacks osadzają stan alokatora razem z dwoma celami wywołań pośrednich:

  • chunkfun (offset +0x38) z sygnaturą void *(*chunkfun)(void *, size_t)
  • freefun (offset +0x40) z sygnaturą void (*freefun)(void *, void *)
  • extra_arg oraz flaga use_extra_arg wybierają, czy _obstack_newchunk wywoła chunkfun(new_size) czy chunkfun(extra_arg, new_size)

Jeśli atakujący może uszkodzić aplikacyjny struct obstack * lub jego pola, następny wzrost obstacka (gdy next_free == chunk_limit) wywołuje pośrednie wywołanie przez chunkfun, umożliwiając prymitywy wykonywania kodu.

Primitive: size_t desync → 0-byte allocation → pointer OOB write

Częstym wzorcem błędu jest użycie 32-bitowego rejestru do obliczenia sizeof(ptr) * count, podczas gdy logiczna długość jest zapisywana w 64-bitowym size_t.

  • Przykład: elements = obstack_alloc(obs, sizeof(void *) * size); jest skompilowane jako SHL EAX,0x3 dla size << 3.
  • Przy size = 0x20000000 i sizeof(void *) = 8 mnożenie zawija się do 0x0 w 32-bit, więc tablica wskaźników ma 0 bytes, ale zapisana wartość size pozostaje 0x20000000.
  • Kolejne zapisy elements[curr++] = ptr; powodują 8-byte OOB pointer stores do sąsiednich heap objects, dając kontrolowane nadpisanie między obiektami.

Leaking libc via obstack.chunkfun

  1. Umieść dwa heap objects obok siebie (np. dwa stosy zbudowane oddzielnymi obstacks).
  2. Wykorzystaj pointer-array OOB write z obiektu A, aby nadpisać wskaźnik elements obiektu B tak, że pop/odczyt z B będzie dereferencjonował adres wewnątrz obstacka obiektu A.
  3. Odczytaj chunkfun (malloc domyślnie) na offsetcie 0x38, aby ujawnić wskaźnik funkcji libc, następnie oblicz libc_base = leak - malloc_offset i wyprowadź inne symbole (np. system, "/bin/sh").

Hijacking chunkfun with a fake obstack

Nadpisz przechowywany u ofiary struct obstack *, aby wskazywał na dane kontrolowane przez atakującego, które imitują nagłówek obstacka. Minimalne pola potrzebne:

  • next_free == chunk_limit aby wymusić _obstack_newchunk przy następnym push
  • chunkfun = system_addr
  • extra_arg = binsh_addr, use_extra_arg = 1 aby wybrać formę wywołania z dwoma argumentami

Następnie wywołaj alokację na obstacku ofiary, aby wykonać system("/bin/sh") poprzez pośrednie wywołanie.

Przykładowy fałszywy układ obstacka (glibc 2.42 offsets):

fake  = b""
fake += p64(0x1000)          # chunk_size
fake += p64(heap_leak)       # chunk
fake += p64(heap_leak)       # object_base
fake += p64(heap_leak)       # next_free == chunk_limit
fake += p64(heap_leak)       # chunk_limit
fake += p64(0xF)             # alignment_mask
fake += p64(0)               # temp
fake += p64(system_addr)     # chunkfun
fake += p64(0)               # freefun
fake += p64(binsh_addr)      # extra_arg
fake += p64(1)               # use_extra_arg flag set

Przepis ataku

  1. Wywołaj size wrap, aby utworzyć 0-byte pointer array o ogromnej logicznej długości.
  2. Groom adjacency, tak aby OOB zapis wskaźnika dosięgnął sąsiedniego obiektu zawierającego obstack pointer.
  3. Leak libc przez przekierowanie victim pointer do sąsiedniego obstack’s chunkfun i odczytanie function pointer.
  4. Forge obstack data z kontrolowanym chunkfun/extra_arg i zmuś _obstack_newchunk, aby wylądował w sfałszowanym nagłówku, co spowoduje wywołanie function-pointer według wyboru atakującego.

Referencje

Tip

Ucz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Ucz się i ćwicz Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Wsparcie dla HackTricks