Desafio da Semana #9


DESAFIO DA SEMANA #9

Por: Roberto Alexis Farah

Olá pessoal!

O Desafio da Semana de hoje é algo atípico e que foge da minha filosofia de colocar problemas simples e ao mesmo tempo difíceis de serem isolados quando em ambiente de produção, muitas vezes sem código fonte, sem reprodução consistente, etc...

O desafio de hoje é sobre como explorar um buffer overflow!

A maioria dos incidentes que trabalhamos onde a causa raiz é buffer overflow não são explorados por hackers. E os que são ou que haja suspeitas de serem são tratados pelo time de segurança, onde há engenheiros especializados em segurança.

Minha idéia inicial era de fazer um artigo e não um desafio, para explicar como um buffer overflow é explorado, fazendo a “demonstração matemática” como venho fazendo nos desafios para explicar como determinado problema ocasiona determinado sintoma.

Mas mudei de idéia e resolvi fazer um desafio.

Portanto, vamos a ele.

 

CENÁRIO

Você é um desenvolvedor em uma empresa de software e seu gerente ou um colega de trabalho te desafia a identificar se uma determinada aplicação tem furo de segurança e como explorá-lo. Você não tem acesso ao código fonte. (ok você tem porque estou enviando aqui, mas finja que não tem J )

Para isso, você precisará de:

- Conhecimento de Assembly,

- Usar um depurador de sua preferência, no caso usei o Windbg,

- Usar um disassemblador de sua preferência, pode ser o DumpBin que vem no Visual Studio,

- Usar um pequeno script em Perl.

Eis o código fonte para você criar uma aplicação C console. No caso usei o Visual C++ 6.0. Em versões mais novas desabilite as opções de segurança.

#include <stdio.h>

#include <string.h>

#define PASSWORD "ghij234"

#define BUFFER 9

void RightPassword(void);

void WrongPassword(void);

int main(int argc, char* argv[])

{

     if(argc != 2)

     {

          printf("Invalido numero de argumentos...\n");

      }

      char szPassword[BUFFER];

                                                                                       

      // Agora usamos uma funcao NAO recomendada pela facilidade de

      // ocasionar buffer overflow e em alguns cenarios strings sem o

      // terminador NULL.

      strcpy(szPassword, argv[1]);

                                                                                       

      if(0 == strcmp(szPassword, PASSWORD))

      {

            RightPassword();

      }

      else

     {

            WrongPassword();

      }

                                                                                       

      return 0;

}

void RightPassword(void)

{

     printf("Senha correta! Voce tem acesso...\n");

}

void WrongPassword(void)

{

     printf("Senha incorreta! Seu acesso e' proibido...\n");

}

Compile a aplicação em Visual C++ 6.0 em modo Debug ou, seu usando novas versões do VC++, desabilite proteções de buffer overflow, etc...

Nota: Não é necessário se ter conhecimento do código fonte para se explorar o buffer overflow da aplicação! Forneço ele apenas para que vocês possam construir a aplicação.

SINTOMA

Como no Desafio #8 a aplicação quebra (crash) quando há o buffer overflow.

OBJETIVO

Explore o buffer overflow sem nenhuma alteração no código fonte de modo a fazer a rotina RightPassword() ser chamada com uma senha inválida.

Em seguida, proponha uma mudança no código para evitar o buffer overflow ocasionado por “strcpy()”.

Alerta de frustração: Embora essa exploração seja trivial do ponto de vista de hackers, engenheiros de segurança e outros habituados a depurar código binário, ela é complexa para quem não conhece bem Assembly, depuradores, disassembladores e detalhes internos do funcionamento de aplicações, conhecimento esse que, em minha opinião, não é necessário no ramo de atuação da maioria dos desenvolvedores.