O documento discute buffer overflows, incluindo sua história, tipos de ataques e estrutura da memória de um programa. Buffer overflows ocorrem quando dados maiores que o tamanho do buffer são armazenados, podendo corromper a memória. Dois tipos comuns são stack-based e heap-based buffer overflows.
2. AGENDA
• Contexto histórico
• Buffer - O que é ?
• Overflow – o que é?
• Buffer Overflow – Uma Visão Geral
• Exploits e tipos de ataques baseados em Buffer Overflow
• A estrutura de um programa na memória
• Conhecendo melhor a heap
• Heap-based Buffer Overflow
• Return-to-libc Attack
3. CONTEXTO HISTÓRICO
• Em 1995, Thomas Lopatic redescobriu sozinho o buffer
overflow e publicou seus achados na lista de emails da
Bugtraq. Um ano depois, Elias Levy (Também conhecido
como Aleph One), publicou na revista Phrack, o artigo
“Smashing the Stack for Fun and Profit” (Arrasando a Pilha
por Diversão e Lucro), uma introdução passo-a-passo para
realizar um stackbased buffer overflow.
4. CONTEXTO HISTÓRICO
• Buffer Overflows foram entendidos por volta de 1972,
quando o Computer Security Technology Planning Study
(documento de planejamento de estudos da USAF) definiu
a técnica como o seguinte:
• “Um código realizando tal função não checa os endereços
de fonte e destino apropriadamente, permitindo que
partes do monitor sejam superpostas pelo usuário. Isso
pode ser usado para injetar códigos no monitor que irão
permitir o usuário a tomar o controle da máquina.”
5. CONTEXTO HISTÓRICO
• Hoje em dia, o monitor, poderia ser referido como o kernel.
• A documentação mais antiga de Buffer Overflow data de
1988. Foi uma das muitas vulnerabilidades exploradas pelo
Morris worm para se propagar pela internet.
6. BUFFER - O QUE É?
Em computação, um buffer é uma região temporária da
memória onde são guardados dados para serem
transportados de um lugar para o outro. Uma aplicação
frequente de um buffer ´e quando dados são
capturados de um dispositivo de entrada (um teclado
ou mouse, por exemplo) e enviados `a um dispositivo
de saída(monitor, impressora).
8. OVERFLOW?
O conceito básico de um overflow é um
transbordamento, ou seja, um overflow ocorre quando
o volume de determinado objeto ou substância é maior
do que a capacidade de seu compartimento.
10. BUFFER OVERFLOW - UMA VISÃO GERAL
O buffer overflow é um erro de programação que pode
resultar em execução errônea de um programa, acesso
indevido a áreas de memória, terminação do programa
ou uma possível falha de segurança em um sistema.
Tecnicamente falando, um buffer overflow consiste em
um processo de armazenar, em um buffer de tamanho
fixo, dados maiores que o seu tamanho.
11. COMO FUNCIONA?
Imagine que um programa declara duas estruturas de dados
adjacentes na memória do computador: um vetor de caracteres
de 8 bytes, A, e um inteiro de 2 bytes, B, enche A de zeros e B
recebe o número 3, como no seguinte esquema:
12. COMO FUNCIONA?
A palavra excessivo tem 9 letras, consequentemente, 10
caracteres, pois um caractere nulo é concatenado ao final para
indicar o fim de uma string (vetor de caracteres).
Separando a palavra em caracteres seria algo como: 'e', 'x', 'c', 'e',
's', 's', 'i', 'v', 'o','0', sendo o '0' o caractere nulo, que consiste
em um um byte zerado.
Sabendo que cada caractere ocupa um byte, a string A, então,
tem apenas 8 bytes, porém estamos inserindo 10 bytes, que é
um tamanho maior do que A comporta.
13. EXPLOITS E TIPOS DE ATAQUES BASEADOS EM
BUFFER OVERFLOW
Exploits são pedaços de código, sequências de comandos, ou até
mesmo programas que se aproveitam de vulnerabilidades ou
bugs em softwares, visando causar comportamento errôneo,
inesperado ou até mesmo ganhar acesso privilegiado a um
sistema.
A maioria dos Exploits visa ganhar acesso de nível de
superusuario á sistemas ou derrubar os mesmos. Pode-se fazer
uso de vários exploits diferentes para galgar níveis de acesso ate
chegar ao superusuario.
14. TIPOS DE ATAQUES BASEADOS EM BUFFER
OVERFLOW
Os tipos mais comuns de ataques baseados em buffer
overflow são:
• Stack-based buffer overflow
• Heap-based buffer overflow
• Return-to-libc attack
15. A ESTRUTURA DE UM PROGRAMA NA
MEMÓRIA
Qualquer programa compilado (e isto inclui interpretadores de
linguagens) possui uma forma estruturada em código de
máquina denotando uma sequência de instruções que serão
executadas pelo processador. Tal sequência é carregada na
memória quando um programa é chamado á execução.
A estrutura de um programa na mem´oria se divide em quatro
partes: texto, dados, stack (pilha) e heap.
16. A ESTRUTURA DE UM PROGRAMA NA
MEMÓRIA
• A região do texto contém as instruções do programa
propriamente ditas e dados somente-leitura. Essa região ´e
geralmente somente-leitura, para evitar códigos mutáveis. Uma
tentativa de escrita nessa ´área resulta em uma falha de
segmentação.
• A região dos dados contém todas as variáveis globais e
estáticas do programa.
17. A ESTRUTURA DE UM PROGRAMA NA
MEMÓRIA
• A região de heap serve para a alocação dinâmica de variáveis,
através de instruções do tipo malloc();
• A pilha é a região mais interessante para os fins deste texto.
Trata-se de um bloco de memória onde são armazenadas
informações vitais para sub-rotinas: variáveis locais,
parâmetros e os valores de retorno.
19. STACK-BASED BUFFER OVERFLOW
o processador lê uma série de instruções. Tais
que são referenciadas por bytes. Com este
conhecimento, podemos então ao invés de
escrevermos um nome, poderíamos enviar um
endereço de memória onde um código
previamente inserido possa ser executado. O
código inserido é normalmente chamado de
shellcode.
20. HEAP-BASED BUFFER OVERFLOW
Este é um tipo muito mais difícil de ser explorado devido ao fato do
alvo ser a heap. Entre as dificuldades estão:
• Na heap, não existem valores os quais o processador usa para saber
qual a próxima operação a executar, apenas valores de organização
do próprio heap.
• Devido ao fato do heap crescer em direção aos valores maiores da
memória e podermos apenas escrever nesta mesma direção, não é
possível reescrever os valores de controle do bloco atual, apenas dos
blocos posteriores.
21. HEAP-BASED BUFFER OVERFLOW
• Como a organização da heap pode variar, o atacante precisa saber
qual é a implementação de heap do programa-alvo.
Para explorar um buffer overflow na heap é necessário encontrar uma
vulnerabilidade em alguma função interna de administração da heap,
de modo que esta processe o buffer alvo na heap. Deste modo:
• Precisamos explorar a heap para sobrescrever os valores de
administração de um bloco alvo e assim inserir o shellcode,
construindo um bloco malicioso na heap.