quinta-feira, 21 de agosto de 2014

Da série: Melhor prevenir do que remediar - Stack Overflow



No Geral...

...Ataques de buffer overflow baseiam-se em duas técnicas ( e normalmente a combinação delas):

  1. Escrevendo dados em um endereço específico na memória
  2.  Aproveitar-se do mau manuseio do sistema sobre o tipos de dados

Isso significa que linguagens de programação fortemente tipadas (e ambientes) que desabilitam acesso direto à memória, normalmente previnem buffer overflows de acontecerem.



Linguagem /Ambiente
Compilada ou Interpretada?
Fortemente Tipada?
Acesso direto à memória?
Seguro ou Inseguro?
Java, Java Virtual Machine (JVM)
Ambos
Sim
Não
Seguro
.NET
Ambos
Sim
Não
Seguro
Perl
Ambos
Sim
Não
Seguro
Python - interpretada
Interpretada
Sim
Não
Seguro
Ruby
Interpretada
Sim
Não
Seguro
C/C++
Compilada
Não
Sim
Inseguro
Assembly
Compilada
Não
Sim
Inseguro
COBOL
Compilada
Sim
Não
Seguro

Características de algumas linguagens
Stack Overflow

Stack Overflow (Estouro de pilha) é a forma de buffer overflow mais fácil de entender. Os básicos de stack overflow são simples.




  1. Existem dois buffers, um buffer de origem contendo uma entrada qualquer (presumindo, do atacante) e um buffer de destino que é muito pequeno para a entrada de ataque. O segundo buffer reside na pilha e ao lado do endereço de uma função de retorno na pilha.
  2.  O código 'desatento' não checa se o buffer de origem é grande a ponto de não caber no buffer de destino. Então copia a entrada no buffer de destino, e sobrescreve informações adicionais que estavam vizinhas na pilha (tais como o função de retorno ao lado)
  3. Quando a função retorna, a CPU retira o quadro (agora modificada) do endereço de retorno na pilha.
  4.  Controle não retorna a função como deveria. Ao invés, o código arbitrário (escolhido pelo atacante quando feito na entrada inicial) é executado.

"Não pise no gramado do vizinho, menino!"
O seguinte exemplo, escrito em C, demonstra um exploração de stack overflow:
#include <string.h>

void f(char* s) {
    char buffer[10]; // Tamanho 10
    strcpy(buffer, s);
}

void main(void) {
    f("01234567890123456789"); //Olha o tamanho da entrada!! isso não vai dar coisa boa!
}

[root /tmp]# ./stacktest

Segmentation fault



Como determinar se você é vulnerável


Se o seu programa:

· É escrito em uma linguagem ( ou sobre um programa que é escrito em uma linguagem) que permite que um buffer overflow seja criado (veja tabela acima) E

  • Copia dados de um buffer para outra na pilha sem checar primeiros os tamanhos E
  • Não usa técnicas tais como valores canário ou pilhas não-executáveis para prevenir buffer overflows 
ENTÃO é mais provável que a aplicação seja vulnerável a ataques desse tipo.

Como se proteger

  •  Estabeleça-se em sistemas capazes de usar pilhas não-executáveis, tais como:

    1.  AMD e Intel x86-64 chips com SO de 64 bits associados
    2. Windows XP SP2 (tanto 32 como de 64 bits, e agora SP3 também)
    3. Windows 2003 SP1 (tanto 32 como de 64 bits)
    4.  Linux após 2.6.8 em AMD e processadores x86-64 em modo 32 e 64 bits
    5.  OpenBSD (w^x em Intel, AMD, SPARC, Alpha e PowerPC)
    6.  Solaris 2.6 e mais recentes como a flag “noexec_user_stack” ativada.
  •  Use linguagens de programações de alto nível que são fortemente tipadas e que não permitem acesso direto à memória.
  • Valide entradas de usuário para prevenir que dados inesperados sejam processados, tais como serem muito longos, ou do tipo de dado errado, contendo caracteres "lixo", etc.
  • Caso se baseie em funções do sistema ou utilitários escritos em linguagem vulnerável, certifique-se de que:
    1.  Use do princípio de privilégio "At least"
    2.  Use compiladores que previnem stacks and heap overflows.
    3.  Estão atualizados, na questão de patches.


Fonte:
https://www.owasp.org/index.php/Buffer_Overflow
https://www.owasp.org/index.php/Buffer_Overflows

Nenhum comentário:

Postar um comentário