Buffer overflow: o que é, como funciona e técnicas de prevenção
Buffer overflow: o que é, como funciona e técnicas de prevenção
Introdução
Buffer overflow (transbordamento de buffer) é uma vulnerabilidade de segurança que ocorre quando um programa grava dados além do limite de memória reservado para um buffer, sobrescrevendo regiões adjacentes de memória. Essa sobrescrita pode corromper dados, provocar falhas na aplicação ou, no cenário mais crítico, permitir que um atacante execute código arbitrário no sistema alvo.
Apesar de ser uma classe de vulnerabilidade conhecida há mais de três décadas, buffer overflow contínua sendo uma das causas mais frequentes de CVEs críticos publicados anualmente. De acordo com dados do MITRE e do NIST NVD, vulnerabilidades relacionadas a CWE-120 (Buffer Copy without Checking Size of Input) e CWE-787 (Out-of-bounds Write) figuram consistentemente entre as fraquezas de software mais perigosas. O próprio MITRE CWE Top 25 posiciona Out-of-bounds Write como a fraqueza número um em diversas edições da lista.
Para analistas de segurança que operam dentro de um programa de Continuous Threat Exposure Management (CTEM), compreender buffer overflow é essencial: vulnerabilidades dessa natureza frequentemente recebem pontuações CVSS elevadas, possuem exploits públicos disponíveis e podem resultar em comprometimento completo do sistema. Este artigo explica o que é buffer overflow, como o ataque funciona na prática, quais são os tipos existentes, exemplos históricos de impacto real, técnicas de prevenção comprovadas e como ferramentas de scan de vulnerabilidades, especificamente o VulScan é o WebAppScan da EcoTrust, detectam CVEs de buffer overflow antes que sejam explorados.
O que é buffer overflow, definição técnica
Leia também: OWASP Top 10 (2025): as vulnerabilidades mais críticas em...
Um buffer é uma região contiga de memória alocada por um programa para armazenar dados temporariamente, por exemplo, uma string de entrada do usuário, um pacote de rede recebido ou o conteúdo de um arquivo sendo processado. Buffers possuem um tamanho fixo definido no momento da alocação.
Buffer overflow ocorre quando o programa escreve mais dados no buffer do que o espaço alocado comporta. Os bytes excedentes "transbordam" para regiões adjacentes de memória, sobrescrevendo valores que podem incluir variáveis locais, ponteiros, endereços de retorno de funções ou metadados de controle do alocador de memória.
A raiz do problema está na ausência de verificação de limites (bounds checking) antes de operações de copia ou escrita em memória. Linguagens como C e C++ não realizam verificação automática de limites de arrays e buffers, delegando essa responsabilidade ao programador. Quando a verificação é omitida, a vulnerabilidade surge.
Exemplo simplificado em C
#include <string.h>
void função_vulnerável(char *entrada_usuário) {
char buffer[64];
strcpy(buffer, entrada_usuário); // nenhuma verificação de tamanho
}
Se entrada_usuário contiver mais de 64 bytes, strcpy continuara escrevendo além do limite de buffer, sobrescrevendo dados adjacentes na stack, incluindo o endereço de retorno da função. Um atacante que controla entrada_usuário pode manipular esse endereço de retorno para redirecionar o fluxo de execução do programa.
Como buffer overflow funciona: stack vs heap
Leia também: Capture The Flag (CTF): o que é, como funciona e como usa...
Para entender como um atacante explora buffer overflow, é necessário compreender como a memória de um processo e organizada. As duas regiões mais relevantes são a stack e a heap.
Buffer overflow na stack
A stack (pilha) é uma estrutura LIFO (Last In, First Out) usada para armazenar variáveis locais, parâmetros de função e endereços de retorno. Quando uma função é chamada, um stack frame e criado contendo:
- Parâmetros da função
- Endereço de retorno (para onde o programa deve voltar após a função terminar)
- Ponteiro de frame anterior (saved base pointer)
- Variaveis locais (incluindo buffers)
Em um stack buffer overflow, o atacante transborda um buffer local para sobrescrever o endereço de retorno armazenado na stack. Quando a função tenta retornar, o processador salta para o endereço controlado pelo atacante, que pode apontar para código malicioso (shellcode) ou para sequências de instruções existentes no programa (técnica ROP).
A cadeia de ataque típica de um stack buffer overflow segue está sequência:
1. Reconhecimento, O atacante identifica um campo de entrada que alimenta um buffer na stack sem verificação de limites.
2. Construção do payload, O atacante cria uma entrada contendo: dados de preenchimento (padding) para alcançar o endereço de retorno, o novo endereço de retorno desejado e, opcionalmente, shellcode.
3. Envio do payload, A entrada maliciosa e enviada ao programa (via rede, arquivo, formulário web, etc.).
4. Sobrescrita, O programa copia a entrada para o buffer sem verificação, e os bytes excedentes sobrescrevem o endereço de retorno.
5. Desvio de fluxo, Ao retornar da função, o processador salta para o endereço controlado pelo atacante.
6. Execução de código, O atacante obtém execução de código arbitrário com os privilegios do processo vulnerável.
Buffer overflow na heap
A heap é a região de memória usada para alocações dinâmicas (via malloc, calloc, new). A estrutura da heap e gerenciada por um alocador que mantém metadados internos (ponteiros de encadeamento, tamanhos de blocos) entre os blocos alocados.
Em um heap buffer overflow, o atacante transborda um buffer alocado dinâmicamente para sobrescrever metadados do alocador ou dados de objetos adjacentes. A exploração e mais complexa do que na stack, mas igualmente perigosa:
- Corrupcao de metadados do alocador: sobrescrever ponteiros de encadeamento (forward/backward pointers) pode permitir escrita arbitraria em memória durante operações de
free(). - Corrupcao de ponteiros de função: se um objeto adjacente na heap contém um ponteiro de função (vtable em C++, callback), o atacante pode redireciona-lo para código malicioso.
- Corrupcao de dados de aplicação: sobrescrever variáveis de controle (flags de autenticação, níveis de privilegio) adjacentes na heap.
Tipos de buffer overflow e vulnerabilidades relacionadas
A tabela a seguir classifica os principais tipos de transbordamento e vulnerabilidades de memória relacionadas:
| Tipo | Descrição | Região de memória | CWE associada | Risco |
|---|---|---|---|---|
| Stack buffer overflow | Transbordamento de buffer local na stack, sobrescrevendo endereço de retorno ou variáveis | Stack | CWE-121 | Execução de código arbitrário |
| Heap buffer overflow | Transbordamento de buffer alocado dinâmicamente, corrompendo metadados do alocador ou objetos adjacentes | Heap | CWE-122 | Execução de código, negação de serviço |
| Integer overflow | Estouro de valor inteiro que resulta em alocação de buffer menor do que o necessário, levando a overflow subsequente | Stack ou Heap | CWE-190 | Bypass de verificações, overflow secundário |
| Format string | Uso de entrada do usuário como string de formato em funções como printf, permitindo leitura e escrita arbitraria em memória | Stack | CWE-134 | Vazamento de informação, execução de código |
| Off-by-one | Transbordamento de exatamente um byte além do limite do buffer, frequentemente em loops com condição de parada incorreta | Stack ou Heap | CWE-193 | Corrupcao de ponteiro de frame, escalonamento |
| Buffer over-read | Leitura além do limite do buffer, expondo dados sensíveis da memória adjacente (ex.: Heartbleed) | Stack ou Heap | CWE-126 | Vazamento de dados sensíveis |
Integer overflow como vetor
Integer overflow merece destaque porque frequentemente atua como vetor para buffer overflow. Considere o seguinte cenário:
size_t tamanho = entrada_largura * entrada_altura; // pode transbordar
char *buffer = malloc(tamanho); // aloca buffer menor
memcpy(buffer, dados, entrada_largura * entrada_altura); // escreve além do buffer
Se o produto entrada_largura * entrada_altura exceder o valor máximo de size_t, o resultado "enrola" para um valor pequeno. O malloc aloca um buffer pequeno, mas o memcpy subsequente escreve a quantidade real de dados, causando heap overflow.
Format string como vetor
Vulnerabilidades de format string ocorrem quando a entrada do usuário e passada diretamente como string de formato:
printf(entrada_usuário); // vulnerável
printf("%s", entrada_usuário); // seguro
Na versão vulnerável, o atacante pode usar específicadores como %x para ler dados da stack ou %n para escrever em endereços de memória arbitrarios, obtendo capacidades semelhantes a um buffer overflow.
Técnicas de exploração de buffer overflow
Shellcode injection
A técnica clássica de exploração consiste em injetar shellcode (código de máquina malicioso) diretamente no buffer e redirecionar a execução para ele. O shellcode tipicamente inicia uma shell reversa, faz download de malware ou cria uma conta de administrador.
Essa técnica foi dominante nos anos 1990 e 2000, mas tornou-se mais difícil com a adoção de DEP/NX (Data Execution Prevention), que marca regiões de dados como não executaveis.
Return-Oriented Programming (ROP)
ROP e a técnica moderna predominante para contornar DEP/NX. Em vez de injetar código novo, o atacante encadeia pequenos trechos de código já existentes no programa ou em bibliotecas carregadas, chamados gadgets. Cada gadget termina com uma instrução ret, e o atacante constroi uma "ROP chain" na stack que encadeia a execução de múltiplos gadgets para realizar operações arbitrarias.
ROP e eficaz porque utiliza código que já está mapeado como executável na memória do processo. A contramedida principal é o ASLR (Address Space Layout Randomization), que aleatoriza os endereços de carga de bibliotecas e do executável, dificultando a localização dos gadgets.
Ret2libc
Uma variante simplificada de ROP, onde o atacante redireciona a execução para funções da biblioteca padrão C (libc), como system(), passando argumentos controlados (ex.: "/bin/sh") para obter uma shell.
Exemplos reais de buffer overflow
Morris Worm (1988)
O Morris Worm é considerado o primeiro worm de internet com repercussão global. Criado por Robert Tappan Morris, o worm explorava, entre outros vetores, um buffer overflow na função gets() do daemon fingerd em sistemas Unix BSD. O worm infectou apróximadamente 6.000 máquinas, cerca de 10% da internet da epoca, e causou prejuizos estimados entre 100 mil e 10 milhões de dolares. O incidente levou a criação do CERT/CC (Computer Emergency Response Team) na Carnegie Mellon University.
Code Red (2001)
O worm Code Red explorava um buffer overflow no serviço IIS (Internet Information Services) da Microsoft (CVE-2001-0500), especificamente na extensão ISAPI para indexação. O worm infectou mais de 350.000 servidores em menos de 14 horas, realizando defacement de sites e lancando ataques DDoS contra endereços IP do governo americano.
Heartbleed (2014)
Heartbleed (CVE-2014-0160) e técnicamente um buffer over-read na implementação da extensão TLS Heartbeat na biblioteca OpenSSL. A vulnerabilidade permitia que um atacante enviasse uma requisição heartbeat com campo de tamanho manipulado, fazendo o servidor retornar até 64 KB de memória adjacente ao buffer. Essa memória podia conter chaves privadas SSL, credenciais de usuários, tokens de sessão e outros dados sensíveis. Estima-se que 17% dos servidores web com SSL no mundo estavam vulneráveis no momento da divulgação.
EternalBlue (2017)
EternalBlue (CVE-2017-0144) explora um buffer overflow no protocolo SMBv1 (Server Message Block) do Windows. Desenvolvido originalmente pela NSA e vazado pelo grupo Shadow Brokers, o exploit permitia execução remota de código sem autenticação. EternalBlue foi o vetor principal de propagação do ransomware WannaCry, que afetou mais de 200.000 computadores em 150 países, causando prejuizos estimados em 4 bilhões de dolares. O NHS (National Health Service) do Reino Unido foi um dos mais afetados, com cancelamento de cirurgias e redirecionamento de ambulancias.
Sudo Baron Samedit (2021)
A vulnerabilidade CVE-2021-3156 (Baron Samedit) era um heap buffer overflow no útilitario sudo, presente há quase 10 anos em praticamente todas as distribuições Linux. Um usuário local sem privilegios podia explorar o overflow para obter acesso root, demonstrando como vulnerabilidades de buffer overflow em software ubiquo podem ter alcance massivo.
Técnicas de prevenção contra buffer overflow
A prevenção contra buffer overflow opera em múltiplas camadas: compilador, sistema operacional, desenvolvimento de código e testes de segurança. A seguir, as técnicas mais eficazes organizadas por camada.
1. ASLR (Address Space Layout Randomization)
O ASLR aleatoriza os endereços base de bibliotecas compartilhadas, stack, heap e do próprio executável a cada execução do processo. Isso impede que o atacante preveja endereços de memória necessários para técnicas como ROP e ret2libc.
- Como funciona: o kernel do sistema operacional seleciona offsets aleatorios para cada região de memória no momento do carregamento do processo.
- Limitação: pode ser contornado com information leaks (vazamentos de endereços) ou força bruta em sistemas 32-bit com entropia limitada.
- Disponibilidade: habilitado por padrão no Linux (desde 2005), Windows (desde Vista), macOS (desde 10.5).
2. DEP/NX (Data Execution Prevention / No-Execute)
DEP/NX marca páginas de memória de dados (stack, heap) como não executaveis no nível do hardware. Se o processador tentar executar código em uma página marcada como NX, uma exceção e gerada é o processo e terminado.
- Como funciona: utiliza o bit NX (No-Execute) nos processadores modernos (Intel XD, AMD NX) para separar dados de código executável.
- Limitação: não impede técnicas como ROP que reutilizam código existente já mapeado como executável.
- Disponibilidade: suportado em processadores x86-64 e habilitado por padrão em sistemas operacionais modernos.
3. Stack canaries (canarios de stack)
Stack canaries são valores sentinela inseridos pelo compilador entre as variáveis locais e o endereço de retorno na stack. Antes do retorno da função, o compilador verifica se o canary foi modificado. Se foi, indica que houve overflow é o programa e terminado imediatamente.
- Como funciona: o compilador insere código de prologo (escrita do canary) e epilogo (verificação do canary) em cada função.
- Limitação: pode ser contornado se o atacante conseguir vazar o valor do canary (via format string ou information leak) ou se o overflow não sobrescrever o canary (ex.: overflow de estruturas específicas).
- Ativação: flag
-fstack-protector-strongno GCC/Clang; habilitado por padrão no MSVC (/GS).
4. Uso de funções seguras e verificação de limites
A medida mais fundamental e utilizar funções que aceitam parâmetro de tamanho máximo:
| Função insegura | Função segura | Observação |
|---|---|---|
strcpy | strncpy, strlcpy | Limita a quantidade de bytes copiados |
strcat | strncat, strlcat | Limita a concatenação |
sprintf | snprintf | Limita a escrita formatada |
gets | fgets | Limita a leitura de entrada |
scanf("%s") | scanf("%63s") | Específica largura máxima |
Além de funções seguras, adotar verificação explícita de limites antes de qualquer operação de copia ou escrita em buffer é essencial.
5. Linguagens memory-safe
Migrar componentes críticos para linguagens com gerenciamento automático de memória e verificação de limites elimina classes inteiras de vulnerabilidades. Linguagens como Rust, Go, Java e C# realizam bounds checking automático e gerenciam memória de forma segura (ownership em Rust, garbage collection nas demais).
Projetos como a reescrita de componentes do kernel Linux em Rust é a adoção de Rust no Android demonstram a tendência da industria em reduzir a superfície de ataque por buffer overflow na origem.
6. SAST (Static Application Security Testing)
Ferramentas de análise estática examinam o código-fonte antes da compilação para identificar padrões vulneráveis: uso de funções inseguras, ausência de verificação de limites, potenciais integer overflows. SAST integra-se ao pipeline de CI/CD e permite detecção precoce durante o desenvolvimento.
7. DAST (Dynamic Application Security Testing)
Ferramentas de análise dinâmica testam a aplicação em execução, enviando entradas malformadas (fuzzing) para identificar comportamentos anomalos indicativos de buffer overflow: crashes, corrupcao de memória, respostas inesperadas. O módulo WebAppScan da EcoTrust realiza testes DAST autenticados em aplicações web, identificando vulnerabilidades de memória que se manifestam em tempo de execução.
8. Compilação com proteções adicionais
Além de stack canaries, compiladores modernos oferecem flags adicionais de proteção:
- FORTIFY_SOURCE: substitui funções inseguras por versões com verificação de limites em tempo de compilação e execução (
-D_FORTIFY_SOURCE=2). - PIE (Position Independent Executable): gera executaveis com endereços relativos, permitindo ASLR completo para o executável principal (
-fPIE -pie). - RELRO (Relocation Read-Only): marca a GOT (Global Offset Table) como somente leitura após a resolução de símbolos, impedindo sobrescrita (
-Wl,-z,relro,-z,now). - CFI (Control Flow Integrity): válida em tempo de execução que transferências indiretas de controle (calls, jumps) apontam para alvos legitimos (
-fsanitize=cfino Clang).
Como o scan de vulnerabilidades detecta buffer overflow
Em ambientes corporativos, a detecção de vulnerabilidades de buffer overflow depende primáriamente de scan de vulnerabilidades baseado em CVEs. Ferramentas de scan identificam software instalado, comparam versões contra bases de dados de vulnerabilidades conhecidas (NVD, vendor advisories) e reportam CVEs que afetam o ambiente.
Detecção com VulScan
O módulo VulScan da EcoTrust realiza varreduras de vulnerabilidades em infraestrutura, identificando CVEs conhecidos de buffer overflow em:
- Sistemas operacionais: CVEs em kernels, bibliotecas do sistema (glibc, OpenSSL, libcurl).
- Servidores e serviços de rede: CVEs em servidores web (Apache, Nginx, IIS), protocolos (SMB, RDP, DNS), serviços de email.
- Software de terceiros: CVEs em aplicações instaladas, frameworks, runtimes.
Para cada CVE detectado, o VulScan apresenta o score CVSS, indicadores EPSS (probabilidade de exploração), informação sobre existência de exploit público e recomendação de remediação. Dentro de um programa CTEM, essa informação alimenta a priorização de vulnerabilidades no módulo GVul da EcoTrust, permitindo que a equipe foque nos buffer overflows com maior probabilidade de exploração real.
Detecção com WebAppScan
O módulo WebAppScan da EcoTrust detecta vulnerabilidades de memória em aplicações web por meio de:
- Identificação de tecnologias: fingerprinting de servidores web, frameworks e bibliotecas com CVEs de buffer overflow conhecidos.
- Testes DAST: envio de payloads que provocam comportamento anomalo indicativo de vulnerabilidades de memória.
- Correlação de CVEs: mapeamento de versões identificadas contra a base de CVEs para reportar vulnerabilidades de buffer overflow aplicaveis.
A plataforma da EcoTrust, como Plataforma de IA Agêntica para CTEM, unifica as deteccoes do VulScan e do WebAppScan em uma visão consolidada, permitindo que analistas priorizem e acompanhem a remediação de buffer overflows críticos de forma contínua.
Como estruturar a remediação de buffer overflow em um programa CTEM
A remediação de vulnerabilidades de buffer overflow em escala requer um processo estruturado que vai além da aplicação de patches individuais:
- Descoberta contínua: execute varreduras regulares com VulScan e WebAppScan para identificar novos CVEs de buffer overflow no ambiente.
- Priorização baseada em risco: utilize CVSS, EPSS e contexto de negócio no módulo GVul para priorizar os buffer overflows com maior impacto potencial.
- Remediação: aplique patches do fabricante, atualize versões vulneráveis ou implemente mitigações temporarias (WAF rules, desabilitação de serviços afetados).
- Validação: reexecute o scan após a remediação para confirmar que a vulnerabilidade foi eliminada.
- Monitoramento: acompanhe novas divulgações de CVEs de buffer overflow que afetam tecnologias presentes no ambiente.
Solicite uma demonstração do VulScan e veja como a EcoTrust identifica CVEs de buffer overflow críticos no seu ambiente com priorização baseada em IA agêntica.
FAQ, Perguntas frequentes sobre buffer overflow
O que é buffer overflow? Buffer overflow é uma vulnerabilidade que ocorre quando um programa escreve dados além do espaço de memória alocado para um buffer, podendo sobrescrever dados adjacentes, corromper a execução do programa ou permitir execução de código malicioso por um atacante.
Qual a diferença entre stack overflow e heap overflow? Stack overflow afeta buffers alocados na pilha de execução (variáveis locais), permitindo sobrescrita do endereço de retorno da função. Heap overflow afeta buffers alocados dinâmicamente, corrompendo metadados do alocador de memória ou objetos adjacentes. A exploração de stack overflow e geralmente mais direta, enquanto heap overflow requer maior sofisticação.
Buffer overflow ainda é relevante em 2026? Sim. Apesar de proteções como ASLR, DEP e stack canaries, buffer overflow contínua sendo uma das classes de vulnerabilidade mais exploradas. Linguagens como C e C++ permanecem amplamente utilizadas em sistemas operacionais, firmware, bibliotecas críticas e software embarcado. CVEs de buffer overflow com exploits públicos são descobertos regularmente.
Quais linguagens de programação são imunes a buffer overflow? Linguagens com gerenciamento automático de memória e verificação de limites, como Rust (em modo safe), Java, C#, Go e Python, previnem buffer overflow por design. Porém, essas linguagens frequentemente utilizam bibliotecas nativas escritas em C/C++ (via FFI), que podem conter vulnerabilidades de buffer overflow.
Como o ASLR protege contra buffer overflow? O ASLR aleatoriza os endereços de memória (stack, heap, bibliotecas) a cada execução do processo. Isso impede que o atacante preveja onde estão seus gadgets ROP ou shellcode, tornando a exploração significativamente mais difícil, embora não impossível se combinada com vazamentos de informação.
O que é ROP (Return-Oriented Programming)? ROP é uma técnica de exploração que contorna proteções DEP/NX ao encadear pequenos trechos de código existente (gadgets) já mapeados como executaveis na memória do processo. O atacante constroi uma cadeia de endereços de retorno na stack que, quando executada sequencialmente, realiza operações arbitrarias sem injetar código novo.
Como detectar buffer overflow no meu ambiente? A forma mais eficaz em ambientes corporativos e por meio de scan de vulnerabilidades que identifica CVEs conhecidos de buffer overflow no software instalado. O VulScan da EcoTrust identifica CVEs de buffer overflow em infraestrutura, enquanto o WebAppScan detecta vulnerabilidades de memória em aplicações web.
Para aprofundamento, consulte a referência oficial: Gartner — How to Manage Cybersecurity Threats.
Conclusão
Buffer overflow é uma vulnerabilidade fundamental que todo analista de segurança precisa compreender. Dos ataques clássicos de stack smashing nos anos 1990 até os exploits sofisticados baseados em ROP da atualidade, o princípio permanece o mesmo: a ausência de verificação de limites em operações de memória cria oportunidades de comprometimento crítico.
A defesa eficaz combina proteções em múltiplas camadas, ASLR, DEP/NX, stack canaries, funções seguras, linguagens memory-safe, com visibilidade contínua sobre vulnerabilidades conhecidas no ambiente. Dentro de um programa CTEM, o VulScan é o WebAppScan da EcoTrust garantem que CVEs de buffer overflow sejam identificados, priorizados e remediados de forma sistemática, reduzindo a janela de exposição da organização.
Conheça a plataforma EcoTrust e descubra como a IA agêntica para CTEM identifica e prioriza vulnerabilidades de buffer overflow no seu ambiente. Fale com um especialista.
Conheça o módulo WebAppScan
Veja como a EcoTrust aplica IA agêntica para resolver os desafios apresentados neste artigo.
Explorar WebAppScanArtigos Relacionados
Pentest: o que é, tipos, metodologias e quando realizar
Pentest, abreviação de penetration test, ou teste de penetração, é uma avaliação de segurança ofensiva na qual profissionais especializados simulam ataques reais contra sistemas, redes ou aplicações d…
Security by Design: princípios, abordagens e como aplicar no desenvolvimento seguro
**Security by Design é a abordagem de engenharia de software que incorpora requisitos e controles de segurança desde a concepcao de um sistema, em vez de trata-los como complemento após a entrega.** A…
Capture The Flag (CTF): o que é, como funciona e como usar para treinar equipes
Competições de **CTF (Capture The Flag)** se tornaram uma das formas mais eficazes de desenvolver habilidades práticas em segurança da informação. Para analistas que atuam em operações de segurança, *…