[0x18] Proteções de memória

Editorial Team
9 Min Read


  

Este tutorial faz parte do GUIA COMPLETO do skilled em Segurança Ofensiva de Software program, saiba mais.

Aula 24: Proteções

Os ataques de exploração de vulnerabilidades, especialmente os que envolvem corrupção de memória como buffer overflows, motivaram o desenvolvimento de uma série de mecanismos de segurança no nível do sistema operacional e do compilador. Estas proteções de memória são barreiras essenciais que dificultam a execução de código malicioso e o desvio do fluxo de execução de um programa.

Aula 24.1: Canários

Os Cookies (também conhecidos como Canários) são um mecanismo criado para proteger contra ataques de transbordamento de buffer de pilha (stack buffer overflow).

  • Origem do Nome: O termo “Canário” tem origem histórica, referindo-se aos pássaros utilizados em minas para alertar sobre a baixa concentração de oxigénio — um alerta precoce de perigo.
  • Funcionamento: É um marcador aleatório inserido na pilha, posicionado estrategicamente entre um buffer native (como uma variável string) e o endereço de retorno da função. Se ocorrer um transbordamento no buffer, o atacante terá de sobrescrever o cookie antes de atingir o endereço de retorno.
  • Verificação: Uma instrução de checagem é inserida no epílogo (o ultimate) da função. Antes de usar o endereço de retorno, a função verifica se o valor do cookie foi alterado. Se o valor for diferente do authentic, o sistema detecta o ataque e aborta o processo.
Figura 1: Exemplo de COOKIE
  • Implementação: Pode ser inserido em tempo de compilação (método mais comum, como no GCC com a flag -fstack-protector e no Visible Studio com /GS) ou em tempo de execução por meio de “funções empacotadoras” (wrappers), sendo esta última opção usada para proteger sistemas legados sem a necessidade de recompilação, embora acarrete um overhead de desempenho.
  • Bypass: Técnicas avançadas, como a exploração de Tratadores de Exceções Estruturadas (SEH) no Home windows, permitiam que o atacante desviasse o fluxo do programa para código malicioso antes que a checagem do cookie fosse realizada.

Aula 24.2: SafeSEH e SEHOP

SafeSEH (Protected Structured Exception Dealing with) e SEHOP (Structured Exception Dealing with Overwrite Safety) são proteções específicas do ambiente Home windows, desenvolvidas para mitigar a exploração de uma vulnerabilidade na forma como o sistema lida com exceções estruturadas.

  • Motivação: Os ponteiros para os tratadores de exceção ficavam na pilha e podiam ser sobrescritos antes da checagem do cookie.
  • Objetivo: Estas proteções asseguram a integridade da cadeia de tratadores de exceção na pilha, impedindo que um atacante a corrompa para desviar a execução para o seu código.

Aula 24.3: ASLR

Handle House Structure Randomization (ASLR), e seu análogo Rebase, é uma técnica basic para combater ataques de reutilização de código.

  • Funcionamento: Embaralha (randomiza) os endereços de memória de áreas-chave do processo, como a pilha, o heap e as bibliotecas dinâmicas (DLLs ou bibliotecas compartilhadas), a cada inicialização do programa ou do sistema.
  • Objetivo: Ao tornar os endereços imprevisíveis, o ASLR impede que um atacante saiba para onde desviar o fluxo de execução (ex: um endereço de uma função útil em ROP), o que tornaria a maioria dos ataques de reutilização de código ineficazes.
  • Implementação: Está implementado no Linux (kernel 2.6.12+), com a randomização ocorrendo durante a carga do processo, e no Home windows (Vista/Server 2008+), com a randomização feita durante a inicialização do sistema operacional.
  • Bypass: Pode ser contornado se um binário ou biblioteca não for compilado com a flag de suporte a ASLR (ex: /DYNAMICBASE), fixando seus endereços. Outros bypasses incluem o uso de heap spraying, vazamento de endereços de memória ou técnicas de força bruta.

Aula 24.4: Pilha Não-Executável (nx-stack)

A proteção nx-stack (Non-Executable Stack) impede que um atacante execute instruções na área de memória da pilha (stack) de um processo.

  • Funcionamento: Marca a região da pilha como não-executável, prevenindo a execução de shellcode injetado na pilha.
  • Implementação: É uma proteção basic implementada desde 1996 nos principais sistemas operacionais, incluindo Linux, OpenBSD, Mac OS X, Solaris e Home windows.

Aula 24.5: DEP

Prevenção de Execução de Dados (DEP), também conhecida pelo princípio Write xor Execute (W^X), é uma proteção implementada no {hardware} (pelo bit NX/XD) e no sistema operacional.

  • Funcionamento: Impede que o código seja executado a partir de páginas de memória marcadas como dados, como as regiões de pilha (stack) e heap.
  • Objetivo: É uma medida primária contra a injeção de código, complementando a nx-stack ao estender a proteção a outras áreas de dados do processo.
  • Implementação: Está presente em sistemas como Linux (kernel 2.6.8+) e Home windows (XP SP2+), sendo ativada em binários compilados com flags específicas (ex: /NXCOMPACT no Visible Studio).
  • Bypass: A DEP pode ser contornada por técnicas de reutilização de código, como Return-Oriented Programming (ROP) ou ret2libc, que utilizam trechos de código legítimo do próprio programa ou das suas bibliotecas para executar ações maliciosas.

Aula 24.6: Filtros de dados

Os Filtros de Dados atuam na sanitização e validação da entrada (enter) de um programa, sendo uma linha de defesa essential contra vulnerabilidades que se originam de dados não confiáveis.

  • Objetivo: Garantir que o dado introduzido por um utilizador ou por outra fonte externa seja seguro, restringindo a sua forma e conteúdo ao que é estritamente esperado.
  • Exemplos de Restrições:
    • Tamanho: Limitar o comprimento de uma string para evitar buffer overflows (ex: máximo de 256 bytes).
    • Tipo de Caracteres (whitelist): Permitir apenas um conjunto restrito de caracteres (ex: nome de arquivo só pode ter letras, números e hifens: a-z, A-Z, 0-9, -).
    • Caracteres “Badchars”: Remover ou codificar caracteres que têm um significado especial e perigoso no contexto de um ataque, como o Byte Nulo (0x00), que é usado para terminar strings e pode parar a execução de um shellcode.
  • Bypass: A técnica de bridge constructing é um exemplo de como atacantes tentam codificar blocos de instruções ou instruções individuais para evitar a detecção por filtros que procuram por badchars no código injetado.

Aula 24.7: Assinaturas

O conceito de Assinaturas é amplamente utilizado por sistemas de deteção de intrusão, antivírus e outros softwares de segurança para identificar a presença de código malicioso conhecido.

  • Funcionamento: Uma assinatura é uma sequência de bytes única de um malware ou de um binário de ataque conhecido. O sistema de segurança compara o binário (ou partes dele) com uma base de dados de assinaturas (muitas vezes otimizada com tabelas hash para agilidade).
  • Aplicação: Usado por Antivírus, Sistemas de Prevenção de Intrusão (IPS), entre outros.
  • Bypass: Os atacantes utilizam diversas técnicas para alterar o código malicioso sem mudar a sua funcionalidade, fugindo assim à deteção baseada em assinaturas:
    • Encoders/Ofuscação de Código: Codificam o shellcode para que a sequência de bytes não corresponda à assinatura authentic.
    • Inserção de Lixo (Junk Code): Adicionam instruções inócuas para modificar o padrão de bytes do programa.
    • Troca de Instruções/Registos: Substituem instruções equivalentes (ex: usar PUSH/POP em vez de MOV) ou trocam registos e variáveis entre operações para criar um binário funcionalmente idêntico, mas com uma assinatura de bytes diferente.
Próxima aula, clique aqui.

Share This Article