The Forgotten Chunks

Glibc Adventures: The forgotten chunks é o título de um livro escrito por François Goichon, que pode ser acessado por meio de um repositório disponibilizado por bash-c.

Exploits

O livro detalha três exploits relacionados à heap: Extending Free Chunks, Extending Allocated Chunks, e Shrinking Free Chunks. Apesar de suas diferenças, esses três métodos resultam praticamente no mesmo objetivo: um chunk alocado dentro de outro também alocado.

Extending Free Chunks

Esse é o método mais simples para causar a sobreposição de chunks. Ele requer pelo menos 3 chunks adjacentes, a, b, e c, sendo que pelo menos um deles deve ser vulnerável a algum tipo de overflow.

Initial State

Uma vez com os 3 chunks alocados, conforme mostrado na imagem acima, o próximo passo é liberar o chunk do meio (b) e, em seguida, sobrescrever seus metadados. Isso envolve alterar pelo menos um byte do campo size do chunk, aumentando o tamanho registrado.

Overflow into B

Agora, ao alocar um novo chunk com o tamanho anterior (deve ser do tamanho anterior porque o chunk está na tcache bin), o gerenciador de memória retornará o chunk do meio junto com o chunk do final (c) e parte do espaço adjacente. Isso ocorre porque a função malloc() não verifica se o chunk liberado é consistente com o campo prev_size do próximo chunk.

C is overlapped

Extending Allocated Chunks

Esta técnica é semelhante à anterior, mas aqui exploramos o fato de que a função free() não verifica se o tamanho do chunk a ser liberado é consistente com o que foi alocado. O único local onde o tamanho do chunk é armazenado é no próprio campo size do chunk.

Assim como antes, precisamos de 3 chunks adjacentes, a, b e c, sendo necessário que pelo menos um deles seja vulnerável a algum tipo de overflow.

Initial state

Neste método, usamos um overflow para sobrescrever o campo size do chunk do meio (b) com um valor maior do que o tamanho real do chunk. Após isso, liberamos o chunk b e o alocamos novamente, especificando o tamanho alterado. Como resultado, o chunk final (c) será alocado dentro do chunk b.

C is overlapped

Shrinking Free Chunks

Esse método, diferentemente dos anteriores, envolve a redução do tamanho de um chunk em vez de aumentá-lo. Por ser mais complexo, ele exige um entendimento detalhado de como o gerenciador de heap funciona.

Assim como antes, precisamos de 3 chunks adjacentes, a, b e c, sendo que um deles deve ser vulnerável a um overflow.

Initial state

Uma vez com os chunks configurados, liberamos o chunk do meio (b), e, em seguida, usamos um overflow para alterar o seu tamanho.

Overflow into B

Depois, alocamos dois novos chunks, b1 e b2, que devem ser menores que o chunk original b. Isso faz com que b1 ocupe o início do espaço de b, enquanto b2 ocupa o espaço seguinte. Após isso, liberamos b1.

b1 is free

Por fim, liberamos o chunk final (c) para que ele se junte ao chunk do meio (b). Como o campo prev_size de c não foi atualizado, o gerenciador de memória acredita que b ainda é o chunk original. Por último, alocamos um chunk maior que abrange o espaço de c, causando a sobreposição.

B2 is overlapped

Referências

Glibc Adventures: The forgotten chunks Heap-Exploitation

Atualizado