Heap Overflow
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Um heap overflow é como um stack overflow mas no heap. Basicamente, isso 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.
Em stack overflows, sabemos que alguns registradores, como o ponteiro de instrução ou o quadro de pilha, serão restaurados da pilha e pode ser possível abusar disso. No caso de heap overflows, não há nenhuma informação sensível armazenada por padrão no chunk do heap que pode ser transbordado. No entanto, pode haver informações sensíveis ou ponteiros, então a criticidade dessa vulnerabilidade depende de quais dados podem ser sobrescritos e como um atacante poderia abusar disso.
Para encontrar offsets de overflow, você pode usar os mesmos padrões que em stack overflows.
Em stack overflows, a disposiçã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 semelhante de dados 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 heap overflow, a memória usada não é linear, mas chunks alocados geralmente estão em posições separadas da memória (não um ao lado do outro) devido a bins e zonas que separam alocações por tamanho e porque memória previamente liberada é usada antes de alocar novos chunks. É complicado saber qual objeto estará colidindo com o vulnerável a um heap overflow. Portanto, quando um heap overflow é encontrado, é necessário encontrar uma maneira confiável de fazer o objeto desejado estar próximo na memória do que pode ser transbordado.
Uma das técnicas usadas para isso é Heap Grooming, que é usada, por exemplo, neste post. No post, é explicado como, quando no kernel do iOS, quando uma zona fica sem memória para armazenar chunks de memória, ela a expande por uma página do kernel, e essa página é dividida em chunks dos tamanhos esperados que seriam usados em ordem (até a versão 9.2 do iOS, depois esses chunks são usados de maneira aleatória para dificultar a exploração desses ataques).
Portanto, no post anterior onde um heap overflow está acontecendo, para forçar o objeto transbordado a colidir com uma ordem de vítima, vários kallocs
são forçados por várias threads para tentar garantir que todos os chunks 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 da linha associada a um mach port do iOS é um candidato ideal. Ao elaborar o tamanho da mensagem, é possível especificar exatamente o tamanho da alocação kalloc
e, quando o mach port correspondente é destruído, a alocação correspondente será imediatamente liberada de volta para kfree
.
Então, alguns desses espaços reservados podem ser liberados. A lista livre kalloc.4096
libera elementos em uma ordem de último a primeiro (last-in-first-out), o que basicamente significa que se alguns espaços reservados forem liberados e a exploração tentar alocar vários objetos de vítima enquanto tenta alocar o objeto vulnerável ao overflow, é provável que esse objeto seja seguido por um objeto de vítima.
Nesta página é possível encontrar uma emulação básica de Heap overflow que mostra como sobrescrever o bit prev in use do próximo chunk e a posição do tamanho prev é possível consolidar um chunk usado (fazendo-o pensar que está não utilizado) e então alocá-lo novamente, sendo capaz de sobrescrever dados que estão sendo usados em um ponteiro diferente também.
Outro exemplo do protostar heap 0 mostra um exemplo muito básico de um CTF onde um heap overflow pode ser abusado para chamar a função vencedora para obter a bandeira.
No exemplo do protostar heap 1 é possível ver como abusar de um buffer overflow é possível sobrescrever em um chunk próximo um endereço onde dados arbitrários do usuário serão escritos.
Na página https://8ksec.io/arm64-reversing-and-exploitation-part-1-arm-instruction-set-simple-heap-overflow/ você pode encontrar um exemplo de heap overflow onde um comando que será executado é armazenado no seguinte chunk do chunk transbordado. Assim, é possível modificar o comando executado sobrescrevendo-o com uma exploração fácil, como:
Usamos uma vulnerabilidade de Integer Overflow para obter um Heap Overflow.
Corrompemos ponteiros para uma função dentro de um struct
do chunk transbordado para definir uma função como system
e obter execução de código.
Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE) Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)