hacktricks/binary-exploitation/heap/house-of-orange.md

9.5 KiB

Casa de Laranja

Aprenda hacking AWS do zero ao herói com htARTE (HackTricks AWS Red Team Expert)!

Outras maneiras de apoiar o HackTricks:

Informações Básicas

Código

Objetivo

  • Abusar da função malloc_printerr

Requisitos

  • Sobrescrever o tamanho do top chunk
  • Vazamentos de libc e heap

Contexto

Algumas informações necessárias dos comentários deste exemplo:

A questão é que, em versões mais antigas da libc, quando a função malloc_printerr era chamada, ela iterava por uma lista de estruturas _IO_FILE armazenadas em _IO_list_all, e realmente executava um ponteiro de instrução nessa estrutura.
Este ataque forjará uma estrutura _IO_FILE falsa que escreveremos em _IO_list_all, e fará com que malloc_printerr seja executado.
Então ele executará qualquer endereço que tivermos armazenado na tabela de saltos das estruturas _IO_FILE, e obteremos a execução de código

Ataque

O ataque começa gerenciando para obter o top chunk dentro do unsorted bin. Isso é alcançado chamando malloc com um tamanho maior que o tamanho atual do top chunk, mas menor que mmp_.mmap_threshold (o padrão é 128K), o que, de outra forma, acionaria a alocação mmap. Sempre que o tamanho do top chunk é modificado, é importante garantir que o top chunk + seu tamanho seja alinhado à página e que o bit prev_inuse do top chunk esteja sempre definido.

Para obter o top chunk dentro do unsorted bin, aloque um chunk para criar o top chunk, altere o tamanho do top chunk (com um estouro no chunk alocado) para que top chunk + tamanho seja alinhado à página com o bit prev_inuse definido. Em seguida, aloque um chunk maior que o novo tamanho do top chunk. Observe que free nunca é chamado para colocar o top chunk no unsorted bin.

O antigo top chunk agora está no unsorted bin. Supondo que podemos ler dados dentro dele (possivelmente devido a uma vulnerabilidade que também causou o estouro), é possível vazar endereços de libc a partir dele e obter o endereço de _IO_list_all.

Um ataque ao unsorted bin é realizado abusando do estouro para escrever topChunk->bk->fwd = _IO_list_all - 0x10. Quando um novo chunk é alocado, o antigo top chunk será dividido, e um ponteiro para o unsorted bin será escrito em _IO_list_all.

O próximo passo envolve reduzir o tamanho do antigo top chunk para caber em um small bin, especificamente definindo seu tamanho como 0x61. Isso serve a dois propósitos:

  1. Inserção no Small Bin 4: Quando malloc percorre o unsorted bin e vê este chunk, ele tentará inseri-lo no small bin 4 devido ao seu tamanho pequeno. Isso faz com que o chunk acabe na cabeça da lista do small bin 4, que é a localização do ponteiro FD do chunk de _IO_list_all já que escrevemos um endereço próximo em _IO_list_all via o ataque ao unsorted bin.
  2. Desencadeando uma Verificação de Malloc: Essa manipulação de tamanho do chunk causará malloc para realizar verificações internas. Quando ele verifica o tamanho do chunk falso à frente, que será zero, ele desencadeia um erro e chama malloc_printerr.

A manipulação do small bin permitirá controlar o ponteiro à frente do chunk. A sobreposição com _IO_list_all é usada para forjar uma estrutura fake _IO_FILE. A estrutura é cuidadosamente elaborada para incluir campos-chave como _IO_write_base e _IO_write_ptr definidos para valores que passam verificações internas na libc. Além disso, uma tabela de saltos é criada dentro da estrutura falsa, onde um ponteiro de instrução é definido para o endereço onde um código arbitrário (por exemplo, a função system) pode ser executado.

Para resumir a parte restante da técnica:

  • Reduza o Antigo Top Chunk: Ajuste o tamanho do antigo top chunk para 0x61 para encaixá-lo em um small bin.
  • Configure a Estrutura Fake _IO_FILE: Sobreponha o antigo top chunk com a estrutura fake _IO_FILE e defina os campos apropriadamente para sequestrar o fluxo de execução.

O próximo passo envolve forjar uma estrutura fake _IO_FILE que se sobrepõe ao antigo top chunk atualmente no unsorted bin. Os primeiros bytes desta estrutura são elaborados cuidadosamente para incluir um ponteiro para um comando (por exemplo, "/bin/sh") que será executado.

Campos-chave na estrutura fake _IO_FILE, como _IO_write_base e _IO_write_ptr, são definidos para valores que passam verificações internas na libc. Além disso, uma tabela de saltos é criada dentro da estrutura fake, onde um ponteiro de instrução é definido para o endereço onde um código arbitrário pode ser executado. Tipicamente, este seria o endereço da função system ou outra função que pode executar comandos shell.

O ataque culmina quando uma chamada para malloc desencadeia a execução do código através da estrutura _IO_FILE manipulada. Isso permite a execução de código arbitrário, resultando tipicamente em um shell sendo aberto ou outra carga maliciosa sendo executada.

Resumo do Ataque:

  1. Configure o top chunk: Aloque um chunk e modifique o tamanho do top chunk.
  2. Force o top chunk para o unsorted bin: Aloque um chunk maior.
  3. Vaze endereços de libc: Use a vulnerabilidade para ler do unsorted bin.
  4. Execute o ataque ao unsorted bin: Escreva em _IO_list_all usando um estouro.
  5. Reduza o antigo top chunk: Ajuste seu tamanho para encaixá-lo em um small bin.
  6. Configure uma estrutura fake _IO_FILE: Forje uma estrutura de arquivo falsa para sequestrar o fluxo de controle.
  7. Desencadeie a execução de código: Aloque um chunk para executar o ataque e executar código arbitrário.

Esta abordagem explora mecanismos de gerenciamento de heap, vazamentos de informações da libc e estouros de heap para alcançar a execução de código sem chamar diretamente free. Ao elaborar cuidadosamente a estrutura fake _IO_FILE e colocá-la na localização correta, o ataque pode sequestrar o fluxo de controle durante operações padrão de alocação de memória. Isso permite a execução de código arbitrário, potencialmente resultando em um shell ou outras atividades maliciosas.

Referências

Aprenda hacking AWS do zero ao herói com htARTE (HackTricks AWS Red Team Expert)!

Outras maneiras de apoiar o HackTricks: