Heap Overflow

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

Um heap overflow é como um estouro de pilha mas no heap. Basicamente significa que algum espaço foi reservado no heap para armazenar alguns dados e os dados armazenados eram maiores do que o espaço reservado.

Nos estouros de pilha sabemos que alguns registradores como o ponteiro de instrução ou o quadro de pilha serão restaurados da pilha e poderia ser possível abusar disso. No caso de estouros de heap, não há nenhuma informação sensível armazenada por padrão no pedaço de heap que pode ser estourado. No entanto, poderia ser informações sensíveis ou ponteiros, então a criticidade dessa vulnerabilidade depende de quais dados podem ser sobrescritos e de como um atacante poderia abusar disso.

Para encontrar deslocamentos de estouro, você pode usar os mesmos padrões que em estouros de pilha.

Estouros de Pilha vs Estouros de Heap

Nos estouros de pilha, a organização e os dados que estarão presentes na pilha no momento em que a vulnerabilidade pode ser acionada são bastante confiáveis. Isso ocorre porque a pilha é linear, sempre aumentando em memória colidida, em lugares específicos da execução do programa a memória da pilha geralmente armazena um tipo de dados semelhante e tem uma estrutura específica com alguns ponteiros no final da parte da pilha usada por cada função.

No entanto, no caso de um estouro de heap, porque a memória usada não é linear mas os pedaços alocados geralmente estão em posições separadas da memória (não um ao lado do outro) por causa de bins e zonas que separam alocações por tamanho e porque a memória anterior liberada é usada antes de alocar novos pedaços. É complicado saber qual objeto vai colidir com o vulnerável a um estouro de heap. Portanto, quando um estouro de heap é encontrado, é necessário encontrar uma maneira confiável de fazer com que o objeto desejado esteja próximo na memória do que pode ser estourado.

Uma das técnicas usadas para isso é o Heap Grooming que é usado, por exemplo, neste post. No post é explicado como no kernel do iOS quando uma zona fica sem memória para armazenar pedaços de memória, ela é expandida por uma página do kernel, e esta página é dividida em pedaços dos tamanhos esperados que seriam usados em ordem (até a versão do iOS 9.2, então esses pedaços são usados de forma randomizada para dificultar a exploração desses ataques).

Portanto, no post anterior onde ocorre um estouro de heap, para forçar o objeto estourado a colidir com uma ordem vítima, vários kallocs são forçados por várias threads para tentar garantir que todos os pedaços livres sejam preenchidos e que uma nova página seja criada.

Para forçar esse preenchimento com objetos de um tamanho específico, a alocação fora de linha associada a uma porta mach iOS é um candidato ideal. Ao criar o tamanho da mensagem, é possível especificar exatamente o tamanho da alocação kalloc e quando a porta mach correspondente é destruída, a alocação correspondente será imediatamente liberada de volta para kfree.

Então, alguns desses espaços reservados podem ser liberados. A lista de liberação kalloc.4096 libera elementos em uma ordem de último a primeiro, o que basicamente significa que se alguns espaços reservados forem liberados e o exploit tentar alocar vários objetos vítimas enquanto tenta alocar o objeto vulnerável ao estouro, é provável que este objeto seja seguido por um objeto vítima.

Exemplo ARM64

Na página https://8ksec.io/arm64-reversing-and-exploitation-part-1-arm-instruction-set-simple-heap-overflow/ você pode encontrar um exemplo de estouro de heap onde um comando que será executado é armazenado no pedaço seguinte ao pedaço estourado. Portanto, é possível modificar o comando executado sobrescrevendo-o com um exploit simples como:

python3 -c 'print("/"*0x400+"/bin/ls\x00")' > hax.txt
Aprenda hacking AWS do zero ao herói com htARTE (HackTricks AWS Red Team Expert)!

Outras maneiras de apoiar o HackTricks:

Last updated