GNU obstack function-pointer hijack

Tip

Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprenda e pratique Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporte o HackTricks

Visão geral

GNU obstacks incorporam o estado do alocador juntamente com dois alvos de chamada indireta:

  • chunkfun (offset +0x38) com assinatura void *(*chunkfun)(void *, size_t)
  • freefun (offset +0x40) com assinatura void (*freefun)(void *, void *)
  • extra_arg e uma flag use_extra_arg selecionam se _obstack_newchunk chama chunkfun(new_size) ou chunkfun(extra_arg, new_size)

Se um atacante puder corromper um struct obstack * pertencente à aplicação ou seus campos, o próximo crescimento do obstack (quando next_free == chunk_limit) dispara uma chamada indireta através de chunkfun, permitindo primitivas de execução de código.

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

Um padrão de bug comum é usar um registrador de 32-bit para calcular sizeof(ptr) * count enquanto armazena o comprimento lógico em um size_t de 64-bit.

  • Exemplo: elements = obstack_alloc(obs, sizeof(void *) * size); é compilado como SHL EAX,0x3 para size << 3.
  • Com size = 0x20000000 e sizeof(void *) = 8, a multiplicação transborda para 0x0 em 32-bit, então o array de ponteiros tem 0 bytes, mas o size registrado permanece 0x20000000.
  • As escritas subsequentes elements[curr++] = ptr; realizam armazenamentos de ponteiros OOB de 8 bytes em objetos heap adjacentes, fornecendo uma primitiva de sobrescrita cross-object controlada.

Leaking libc via obstack.chunkfun

  1. Coloque dois objetos heap adjacentes (por exemplo, duas stacks construídas com obstacks separadas).
  2. Use o write OOB do array de ponteiros do objeto A para sobrescrever o ponteiro elements do objeto B de modo que um pop/leitura de B desreferencie um endereço dentro do obstack do objeto A.
  3. Leia chunkfun (malloc por padrão) no offset 0x38 para divulgar um ponteiro de função libc, então calcule libc_base = leak - malloc_offset e derive outros símbolos (por exemplo, system, "/bin/sh").

Hijacking chunkfun with a fake obstack

Sobrescreva o struct obstack * armazenado da vítima para apontar para dados controlados pelo atacante que imitam o cabeçalho do obstack. Campos mínimos necessários:

  • next_free == chunk_limit para forçar _obstack_newchunk no próximo push
  • chunkfun = system_addr
  • extra_arg = binsh_addr, use_extra_arg = 1 para selecionar a forma de chamada com dois argumentos

Então dispare uma alocação no obstack da vítima para executar system("/bin/sh") através da chamada indireta.

Exemplo de layout de obstack falso (offsets 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

Receita de ataque

  1. Trigger size wrap para criar um array de ponteiros de 0 bytes com um comprimento lógico enorme.
  2. Groom adjacency para que uma escrita de ponteiro OOB alcance um objeto vizinho contendo um ponteiro obstack.
  3. Leak libc redirecionando um ponteiro da vítima para o chunkfun do obstack vizinho e lendo o ponteiro de função.
  4. Forge obstack dados com chunkfun/extra_arg controlados e forçar _obstack_newchunk a cair no cabeçalho forjado, resultando em uma chamada de ponteiro de função à escolha do atacante.

Referências

Tip

Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprenda e pratique Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporte o HackTricks