• Nenhum resultado encontrado

Estouro de Buffer (Buffer Overflow) Prof. Paulo Cesar F. de Oliveira, BSc, PhD

N/A
N/A
Protected

Academic year: 2021

Share "Estouro de Buffer (Buffer Overflow) Prof. Paulo Cesar F. de Oliveira, BSc, PhD"

Copied!
53
0
0

Texto

(1)

Estouro de Buffer (Buffer Overflow)

Prof. Paulo Cesar F. de Oliveira,

BSc, PhD

(2)

Capítulo 03

Estouro Buffer

Seção 1.1

Introdução

(3)

Capítulo 03

Estouro Buffer

O que é ?

(4)

²   Definições

²  Buffer (array ou string)

²  Área da memória onde a entrada do usuário é armazenada

²  Estouro (Overflow)

²  Entrada do usuário excede o tamanho máximo do buffer

²  Sobrescrevendo outras áreas da memória e corrompendo-as

Capítulo 03

Estouro Buffer

(5)

Capítulo 03

Estouro Buffer

²  O que é?

²  Evento que ocorre quando:

²  Buffer de dados de comprimento fixo (e.g. string )

²  Pelo menos um valor destinado ao buffer é escrito fora de seus limites (geralmente após o seu fim)

²  Leitura da entrada ou após o tratamento de dados

(6)

Capítulo 03

Estouro Buffer

²  O que é?

²  Buffer overflows = buffer overruns

²  Stack overrun

²  Buffer na pilha (stack)

²  Também chamado “stack smashing”

²  Heap overrun

²  Buffer na heap

²  Também chamado “heap smashing”

(7)

Capítulo 03

Estouro Buffer

²  O que é?

²  Problema comum

²  Se explorável

²  Agressor pode controlar o programa completamente

²  Agressor pode tipicamente causar negação de serviço

²  Muitas defesas simplesmente reduzem-se de

“programa de controle” para o DoS (Denial-of-

Service)

(8)

Capítulo 03

Estouro Buffer

1988: Morris worm – tirou Internet do ar Inclui estouro de buffer via gets() in fingerd

1999: Implementação de referência crypto RSA, Subverteu PGP, OpenSSH, Apache’s ModSSL, etc.

2003: SQL Slammer worm comprometeu máquinas rodando Microsoft SQL Server 2000

2008: Twilight hack – abre consoles Wii, Criando um nome longo para cavalo

“Epona” no jogo "The Legend of Zelda:

Twilight Princess", permitindo execução 2001: Code Red worm – buffer overflow no Microsoft’s Internet Information Services (IIS) 5.0

1998: University of Washington servidor IMAP (mail)

Histórico

(9)

Capítulo 03

Estouro Buffer

²  Linguagens de Programação e Estouro de Buffer

²  Linguagens que permitem o evento

² C, C++, Objective-C, Vala, Forth, Assembly

²  Linguagens que não permitem

² Ada strings, Pascal: Detém/previne overflow

² Java, Python, Perl, Ada: Auto-resize

²  Outras linguagens não dão imunidade

² Implementações da maioria são em C/C++

² Várias bibliotecas/componentes do SO incluem C/C++

² Algumas linguagens/compiladores permitem desabilitar proteção

² C# e Ada

² Escolhendo outra ajuda – mas não completamente

Muito comum

(10)

Capítulo 03

Estouro Buffer

Seção 1.2

Recapitulação

(11)

Capítulo 03

Estouro Buffer

²  Terminação de string em C è \O

²  Strings em C terminam com caracter \0 (1 byte valor 0)

²  Vários SOs e componentes construídos com C

²  Interfaces herdam semanticamente “strings com \0”

²  Alguns componentes não lidam com isto, mesmo que a linguagem possa

²  Observe que \0 ocupa espaço – lembre-se disto

²  Nome formal é NUL ou caracter NULL

²  Às vezes confundido com NULL – “null pointer”

H e l l o \0 NIL (reduzir confusão)

(12)

Capítulo 03

Estouro Buffer

²  Arrays em C

²  Arrays alocam um tamanho fixo de memória

²  Ex., para um buffer

²  Arrays “char” são usadas para string de caracteres

²  Devem ser o grande suficiente

²  Para os caracteres a serem armazenados

²  Incluindo também o caracter NIL

²  Ex. “char x[10];”

§ Aloca espaço para uma array x

§ Array x possui 10 chars

§ Armazena 9 caracteres + caracter de terminação NIL

(13)

Capítulo 03

Estouro Buffer

Exemplo #1

int main() {

int array[5] = {1, 2, 3, 4, 5};

printf("%d\n", array[5]);

}

§ Nunca faça isto

§ Checar limites da array em tempo de execução

(14)

Capítulo 03

Estouro Buffer

Exemplo #2

int main() {

int array[5] = {1, 2, 3, 4, 5};

int i;

for( i=0; i<=255; i++ ) array[i] = 41;

}

§ Nunca faça isto

§ Checar limites da array em tempo de execução

(15)

Capítulo 03

Estouro Buffer

Exemplo #3

int main(int argc, char* argv[]) { char command[10];

printf(”Seu comando? \n");

gets(command);

printf(”Seu comando foi: %s\n", command);

}

§ Só 10 bytes para variável command (incluindo NIL)

§ Instrução gets não provê proteção contra estouro de buffer

§ Nunca use gets

§ Use fgets(buf, size, stdin)

(16)

Capítulo 03

Estouro Buffer

Exemplo #3

...

char dest [20];

strcpy (dest, src) //copia string src para dest ...

§ strcpy assume dest é grande o bastante

§ Nunca use strcpy

§ Use strncpy(dest, src, size)

(17)

Seção 1.3

Mapeamento da Memória

Capítulo 03

Estouro Buffer

(18)

Capítulo 03

Estouro Buffer

Stack (Pilha)

Heap (alocada dinamicamente)

Dados 2 Globais não inicializados

Dados 1 Globais inicializados

Código do Programa

§  Stack: Contém endereço de retorno das chamadas de função, argumentos para funções e variáveis locais

§  Heap: Contém dados dinâmicos e não inicializados

§  Dados 2: Contém variáveis globais não inicializadas

§  Dados 1: Contém variáveis globais inicializadas

§ Inicializadas na carga do código

§  Código do programa: Contém as instruções (comandos)

§ Somente pra leitura

§ Usado para variáveis e constantes globais

(19)

Capítulo 03

Estouro Buffer

Observando código abaixo int main() {

int char sample[10];

int i;

for (i=0; i<=9; i++) sample[i] = 'A';

sample[10] = 'B’

}

Onde ‘B’ ficará (memória) ?

(20)

Capítulo 03

Estouro Buffer

Possibilidade #1

A A A A A A A A A A B

Memória Afeta os dados do usuário

Dados do Usuário

(21)

Capítulo 03

Estouro Buffer

Possibilidade #2

A A A A A A A A A A B

Memória Afeta código do usuário

Dados do Usuário

Código do Programa do Usuário

(22)

Capítulo 03

Estouro Buffer

Possibilidade #3

A A A A A A A A A A B

Memória Afeta os dados do sistema

Dados do Usuário Dados do Sistema

(23)

Capítulo 03

Estouro Buffer

Possibilidade #4

A A A A A A A A A A B

Memória Afeta código do sistema

Dados do Usuário

Código do Programa do Sistema

(24)

02/04/14 © P C F de Oliveira 2014 24

Capítulo 03

Estouro Buffer

Questões para responder

²  Que valores o hacker poderia inserir após o buffer que causasse prejuízo ou dano?

²  Quais códigos de instrução planejados o sistema

seria forçado a executar?

(25)

Capítulo 03

Estouro Buffer

Seção 1.4

Stack Smashing

(estouro da pilha)

(26)

²  Conceito de Pilha (Stack)

²  Pilha de objetos tem a propriedade de que o último objeto inserido será o primeiro objeto a ser removido

²  Last in – First out (LIFO)

²  Operações básicas

²  PUSH: adiciona um elemento no topo da pilha

²  POP: remove um elemento do topo da pilha, reduzindo o tamanho dela em 1 unidade

 

Capítulo 03

Estouro Buffer

(27)

Capítulo 03

Estouro Buffer

Funcionamento da Stack (Pilha)

(28)

²  Pilha (Stack) no Processo de Mapeamento da Memória

² Área de memória reservada para implementar as chamadas para um procedure / function / method / subroutine

² Estes termos são sinônimos (C -> function – função)

² Stack é usada para implementar controle de fluxo

² Quando você chama procedure, de “onde ele veio" é inserido (PUSH) na pilha

² Quando procedure retorna, o de “onde vim" é removido (POP) da pilha;

² Sistema começa a execução de código lá

² Stack também utilizado para outros dados (em muitos casos)

² Parâmetros passados para procedure

² Variáveis locais das procedures

² Valores de retorno da procedure

 

Capítulo 03

Estouro Buffer

(29)

²  Stack possui 2 valores

²  Stack Pointer : valor que está no topo

²  Onde o último dado foi armazenado

²  Modificado quando dado for (pushed/popped)

²  Frame Pointer : valor do “quadro” – conteúdo

²  Simplifica acesso a parâmetros e variáveis locais

²  Aponta para onde “o procedimento” começa dentro da pilha

²  Modificado na entrada/saída do procedimento

Capítulo 03

Estouro Buffer

(30)

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

void f(int a, int b, int c) { char buffer1[5];

char buffer2[10];

strcpy(buffer2, "This is a very long string!!!!!!!");

}

int main() { f(1,2,3);

}

Capítulo 03

Estouro Buffer

Código assembler

pushl $3 ;constante 3 pushl $2 ;constante 2 pushl $1 ;constante 1 call f

Execução do programa

(31)

Capítulo 03

Estouro Buffer

Lower-numbered addresses

Higher-numbered addresses

Stack pointer (SP) (current top of stack)

3

Stack:

após push do valor 3

(32)

Capítulo 03

Estouro Buffer

Lower-numbered addresses

Higher-numbered

addresses

3

2

Stack pointer (SP)

(current top of stack)

Stack:

após push do valor 2

Stack cresce; i.e. devido à chamada da procedure

(33)

Capítulo 03

Estouro Buffer

Lower-numbered addresses

Higher-numbered

addresses

3

2

1

Stack pointer (SP)

(current top of stack)

Stack:

após push do valor 1

Stack cresce; i.e. devido à

(34)

Capítulo 03

Estouro Buffer

Lower-numbered addresses

Higher-numbered

addresses

3

2 1

Stack:

logo após a chamada da função

Endereço Retorno em main() Stack pointer (SP) (current top of stack)

Stack cresce; i.e. devido à chamada da procedure

(35)

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

void f(int a, int b, int c) { char buffer1[5];

char buffer2[10];

strcpy(buffer2, "This is a very long string!!!!!!!");

}

int main() { f(1,2,3);

}

Capítulo 03

Estouro Buffer

pushl %ebp ;Push old frame pointer (FP) movl %esp,%ebp ;New FP é SP (old)

subl $20,%esp ;New SP está após vars locais

;$20calculado p/ser >= espaço var local

Execução da procedure

§ EBP: Base pointer: aponta para o início do stack frame corrente

§ ESP: Stack pointer: aponta para o topo da stack

(36)

Capítulo 03

Estouro Buffer

Lower-numbered addresses

Higher-numbered

addresses

3

2 1

Stack:

execução da função

Endereço Retorno em main()

Frame pointer (FP) – Use para acessar variáveis locais e parâmetros

Frame pointer salvo (old) Array local buffer1Array local buffer2

Stack pointer (SP) (current top of stack)

Stack cresce; i.e. devido à chamada da procedure

(37)

Capítulo 03

Estouro Buffer

Lower-numbered addresses

Higher-numbered

addresses

3

2 1

Stack:

“estourando” buffer2

Endereço Retorno em main()

Frame pointer (FP) – Use para acessar variáveis locais e parâmetros

Frame pointer salvo (old) Array local buffer1Array local buffer2

Stack pointer (SP) (current top of stack)

Overwrite

Stack cresce; i.e. devido à

(38)

² O que acontece se escrevermos algo no fim de buffer2?

²  Substitui o que estiver após buffer2

²  Quanto mais longe for, mais endereços altos sobrescritos

²  Impacto depende de detalhes do sistema

²  No exemplo, irá substituir

²  Valores locais (buffer1)

²  Frame Pointer Salvo

²  Valor de Retorno (mudando ponto de volta ao PP)

²  Parâmetros da função (procedure)

²  Frames anteriores

Capítulo 03

Estouro Buffer

(39)

²  Ataque mais comum de estouro de buffer

² Enviar dados muito largos ou

² Criar dados extremamente largos

² Dados muito largos sobrescrevem o buffer

² Modifica o valor de retorno para

² Aponta para algo que o hacker quer que se execute

² Talvez com parâmetros diferentes também

² No retorno executa código selecionado por ele

Capítulo 03

Estouro Buffer

Mas, tem coisa pior!!!

(40)

²  Inserindo código no estouro de buffer (e.g. Shell code)

² Hacker pode incluir um código de máquina que ele quer que se rode

² Se ele pode definir o valor de “retorno” apontar para um código malicioso,

² No retorno a vítima executará este código

² A menos que algo seja feito

²  O paper “Smashing the Stack” contém uma descrição de como inserir este código

Capítulo 03

Estouro Buffer

(41)

Capítulo 03

Estouro Buffer

Lower-numbered addresses

Higher-numbered

addresses

3

2 1 Stack:

1 possível resultado após ataque

Endereço Retorno em main()

Frame pointer (FP) – Use para acessar variáveis locais e parâmetros

Frame pointer salvo (old) Array local buffer1Array local buffer2

Stack pointer (SP) (current top of stack)

Stack cresce; i.e. devido à

Código Malicioso

Ptr código malicioso

(42)

Capítulo 03

Estouro Buffer

Lower-numbered addresses

Higher-numbered

addresses

3

2 1 Stack:

1 possível resultado após ataque

Endereço Retorno em main()

Frame pointer (FP) – Use para acessar variáveis locais e parâmetros

Frame pointer salvo (old) Array local buffer1Array local buffer2

Stack pointer (SP) (current top of stack)

Stack cresce; i.e. devido à chamada da procedure

Ptr código malicioso

Shellcode: \xeb\x1f\x5e

\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x 0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c

\xcd\x80\x31\xdb\x89\xd8\x40\xcd

\x80\xe8\xdc\xff\xff\xff/bin/sh

NOP sled: \x90\x90\x90\x90\x90….

NOP slide

§  Permite que hacker pule para qualquer lugar para atacar

§  Alguns muito complexos para detectar

Shellcode: ver slide seguinte

(43)

²  Outros tipos de ataques possíveis no estouro de buffer

² Fazer o “código de retorno” apontar para um código existente que o hacker queira que se execute

² E.g. chamar um shell

² Talvez modificar parâmetros

² Alterar valores de variáveis locais adjacentes

² Alterar valor dos parâmetros

² Entender que sobrescrever algo após o fim de um buffer pode ter consequências devastadoras

² Detalhes dependem do sistema

² Sim, os hackers realmente entendem isto

Capítulo 03

Estouro Buffer

(44)

Seção 1.5

Heap Smashing

(estouro da heap)

Capítulo 03

Estouro Buffer

(45)

² “Estourando a Heap”

² Heap contém dados alocados dinamicamente

² e.g. “new” (Java/C++)

² malloc (C)

²Dados são globais

²Incluem valores de controle de infraestrutura importantes

² Se hacker pode sobrescrever além do buffer, pode controlar outros valores (e.g. Armazenados depois disto)

² Valores de outras estruturas

² Dados de manutenção da heap (e.g. O que livre/usado)

²Até mesmo 1 byte sobrescrito pode ser devastador

²Detalhes são dependentes do sistema

²Hackers podem explorá-los também

² Questão fundamental como estouro da pilha (stack smashing)

Capítulo 03

Estouro Buffer

(46)

Seção 1.6

Soluções em C

Capítulo 03

Estouro Buffer

(47)

Solução óbvia quando se usa C é sempre verificar os limites dos buffers (i.e.

arrays)

Entretanto...

Capítulo 03

Estouro Buffer

(48)

²   Funções C que não verificam limites

²  gets() – lê entrada sem checar – não use!!!

²  strcpy() – strcpy(dest, src) copia src para dest

²  Se src > dest, continua escrevendo!!!!

²  strcat() – strcat(dest, src) adiciona src em dest

²  Se src + dados em dest > buffer dest, continua gravando!!!

Capítulo 03

Estouro Buffer

(49)

²   Funções C que não verificam limites

²  scanf() família de funções de entrada – várias opções perigosas

²  scanf(), fscanf(), sscanf(), vscanf(), vsscanf(), vfscanf()

²  Muitas opções não controlam comprimento máximo (e.g. “%s”)

²  Outras funções perigosas

²  realpath(), getopt(), getpass()

²  streadd(), strecpy(), and strtrns()

²  Laços (loops) também podem ocasionar estouro

Capítulo 03

Estouro Buffer

(50)

Seção 1.7 Medidas - Conclusões

Capítulo 03

Estouro Buffer

(51)

²  Estouro de Buffer pode ser devastador

²  C / C++ / Objective-C è vulneráveis

²  Tentar linguagens seguras (e.g. Java, Python)

²  Tornar a localização da pilha (stack) aleatória

²  Usar verificação em tempo de execução

²  StackGuard

²  Libsafe

²  SafeC

²  Teste da Caixa Preta (e.g. eEye Retina, ISIC)

Capítulo 03

Estouro Buffer

(52)

²   Referências

²  Conference on Software Security : Aleph One, Smashing the Stack for Fun and Profit. Originally published in

Phrack 49-14.1996

²  IEEE Reference : Buffer Overflows: Attacks and Defenses for the Vulnerability of the Decade*

²  Pincus, Jonathan,”Beyond Stack Smashing: Recent Advances in Exploiting Buffer Overruns”, IEEE

Security&Privacy

Capítulo 03

Estouro Buffer

(53)

Texto – Fonte Arial Normal – Máx.14pt / Mín.12pt – Preto – Centralizado

Referências

Documentos relacionados

l  onde &lt;tabela&gt; é o nome de uma tabela ou uma expressão de álgebra relacional que resulta em uma tabela e &lt;critério de seleção&gt; é uma expressão

A propósito, o aumento do valor absoluto máximo, bem como dos critérios para a fixação do valor relativo das sanções pecuniárias aplicáveis por essas entidades foi uma

No presente trabalho observou-se um aumento significativo da densidade básica da madeira com o aumento da idade (Figura 6), sendo que, somente aos sete anos, foram

Parágrafo quarto – Usuário internos Professores podem quitar multas através da doação de obras. relacionadas aos cursos que ministram na instituição e que não estejam na

­ Erros deste tipo em programas maiores podem levar à bugs desastrosos, 

VUOLO, J.H. Fundamentos da Teoria de Erros, Edgard Blucher Ltda, São Paulo, 1992 YIN, R.K. Estudo de caso: planejamento e métodos, Bookman, Porto Alegre, 2005.. Quando a

Preocupado com as iniqüidades que se verificam nas condições de saúde da população e no acesso aos serviços de saúde e a outros serviços públicos que influenciam a situação

Essa propensão faz com que o grafite se transcodifique também para outras áreas, como o design e a publicidade, o que, consequentemente, abre novos campos de