Stack canary

Origem: Wikipédia, a enciclopédia livre.
Saltar para a navegação Saltar para a pesquisa

Stack canaries é um termo referente a uma antiga pratica que utiliza canários em uma mina de carvão, onde os animais seriam afetados pelos gases tóxicos antes dos mineiros.

Esse método é utilizado para detectar stack buffer overflow antes que a execução de um código malicioso possa ocorrer. Este método funciona utilizando um numero inteiro baixo que é colocado na memória antes do return pointer da pilha, esse valor é escolhido aleatoriamente quando o programa é iniciado.

A maioria dos buffer overflows sobrescrevem os endereços de memória de baixo para cima, ou seja, ao substituir o return pointer, para poder obter controle do processo, o valor do canário também é sobrescrito. Esse valor é verificado para garantir que o mesmo não foi modificado depois que a rotina usa o return pointer da pilha. Essa técnica pode aumentar a dificuldade de exploração da pilha utilizando buffer overflows, pois força o atacante a tentar ganhar controle do instruction pointer através de técnicas não tradicionais, tais como corromper outras variáveis importantes da pilha.

StackGuard[editar | editar código-fonte]

StackGuard foi lançado pelo GCC no ano de 1997, e publicado no USENIX Security 1998. É uma extensão para o GCC que proporciona uma proteção ao buffer overflow. Foi criado por Crispin Cowan, primeiramente com o zero canary nos processadores i386 backend para o GCC 2.7.2.2 por Aaron Grier e verificado por Peat Bakke. Perry Wagle continuou a manutenção do StackGuard para o Immunix project, implementando o Terminator, Random, and Random XOR canaries. StackGuard foi disponibilizado como uma parte padrão da distribuição Linux Immunix 1998-2003. StackGuard foi sugerido para implementação no GCC de acordo com o GCC 2003 Summit Proceedings e o site do StackGuard. No entanto o gcc 3.x não oferece nenhuma proteção oficial contra buffer overflow e o conceito SSP abaixo foi adaptado para GCC 4.1 em seu lugar.

GCC Stack-Smashing Protector (ProPolice)[editar | editar código-fonte]

O "Stack-Smashing Protector" ou SSP, também conhecido como ProPolice, é um aprimoramento do conceito StackGuard escrito e mantido por Hiroaki Etoh da IBM. Seu nome deriva da palavra própolis. ProPolice difere da StackGuard de três maneiras:

  • ProPolice move a geração de código canário do back-end para o front-end do compilador.
  • ProPolice também protege todos os registradores salvos no prólogo da função e não somente o Return Address.
  • Adicionalmente o conceito do ProPolice, quando possível, protege variáveis do tipo array, dificultando o estouro de outras variáveis. Também cria copias dos argumentos das funções. realocando-as junto das variáveis locais.

Foi implementado um patch to GCC 3.x e uma representação menos intrusiva esta incluída no GCC 4.1. Atualmente o SSP vem por padrão no OpenBSD, FreeBSD (desde 8.0), Ubuntu (desde 6.10), Hardened Gentoo (GCC 4.x) e DragonFly BSD, NetBSD (x86). No Debian e Gentoo por padrão tem o SSP desabilitado.

Técnicas[editar | editar código-fonte]

Existe três tipos de técnicas em uso: Terminator, Random, e Random XOR. A versão atual do StackGuard suporta as três enquanto o ProPolice suporta Terminator e Random canaries.

Terminator Canaries: A maioria dos ataques de buffer overflow são baseados em algumas operações de strings que acabam nos Terminators. Portanto os canaries são criados de termina dores nulos, CR, LF, e -1. O problema é que o resultado do canário é conhecido, possibilitando ao atacante sobrescrever o valor já conhecido, podendo assim controlar os valores de returno passado pelo verificação do canário.

Random canaries: Os valores são gerados aleatoriamente, normalmente utilizando EGD (entropy-gathering daemon), para evitar que o atacante descubra o valor do canário. Normalmente não é logicamente plausível ler o valor do canário para poder explorá-lo, já que o mesmo é um valor conhecido apenas por que precisa saber.

Normalmente o valor aleatório do canário é gerado na inicialização do programa e armazenado em uma variável global. Essa variável é preenchida normalmente por paginas não mapeadas, de forma que a tentativa de lê-lo usando qualquer tipo de truques que exploram bugs para ler a memória RAM causa um segmentation fault terminando a execução do programa. Mesmo assim ainda é possível ler o valor do canário, se o atacante conhecer onde ele se encontra ou pode fazer com que o programa leia o valor da pilha.

Random XOR Canaries: São Random Canaries que tem seus valores de controle ou parte deles embaralhados com um XOR. Desta forma, uma vez que o canário ou os dados de controlo é substituído, o valor canário será errado.

Possuem a mesma vulnerabilidade do Random Canaries, exceto quando o atacante utiliza algum método que lê as informação da memória a obtenção do canário tornasse mais complicada. O atacante deve obter além do valor do canário, precisa do algoritmo e do controle de dados que originalmente gerou o canário, para obter o valor original do canário.

Adicionalmente podem proteger contra um tipo de ataque envolvendo overflowing a buffer in a structure em um ponteiro alterando-o para um pedaço de dados de controlo. Por causa da codificação XOR, o canário estará errado se os dados de controle ou valor de retorno é alterado. Por causa do ponteiro, os dados de controle ou valor de retorno pode ser alterado sem sobrescrever o valor do canário.

Embora estes canários protejam os dados de controle de ser alterado por ponteiros sobrepostos, eles não protegem quaisquer outros dados ou os próprios ponteiros. Ponteiros de função, especialmente, são um problema, já que podem ser explorados para executar shellcode quando chamado.

Ver Também[editar | editar código-fonte]