Quais ataques de corrupção de memória além do buffer overflow existem?
Este tutorial faz parte do GUIA COMPLETO do professional em Segurança Ofensiva de Software, saiba mais.
Aula 23: Outras corrupções de memória
As vulnerabilidades de corrupção de memória continuam sendo uma das classes de falhas de segurança mais exploradas. Dentro deste cenário, o Heap Buffer Overflow e a falha em String de Formatação se destacam como métodos poderosos para sequestrar o fluxo de execução de um programa. Embora não entraremos em detalhes na exploração dessas vulnerabilidades, abaixo você confere uma breve introdução sobre cada uma delas. Caso deseja aprofundar no tema abordado, recomendamos realizar os desafios Phoenix apresentados no site Exploit Education.
Aula 23.1: Heap
O Heap é a área de memória alocada dinamicamente, crescendo do menor endereço para o maior e frequentemente usada para variáveis globais e estruturas de dados complexas, em contraste com a Stack (Pilha), que é usada para variáveis locais de função.
Assim, a vulnerabilidade de Heap Buffer Overflow (transbordamento de buffer no Heap) ocorre quando uma entrada de usuário excede o tamanho do bloco de memória que lhe foi alocado no Heap. Ao extrapolar o limite, os dados do atacante sobrescrevem informações adjacentes na memória.
O ataque se torna crítico quando o buffer transbordado está localizado imediatamente antes de dados importantes, como um ponteiro para função. Ponteiros de função são comumente utilizados na arquitetura de bibliotecas dinâmicas do sistema operacional. O sistema usa uma tabela com símbolos e endereços das funções de bibliotecas (como a função printf) para realizar chamadas.
O ataque envolve os seguintes passos:
![]() |
Figura 1: Heap Buffer Overflow |
- O atacante envia uma entrada de dados maliciosa que é maior do que o buffer alocado.
- Essa entrada sobrescreve o ponteiro de função adjacente no Heap.
- O atacante substitui o endereço original da função legítima pelo endereço contendo um código malicioso (shellcode).
- Quando o programa tenta chamar a função original, o fluxo de execução é desviado para o shellcode, sequestrando o controle do programa.
Aula 23.2: Format String
A vulnerabilidade de Format String (falha em String de Formatação) é uma técnica considerada um pouco mais complexa de se executar do que um Buffer Overflow simples. A vulnerabilidade surge em funções que manipulam strings (como as da família printf na linguagem C) quando o programador permite que uma entrada de usuário seja usada diretamente na string de formatação, sem nenhum tipo de tratativa.
![]() |
Figura 2: exemplo de código em C |
Isso permite ao atacante injetar diretamente na entrada, strings de formatação que possam ser interpretadas maliciosamente pelo programa.
No padrão ANSI C, diversas funções são vulneráveis se não usadas corretamente, pois são utilizadas para converter tipos de dados C para representação de string. Abaixo você vê algumas das funções de formatação de string em C:
- printf: Imprime para a stream 'stdout'.
- fprintf: Imprime para uma stream FILE.
- sprintf: Imprime em uma string.
- snprintf: Imprime em uma string com verificação de limite de tamanho.
- Outras:
- vfprintf, vprintf, vsprintf, vsnprintf, setproctitle, syslog, err*, verr*, warn*, vwarn*
Um atacante pode explorar a falha em String de Formatação de duas maneiras principais:
- Leitura de Memória:
- O especificador %x permite imprimir valores da pilha de execução do programa, para encontrar o offset (deslocamento) de exploração.
- O %s permite visualizar de forma arbitrária a memória a partir de um endereço escolhido até encontrar um byte nulo.
- Escrita de Memória:
- O %n tem a função de escrever na memória. Ele grava no endereço de memória fornecido, o número de bytes que já foram impressos pela função de formatação.
- O atacante insere na string de entrada o endereço de memória alvo que deseja modificar (por exemplo, o endereço de retorno da função).
- Em seguida, ele utiliza o especificador %n em conjunto com especificadores de largura, para forçar a impressão de um número exato de bytes.
- O número de bytes impresso é, na verdade, o valor que o atacante deseja escrever no endereço alvo. Ao redirecionar o fluxo de execução, o atacante ganha o controle total do programa.