GNU obstack function-pointer hijack

Tip

Impara e pratica il hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Impara e pratica il hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporta HackTricks

Panoramica

GNU obstacks incorporano lo stato dell’allocatore insieme a due target di chiamata indiretta:

  • chunkfun (offset +0x38) con la firma void *(*chunkfun)(void *, size_t)
  • freefun (offset +0x40) con la firma void (*freefun)(void *, void *)
  • extra_arg e un flag use_extra_arg selezionano se _obstack_newchunk chiama chunkfun(new_size) oppure chunkfun(extra_arg, new_size)

Se un attacker può corrompere un struct obstack * posseduto dall’applicazione o i suoi campi, la successiva espansione dell’obstack (quando next_free == chunk_limit) attiva una chiamata indiretta tramite chunkfun, abilitando primitive di esecuzione di codice.

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

Un pattern di bug comune è usare un registro a 32 bit per calcolare sizeof(ptr) * count mentre la lunghezza logica viene memorizzata in un size_t a 64 bit.

  • Esempio: elements = obstack_alloc(obs, sizeof(void *) * size); viene compilato come SHL EAX,0x3 per size << 3.
  • Con size = 0x20000000 e sizeof(void *) = 8, la moltiplicazione va in wrap su 32 bit a 0x0, quindi l’array di puntatori è 0 bytes, ma la size registrata rimane 0x20000000.
  • Successive scritture elements[curr++] = ptr; effettuano store di puntatori OOB da 8 byte in oggetti heap adiacenti, fornendo una primitive di overwrite cross-object controllata.

Leaking libc via obstack.chunkfun

  1. Posiziona due oggetti heap adiacenti (es. due stack costruiti con obstacks separati).
  2. Usa il pointer-array OOB write dall’oggetto A per sovrascrivere il puntatore elements dell’oggetto B in modo che un pop/read da B dereferenzi un indirizzo all’interno dell’obstack di A.
  3. Leggi chunkfun (malloc di default) all’offset 0x38 per ottenere un puntatore a funzione libc, quindi calcola libc_base = leak - malloc_offset e deriva altri simboli (es. system, "/bin/sh").

Dirottamento di chunkfun con un fake obstack

Sovrascrivi il struct obstack * della vittima per puntare a dati controllati dall’attacker che imitano l’header dell’obstack. Campi minimi necessari:

  • next_free == chunk_limit per forzare _obstack_newchunk alla prossima push
  • chunkfun = system_addr
  • extra_arg = binsh_addr, use_extra_arg = 1 per selezionare la forma di chiamata a due argomenti

Poi triggera un’allocazione sull’obstack della vittima per eseguire system("/bin/sh") tramite la chiamata indiretta.

Esempio di layout di fake obstack (offset glibc 2.42):

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

Ricetta d’attacco

  1. Trigger size wrap per creare un array di puntatori di 0 byte con una lunghezza logica enorme.
  2. Groom adjacency in modo che un OOB pointer store raggiunga un neighbor object contenente un obstack pointer.
  3. Leak libc reindirizzando un victim pointer al chunkfun del neighbor obstack e leggendo il function pointer.
  4. Forge obstack dati con chunkfun/extra_arg controllati e forzare _obstack_newchunk a finire nell’header falsificato, producendo una chiamata a function-pointer a scelta dell’attacker.

Riferimenti

Tip

Impara e pratica il hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Impara e pratica il hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporta HackTricks