1 - Introducao2 - O Problema 3 - A Exploitacao 4 - Expansao do Conceito5 - Terminando 5.1 - Links e Referencias 5.2 - Consideracoes Finais 5.2 - AgradecimentosOs ataques de Buffer Overflows parecem que ainda perdurarao por algum tempo. Apesar dos esforcos de grande parte da Comunidade de Seguranca, os exemplos de condicoes de overflow permanecem como uma "constante" entre os aplicativos de um modo geral.Ate onde eu conheco, o conceito de buffer overflow eh apenas um, no entanto, as tecnicas para implementacao deste conceito sao diversas. E ate onde eu sei, o Mudge(antiga L0pht, hoje @stake), foi o primeiro a expandir para as massas o conceito de buffer overflows. Desde o worm (Robert Morris, 1988) ate os nossos dias, muitos programadores tem procurado diminuir as condicoes de buffer overflows em programas que manipulam parametros recebidos de um usuario, substituindo funcoes conhecidas como vulneraveis(strcpy, gets, sprintf) por funcoes que necessariamente fazem checagem do tamanho dos parametros recebidos (strncpy, snprintf, etc).No dia 01 de maior de 2000, twich (twitch@vicar.org) tornou manifesto uma tecnica capaz de exploitar espacos de memoria adjacente, especificamente o manuseio incorreto das funcoes ditas seguras(strcnpy, por exemplo). As Analises de codigo-fonte(auditoria) passaram agora a incluir todo tipo de funcoes, demonstrando assim que nao basta apenas a funcao fazer a checagem do tamanho dos parametros, mas outros fatores passaram a ser essenciais.Neste documento abordaremos esta tecnica. Conhecimentos em C, Assembly (AT&T), escrita de exploits(ver docs da Unsek Scene) e Linux se fazem necessarios. E principalmente mentalidade fucadora!O problemaPodemos descrever basicamente o problemas com as funcoes ditas seguras (strncpy, strncat, etc) eh que elas nao sao capazes de terminar automaticamente os buffers ou strings com um NULL. Como assim?Vejamos nosso primeiro codigo inicial:/* Exemplo de strncpy()*/#include <stdio.h>#include <string.h> int main(int argc, char *argv[]){char buffer[256]; /* Iremos copiar argv[1] para buffer e imprimir */strncpy(buffer,argv[1],sizeof(buffer)); /* Iremos imprimir o tamanho da string recebida em argv[1] */printf("strlen: %d | sizeof: %d\n",strlen(buffer), sizeof(buffer));return 0;}Como sabemos, strcnpy() ira copiar os dados recebidos da linha decomando ateh chegar o tamanho de buffer(sizeof(buffer)) ou atehreceber um NULL(\0), vejamos um exemplo de execucao:kimera3:/work/testes# ./b1 `perl -e 'print "A" x 255'`strlen: 255 | sizeof: 256A "anomalia" ocorre quando digitamos mais dados que o tamanho dobuffer de espera. Vejamos:kimera3:/work/testes# ./b1 `perl -e 'print "A" x 256'`strlen: 265 | sizeof: 256kimera3:/work/testes# ./b1 `perl -e 'print "A" x 257'`strlen: 265 | sizeof: 256Como podemos notar strlen() contem um tamanho superior ao esperado. Isso ocorre porque strncpy() nao recebeu o caracter NULL e de alguma forma uniu dados ateh encontrar um NULL. Podemos clarear mais analisando o programa abaixo:/* Exemplo 2 de strncpy() */#include <stdio.h>#include <string.h>int main(int argc, char *argv[]){char buffer1[20], buffer2[8]; /* Iremos copiar argv[1] para buffer1 */strncpy(buffer1,argv[1],sizeof(buffer1)); /* Iremos copiar buffer1 para buffer2 */strncpy(buffer2,buffer1,sizeof(buffer2)); /* Iremos imprimir agora o conteudo de buffer2 */printf("Buffer2: %s\n",buffer2);return 0;}Executando este programa, teoricamente deveriamos ter a saida de buffer2, ou seja, uma string contendo 8 caracteres.Mas vejamos:kimera3:/work/testes# ./b2 NashLeonBuffer2: NashLeonNashLeonNashLeonNashLeon Possue 16 caracteres.No mais a gente pode brincar com isso:kimera3:/work/testes# ./b2 NashLeonUnsekBuffer2: NashLeonNashLeonUnsekkimera3:/work/testes# ./b2 NashLeonUnsekSceneBuffer2: NashLeonNashLeonUnsekScenekimera3:/work/testes# ./b2 NashLeonUnsekSceneAgainBuffer2: NashLeonNashLeonUnsekSceneAgxuyca@Ele imprime justamente porque o strncpy() nao encontrou o