Introdução aos Sistemas de Informações Unidade Didática 6: Segurança e Auditoria de Sistemas.
Segurança e auditoria de sistemas
-
Upload
vanna-wilkinson -
Category
Documents
-
view
14 -
download
0
description
Transcript of Segurança e auditoria de sistemas
![Page 1: Segurança e auditoria de sistemas](https://reader035.fdocumentos.tips/reader035/viewer/2022062517/5681367d550346895d9e0b74/html5/thumbnails/1.jpg)
Segurança e auditoria de sistemas
Carlos Oberdan Rolim
Ciência da ComputaçãoSistemas de Informação
![Page 2: Segurança e auditoria de sistemas](https://reader035.fdocumentos.tips/reader035/viewer/2022062517/5681367d550346895d9e0b74/html5/thumbnails/2.jpg)
Exploiting Buffer Overflow
![Page 3: Segurança e auditoria de sistemas](https://reader035.fdocumentos.tips/reader035/viewer/2022062517/5681367d550346895d9e0b74/html5/thumbnails/3.jpg)
Estatísticas
40% dos sites comprometidos usam senhas fracas.
35% devido a exploits de buffer overflow.
10% devido a descuidos administrativs
8% devido a helicópteros pretos
2.600% a IP spoofing.
![Page 4: Segurança e auditoria de sistemas](https://reader035.fdocumentos.tips/reader035/viewer/2022062517/5681367d550346895d9e0b74/html5/thumbnails/4.jpg)
Popularidade do buffer overflow
Pesquisar na web por “buffer overflow exploit”.
Verificar sites como alt.2600, rootshell.com, antionline.com – pode ser encontradas longas listas de exploits baseadas em buffer overflow.
Até mesmo a versão original do ssh tinha um problema com buffer!
![Page 5: Segurança e auditoria de sistemas](https://reader035.fdocumentos.tips/reader035/viewer/2022062517/5681367d550346895d9e0b74/html5/thumbnails/5.jpg)
Exemplos
(In)famous: Morris worm (1988)gets() in fingerd
Code Red (2001)MS IIS .ida vulnerability
Blaster (2003)MS DCOM RPC vulnerability
Mplayer URL heap allocation (2004)% mplayer http://`perl –e ‘print “\””x1024;’`
![Page 6: Segurança e auditoria de sistemas](https://reader035.fdocumentos.tips/reader035/viewer/2022062517/5681367d550346895d9e0b74/html5/thumbnails/6.jpg)
O problema
void foo(char *s) {
char buf[10];
strcpy(buf,s);
printf(“buf is %s\n”,s);
}
…
foo(“thisstringistolongforfoo”);
void foo(char *s) {
char buf[10];
strcpy(buf,s);
printf(“buf is %s\n”,s);
}
…
foo(“thisstringistolongforfoo”);
![Page 7: Segurança e auditoria de sistemas](https://reader035.fdocumentos.tips/reader035/viewer/2022062517/5681367d550346895d9e0b74/html5/thumbnails/7.jpg)
Conceito de Buffer Overflow
O principio de explorar o buffer overflow é sobrescrever partes da memoria que supostamente nao poderia ser sobreescritas com codigos arbitrarios fazendo o processo executar esse codigo
![Page 8: Segurança e auditoria de sistemas](https://reader035.fdocumentos.tips/reader035/viewer/2022062517/5681367d550346895d9e0b74/html5/thumbnails/8.jpg)
Exploitation
A idéia geral é fornecer ao programa (servidores) strings grandes que vão estourar o buffer.
Para servidres com códigos problemáticos é fácil derrubar o código.
As vezes é possível fazer o servidor fazer qualquer coisa (!!!) ao invés de derrubá-lo.
![Page 9: Segurança e auditoria de sistemas](https://reader035.fdocumentos.tips/reader035/viewer/2022062517/5681367d550346895d9e0b74/html5/thumbnails/9.jpg)
Conhecimento necessário
Funções C e pilha (stack)
Um pouco de conhecimento em linguagem assembly.
Saber como as chamadas de sistema são efetuadas (em nível de máquina).
exec() system calls
Como “adivinhar” alguns parâmetros.
![Page 10: Segurança e auditoria de sistemas](https://reader035.fdocumentos.tips/reader035/viewer/2022062517/5681367d550346895d9e0b74/html5/thumbnails/10.jpg)
Dependência de CPU/OS
Construir um exploit requerer alguns conhecimentos específicos do sistema operacional alvo e da arquitetura usada.
Apesar de poucas diferenças o conceito é o mesmo
![Page 11: Segurança e auditoria de sistemas](https://reader035.fdocumentos.tips/reader035/viewer/2022062517/5681367d550346895d9e0b74/html5/thumbnails/11.jpg)
Chamada em C e a pilha
Quando uma chamada a uma função é feita o When a function call is made, the return address is put on the stack.
Often the values of parameters are put on the stack.
Usually the function saves the stack frame pointer (on the stack).
Local variables are on the stack.
![Page 12: Segurança e auditoria de sistemas](https://reader035.fdocumentos.tips/reader035/viewer/2022062517/5681367d550346895d9e0b74/html5/thumbnails/12.jpg)
Direção da pilha
Em sistemas Linux (x86) a pilha cresce dos endereços mais altos para os mais baixos
Colocar algo na pilha conduz ela em direção ao endreço 0.
![Page 13: Segurança e auditoria de sistemas](https://reader035.fdocumentos.tips/reader035/viewer/2022062517/5681367d550346895d9e0b74/html5/thumbnails/13.jpg)
Buffer na pilha
Imagine um servidor web com a seguinte função:
void func(char *str) {
char buf[126];
strcpy(buf,str);
}
Quando essa função é invocada um novo frame com variáveis locais é colocado na pilha
Aloca buffer local(126 bytes reservados na pilha)
Copia o argumento no buffer local
Top ofstack
Stack grows this way
buf sfpret
addr str
Local variables
Frame of thecalling function
Execute code at
this address after func()
finishes
ArgumentsPointer toprevious
frame
![Page 14: Segurança e auditoria de sistemas](https://reader035.fdocumentos.tips/reader035/viewer/2022062517/5681367d550346895d9e0b74/html5/thumbnails/14.jpg)
E se o buffer for sobreescrito ??
Ponteiro de memória para str é copiado na pilha…
void func(char *str) {
char buf[126];
strcpy(buf,str);
}
Se uma string maior que 126 bytes é copiada no buffer, ela vai sobrescresver as posições adjacentes da pilha
strcpy NÃO verifica se a string em *str contém mais que 126 caracteres
buf str
Isto sera interpretado como
o endereço de retorno!
overflowTop ofstack
Frame of thecalling function
![Page 15: Segurança e auditoria de sistemas](https://reader035.fdocumentos.tips/reader035/viewer/2022062517/5681367d550346895d9e0b74/html5/thumbnails/15.jpg)
Executando o código
Imagine que o buffer contém uma string com código malicioso
Se por exemplo, *str contém uma string recebida via rede como entrada de algum serviço
Quando a função termina, o código nobuffer vai ser executado
fornecendo uma shell ao atacante
Root shell se o programa exploitado rodar como setuid root
code str Frame of thecalling function
ret
Atacante coloca instruçòes assembly nessa string de entrada, exemplo
Código binário de execve(“/bin/sh”)
Nessa área, um ponteiro apontando de volta para o buffer aparece onde o sistema
esperava pelo retorno de endereço
Top ofstack
![Page 16: Segurança e auditoria de sistemas](https://reader035.fdocumentos.tips/reader035/viewer/2022062517/5681367d550346895d9e0b74/html5/thumbnails/16.jpg)
“Smashing the Stack”*
A idéia é encher o buffer para ele sobrescrever o endereço de retorno.
Quando uma função termina ela vai para um endereço na pilha.
Nós colocamos algum código no buffer e apontamos o endereço de retorno para ele!
*taken from the title of an article in Phrack 49-7
![Page 17: Segurança e auditoria de sistemas](https://reader035.fdocumentos.tips/reader035/viewer/2022062517/5681367d550346895d9e0b74/html5/thumbnails/17.jpg)
Antes e depois void foo(char *s) {
char buf[100];
strcpy(buf,s);
…
address of sreturn-address
saved sp
buf
address of spointer to pgm
Small Program
![Page 18: Segurança e auditoria de sistemas](https://reader035.fdocumentos.tips/reader035/viewer/2022062517/5681367d550346895d9e0b74/html5/thumbnails/18.jpg)
Observações
Como nós sabemos para onde o ponteiro deve apontar (novo endereço de retorno)
É o endereço do buffer, mas como nós vamos saber onde é esse endereço?
Como nós contruimos o “small program” e colocamos ele em uma string ?
![Page 19: Segurança e auditoria de sistemas](https://reader035.fdocumentos.tips/reader035/viewer/2022062517/5681367d550346895d9e0b74/html5/thumbnails/19.jpg)
Adivinhando o endereço
Geralmente o código fonte é necessário para estimar o endereço de retorno e o endereço do buffer.
Uma estimativa geralmente é o suficiente!
![Page 20: Segurança e auditoria de sistemas](https://reader035.fdocumentos.tips/reader035/viewer/2022062517/5681367d550346895d9e0b74/html5/thumbnails/20.jpg)
Construindo o “small program”
Tipicamente o exploit coloca no buffer um exec().
Outras vezes altera senhas, outras arquivos, outras abre portas….
![Page 21: Segurança e auditoria de sistemas](https://reader035.fdocumentos.tips/reader035/viewer/2022062517/5681367d550346895d9e0b74/html5/thumbnails/21.jpg)
exec()
In Unix, the way to run a new program is with the exec() system call.
There is actually a family of exec() system calls…
This doesn't create a new process, it changes the current process to a new program.
To create a new process you need something else ( fork() ).
![Page 22: Segurança e auditoria de sistemas](https://reader035.fdocumentos.tips/reader035/viewer/2022062517/5681367d550346895d9e0b74/html5/thumbnails/22.jpg)
Exemplo exec()
#include <stdio.h>
char *args[] = {"/bin/ls", NULL};
void execls(void) {
execv("/bin/ls",args);
printf(“I’m not printed\n");
}
![Page 23: Segurança e auditoria de sistemas](https://reader035.fdocumentos.tips/reader035/viewer/2022062517/5681367d550346895d9e0b74/html5/thumbnails/23.jpg)
Gerando uma string
Pega-se o código desejado (exemplo do slide anterior) e gera linguagem de máquina.
Copia-se os valores indiduais dos bytes e constroi-se uma string.
Um exemplo simples requerer menos de 100 bytes.
![Page 24: Segurança e auditoria de sistemas](https://reader035.fdocumentos.tips/reader035/viewer/2022062517/5681367d550346895d9e0b74/html5/thumbnails/24.jpg)
Exemplo de programa/string
Exemplo de um exec() com /bin/ls: exec(‘/bin/ls’)
unsigned char cde[] =
"\xeb\x1f\x5e\x89\x76\x08\x31\xc0”
“\x88\x46\x07\x89\x46\x0c\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/ls";
![Page 25: Segurança e auditoria de sistemas](https://reader035.fdocumentos.tips/reader035/viewer/2022062517/5681367d550346895d9e0b74/html5/thumbnails/25.jpg)
Algumas considerações importantes
O “small program” deve rodar em qualquer posição da memória não sendo dependente de uma posição
Ele não pode ser grande ou então colocaremos o programa e o novo endereço de retorno na pilha
![Page 26: Segurança e auditoria de sistemas](https://reader035.fdocumentos.tips/reader035/viewer/2022062517/5681367d550346895d9e0b74/html5/thumbnails/26.jpg)
Sample Overflow Programunsigned char cde[] = "\xeb\x1f\…
void tst(void) {
int *ret;
ret = (int *)&ret+2; // pointer arith!
(*ret) = (int) cde; //change ret addr
}
int main(void) {
printf("Running tst\n");
tst();
printf("foo returned\n");
}
![Page 27: Segurança e auditoria de sistemas](https://reader035.fdocumentos.tips/reader035/viewer/2022062517/5681367d550346895d9e0b74/html5/thumbnails/27.jpg)
Atacando um programa
Relembrando: a idéia é fornecer ao servidor uma string grande capaz de estourar o tamanho do buffer.
Esta string estoura o buffer e sobreescreve o endereco de retorno na pilha.
Assumindo que nos colocamos o nosso “small program” em uma string nós precisamos saber seu endereço
![Page 28: Segurança e auditoria de sistemas](https://reader035.fdocumentos.tips/reader035/viewer/2022062517/5681367d550346895d9e0b74/html5/thumbnails/28.jpg)
NOPs
Várias CPUs possuem a No-Operation instruction – ela não faz nada somente avança o ponteiro de instrução.
Usualmente podemos colocar várias NOOP na frente do nosso programa (na string).
Se o novo endereço de retorno apontar para um NOP está OK.
![Page 29: Segurança e auditoria de sistemas](https://reader035.fdocumentos.tips/reader035/viewer/2022062517/5681367d550346895d9e0b74/html5/thumbnails/29.jpg)
Using NOPs
Programa real
(exec /bin/ls ou outra coisa)
Novo endereço de retorno
Instruções nop
Pode apontar
para qualquer
lugar a
qui
![Page 30: Segurança e auditoria de sistemas](https://reader035.fdocumentos.tips/reader035/viewer/2022062517/5681367d550346895d9e0b74/html5/thumbnails/30.jpg)
Estimando o tamanho da pilha
Pode ser adivinhado a localização do endereço de retorno relativo ao buffer estourado.
Colocar ele em vários novos endereços de retorno!
![Page 31: Segurança e auditoria de sistemas](https://reader035.fdocumentos.tips/reader035/viewer/2022062517/5681367d550346895d9e0b74/html5/thumbnails/31.jpg)
Estimando a localização
Program real
Novo endereço de retorno
Instruções nop
Novo endereço de retorno
Novo endereço de retornoNovo endereço de retorno
Novo endereço de retornoNovo endereço de retorno
![Page 32: Segurança e auditoria de sistemas](https://reader035.fdocumentos.tips/reader035/viewer/2022062517/5681367d550346895d9e0b74/html5/thumbnails/32.jpg)
vulnerable.c
void foo( char *s ) {
char name[200];
strcpy(name,s);
printf("Name is %s\n",name);
}
int main(void) {
char buf[2000];
read(0,buf,2000);
foo(buf);
}
void foo( char *s ) {
char name[200];
strcpy(name,s);
printf("Name is %s\n",name);
}
int main(void) {
char buf[2000];
read(0,buf,2000);
foo(buf);
}
![Page 33: Segurança e auditoria de sistemas](https://reader035.fdocumentos.tips/reader035/viewer/2022062517/5681367d550346895d9e0b74/html5/thumbnails/33.jpg)
genpgm.c
genpgm.c foi construido para estourar o buffer do programa vulnerable.c
Ele permite ao usuário acrescer um deslocamento para um endereço fixo imaginado (“xute”) que seja o endereço de retorno da pilha.
Ele escreve (para stdout) uma string contendo vários endereços de retorno e um programa que executa um : exec /bin/ls.
![Page 34: Segurança e auditoria de sistemas](https://reader035.fdocumentos.tips/reader035/viewer/2022062517/5681367d550346895d9e0b74/html5/thumbnails/34.jpg)
Testando
./genpgm 16 | ./vulnerable
Seja ambicioso!!!! Troque a saída do programa genpgm para exec /bin/sh!
(./genpgm; cat) | ./vulnerable
![Page 35: Segurança e auditoria de sistemas](https://reader035.fdocumentos.tips/reader035/viewer/2022062517/5681367d550346895d9e0b74/html5/thumbnails/35.jpg)
Maiores informações
Leitura obrigatória Smashing the Stack for Fun and Profit
Recomendado Exploiting Format String Vulnerabilities
Recomendado Blended Attacks by Chien and Szor para entender melhor buffer overflows e como eles são usados em worms internet
Opcional: The Tao of Windows Buffer Overflow by DilDog (Cult of the Dead Cow)