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.