Introdução
Estou iniciando uma série de artigos onde pretendo escrever sobre vulnerabilidades, shellcodes, exploits e afins.
É uma área que tenho estudado e descobri ser muito interessante, pois envolve assuntos como assembly, engenharia reversa, programação de baixo-nível, segurança, e que também está no contexto dos crimes cibernéticos.
Por exemplo, uma vulnerabilidade no navegador pode ser explorada quando o usuário acessar um site com códigos-maliciosos, possibilitando assim a instalação de malwares.
Ao invés de utilizar ferramentas prontas resolvi iniciar meus estudos do começo, do nível mais baixo, entender como ocorre uma vulnerabilidade, como é feito um exploit e como é criado o shellcode.
Mesmo que as técnicas estejam um pouco ultrapassadas, acho importante ter o conhecimento da base para depois partir para ferramentas como Metasploit. E para aprender mais nada melhor do que ensinar o pouco que sei.
Então, qual seria a vulnerabilidade mais conhecida e simples de entender?
Buffer Overflow
Frequentemente é noticiado que em uma aplicação qualquer foi encontrada a vulnerabilidade de buffer overflow (ou estouro de buffer) e que através dela um atacante consegue executar código arbitrário. O arbitrário quer dizer qualquer código que ele desejar, ou quase isso.
O comunicado abaixo é um exemplo clássico, emitido pelo CERT em 2003:
A buffer overflow vulnerability exists in Microsoft's Remote Procedure Call (RPC) implementation. A remote attacker could exploit this vulnerability to execute arbitrary code or cause a denial of service.
Atualmente a vulnerabilidade de buffer overflow é encontrada com menos frequência pois foram criados vários mecanismos de proteção contra ela. Porém ainda ocorre, como podemos ver nessa notícia mais atual, de 27/01/2011:
Multiple vulnerabilities have been reported in Symantec products, which can be exploited by malicious people to cause a Denial of Service and compromise a vulnerable system, according to Secunia.
1. An error in the Intel AMS2 component when processing certain messages can be exploited to cause a buffer overflow via specially crafted packets sent to TCP port 38292.…Successful exploitation of the vulnerabilities may allow execution of arbitrary code.…The vulnerabilities are reported in the following products: Symantec AntiVirus Corporate Edition Server 10.x and .Symantec System Center 10.x. A solution is to update to version 10.1 MR10.
Afinal, na prática o que é isso de buffer overflow?
Entendendo o Buffer Overflow
Em programação, buffer é uma variável (também conhecida como array ou vetor), um local na memória que armazena uma quantidade X de bytes.
Por exemplo um buffer que tenha capacidade de armazenar 10 bytes, só conseguiria guardar uma palavra de 9 caracteres (cada caracter sendo 1 byte) já que o último precisa ser o caracter nulo para o programa saber que a palavra termina ali.
Então esse código em C estaria correto:
char buffer[10] = {'S', 'E', 'G', 'U', 'R', 'A', 'N', 'Ç', 'A', '\0'};
Uma variável denominada buffer que tem 10 bytes de capacidade de armazenamento recebe uma palavra de 9 caracteres finalizando com o ('\0'). Isso está correto.
Agora o que aconteceria se eu inserisse uma palavra com mais de 9 caracteres?
Eis o buffer overflow! A variável copia somente os 10 primeiros caracteres e o resto estoura, ou transborda, já que não cabe mais nela.
E o resto da sequência após o 10º byte não é descartado, ele sobrescreve o que tiver na memória após a varíavel. Vamos ver um programinha que demonstra isso.
Esse é o código do programa em C:
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[]){
char buffer1[8] = {'B','U','F','F','E','R','1','\0'};
char buffer2[8] = {'B','U','F','F','E','R','2','\0'};
printf("\n[ANTES] Buffer2 contem: %s\n",buffer2);
printf("[ANTES] Buffer1 contem: %s\n\n",buffer1);
strcpy(buffer2,argv[1]);
printf("[DEPOIS] Buffer2 contem: %s\n",buffer2);
printf("[DEPOIS] Buffer1 contem: %s\n\n",buffer1);
return 0;
}
O programa cria uma variável denominada buffer1 com capacidade de armazenamento de 8 bytes e atribui a ela a palavra “BUFFER1” com o caracter nulo finalizando, o mesmo ocorre com a buffer2. Depois exibe o conteúdo de cada uma com o printf.
Na sequência copia para a variável buffer2 o que for passando como argumento na execução do programa e exibe novamente o conteúdo de cada uma.
O programa foi salvo com o nome “overflow.c” e compilado no Linux Debian 3.0 R4 com esse comando:
gcc -o overflow overflow.c
Vejamos algumas execuções do programa com argumentos diferentes:
Na primeira execução foi passada a string “1234567” como argumento para o programa, vemos que ela foi exibida corretamente já que possui 7 bytes e está no limite da capacidade da variável, o programa adiciona o caracter nulo automaticamente ao final da string.
Na segunda execução foi informada a string “12345678” e já vemos aí um buffer overflow. Apesar dela ter 8 bytes (mesma capacidade da variável), ela estourou porque o programa sempre adiciona o nulo ao final. Sendo assim o nulo transbordou o espaço do buffer2 e sobrescreveu o espaço do buffer1.
O mesmo aconteceu na terceira execução, a string foi maior ainda “1234567890123”, dessa vez estourou 5 bytes mais o nulo. A variável buffer1 ficou com esses bytes que passaram da conta.
Detalhe: mesmo a string sendo maior que a variável o programa ainda exibe a string completa no buffer2, isso ocorre porque conforme já mencionado o programa só sabe que um string termina quando ele encontra o nulo.
Caso seja passada como parâmetro uma string maior ainda, o programa irá travar e apresentar um erro de Segmentation falt. Isso ocorre porque a string começa sobrescrever vários segmentos de memória que são utilizados para controlar a execução do programa, isso faz com o que o programa “se perca” e trave. Conhece a famosa tela azul do Windows, the blue screen of death? :)
Nosso programa exibindo o erro de segmentation falt:
Justamente a capacidade da variável sobrescrever o que tiver pela frente na memória torna possível tomar o controle do programa e redirecionarmos a execução do mesmo para o que quisermos, isto é, executar código arbitrário. Ao invés de o programa travar podemos fazê-lo executar um shell.
Isso é assunto para o próximo post!
Obs.: os exemplos aqui apresentados podem variar de acordo com a a versão do sistema operacional e do compilador gcc. Utilizei uma versão antiga do Debian, a 3.0 R4, pois nela ainda não havia sido implementadas técnicas de proteção contra buffer overflow. Em posts futuros irei falar sobre isso também.
Adicionado em 15/03/2011:
Para reproduzir os exemplos desse artigo em distribuições Linux mais atuais é necessário desativar algumas proteções, faça o seguinte:
- Debian e Ubuntu based, desativar ASLR:
echo 0 > /proc/sys/kernel/randomize_va_space
- Red Hat based, desativar ASLR e DEP (ExecShield):
echo 0 > /proc/sys/kernel/exec-shield-randomize
echo 0 > /proc/sys/kernel/exec-shield
- GCC a partir da versão 4.1 compilar com diretiva -fno-stack-protector, exemplo:
gcc -fno-stack-protector -o overflow overflow.c
Ronaldo Lima
crimesciberneticos.com | twitter.com/crimescibernet
Se vc puder faça um post sobre XSS (Cross Site Scripting) que também é uma vulnerabilidade muito conhecida!
ResponderExcluirabraço!
show!!!!!
ResponderExcluirCara ta de parabéns, tudo que li no seu blog consegui entender com facilidade.. Tô gostando se tiver como postar as coisas mais rapido, melhor ainda =D
ResponderExcluirAbraços
Olá Ronaldo, aqui é o Luiz Vieira!
ResponderExcluirRapaz, muito bom o seu post :-) Estou justamente compilando material para um curso sobre desenvolvimento de exploits, e é legal saber que você também se interessa pela assunto, além da análise de malware (são os dois próximos cursos a serem criados por mim: análise de malware e desenvolvimento de exploits).
O que me diz de criarmos uma lista sobre o assunto?
Abração
Luiz
Olá pessoal, agradeço todos os comentários!!
ResponderExcluirEstão anotadas todas as sugestões.
Grande Luiz, legal que tenha gostado do post, achei boa sua ideia, podemos criar uma lista sim. Tenho estudado bastante sobre desenvolvimento de exploits. Vou mandar um email pra vc.
Abraços!
cara muito bom essa explicação sobre buffer overflow. Estou estudando assembly para entender mais sobre exploits, shell codes e malwares.
ResponderExcluirO que vc està estudando para entender sobre estes assuntos e o que eu devo estudar para ficar fera igual vc?
Vlw cara
Olá Anônimo, agradeço os comentários.
ResponderExcluirEsses assuntos estou estudando por esses livros:
1. Gray Hat Hacking The Ethical Hackers Handbook, 3rd Edition (acabou de ser lançado)
2. Hacking: The Art Of Exploitation, 2nd Edition
3. Writing Security Tools and Exploits
4. Shellcoder's Handbook
No site da Amazon dá pra obter mais informações sobre eles, inclusive comprá-los.
Abraço!
Vlw pela dica Ronaldo!
ResponderExcluirEstou pensando seriamente em buscar cursos dos USA porque os cursoa na àrea de Security aqui no brasil està muito fraco. Achei um site de treinamento em security muito fera! (Programa de Segurança InfoSec Institute) Inclusive uns dos gerentes desta escola é um dos principais autores do livro Shellcoder's Handbook (citado por vc)
Estava olhando o curso deles de Ethical Hacking e Hands On Training Segurança, e fiquei cabulado!
Por que será?
Com certeza é por causa do conteúdo do curso deles...
Aqui vai uns dos tópicos falados em um dos cursos de Hacking:
* Escrever exploits de buffer overflow
* dlmalloc Heap Overflow exploits dlmalloc heap overflow
* Win32 Heap Overflow exploits Win32 Heap overflow
* Linux stack overflow exploits Linux explorações de estouro de pilha
* Defeating non-exec stacks Derrotar pilhas non-exec
* Return-to-libc shellcode shellcode Return to libc
* Function pointer overwrites ponteiro de função substitui
* Crafting Injectable Shellcode Crafting Shellcode injetável
* Defeating non-executable stacks Derrotar pilhas não-executável
* Linux LKM Rootkits Rootkits LKM Linux
* Windows Kernel Rootkits Kernel Rootkits Windows
* Reverse engineering training Formação em engenharia reversa
* Vulnerability development and discovery Vulnerabilidade de desenvolvimento e descoberta
* Attacking and blinding IDSs Atacar e cegando IDSs
* Hiding your attacks from IDSs Escondendo seus ataques de IDSs
* Encrypted covert channels Criptografado canais dissimulados
* Global Offset Table Overwrites Global Tabela Offset Overwrites
* Windows Shellcode Windows Shellcode
* Integer Overflows Integer Overflow
* Linux shellcode Linux shellcode
* "no listening port" trojans "Nenhuma porta de escuta" trojans
* A whole day on breaking through enterprise DMZs Um dia inteiro de romper DMZs empresa
* Reconstructing binaries from sniffed traffic Reconstruindo binários de tráfego cheirou
* Circumventing antivirus Engana antivírus
* Bi-directional Spoofed Communication Bi-direcional falsificados Comunicação
* Session fixation fixação de sessão
* Advanced SQL Injection Advanced SQL Injection
* Justifying a penetration test to management and customers Justificando um teste de penetração para a gestão e os clientes
* Defensive techniques técnicas de defesa
Fala pra min Ronaldo. Aonde vejo um curso assim no Brasil?
Os cursos do Brasil parecem que são censurados!
Vlw Ronaldo! Me add no msn pra gente bater um papo
igor anderline rfl anderline arroba msn.com
Abraçs!
http://www.infosecinstitute.com/
ResponderExcluirOlá Igor, muito bom mesmo o curso!!
ResponderExcluirVendo esses tópicos dá vontade de ir correndo lá fazer, vc tem razão não existe nenhum curso avançado no Brasil sobre esses temas.
Será que falta mercado para esses cursos ou falta profissional qualificado para passar esses conhecimentos no Brasil?
Cursos similares no exterior têm nessas empresas também:
SANS
http://www.sans.org/security-training/courses.php
Immunity
http://www.immunitysec.com/education-overview.shtml
O Luiz Vieira que deixou um comentário acima é instrutor de cursos de segurança na 4Linux, fiz o curso de forense lá com ele, ele falou que está criando um curso de desenvolvimento de exploits, inclusive vamos criar um lista sobre o assunto, aí eu te adiciono ok? O blog dele é esse: http://hackproofing.blogspot.com
Abraço!
Ok!! Quando começar este curso Ronaldo você me avisa!
ResponderExcluirFico feliz de saber que no brasil tem grandes profissionais como vc e o Luiz Vieira.
Vc é uma grande influência nos meus estudos...
Vlw Ronaldo!
Abraçs
muito bacana..que pena q não é muito divulgado..
ResponderExcluirmacedo$ gcc overflow.c -o overflow
macedo:Desktop macedo$ ./overflow 12345678
[ANTES] Buffer2 contem: BUFFER2
[ANTES] Buffer1 contem: BUFFER1
[DEPOIS] Buffer2 contem: 12345678
[DEPOIS] Buffer1 contem: BUFFER1
macedo:Desktop macedo$
macedo$ ./overflow 1234567890
[ANTES] Buffer2 contem: BUFFER2
[ANTES] Buffer1 contem: BUFFER1
Abort trap
macedo:Desktop macedo$
Como vc tinha falado, provavelmente este erro deve ser pela versão que estou utilizando, caso nao seja...se puder esclarecer obrigado.
utilizo: Darwin Kernel Version 10.6.0 e gcc version 4.2.1
obrigado....
Olá Fernandes, a gente fez o curso de forense juntos né?
ResponderExcluirEntão, é por causa das versões sim, foram criadas várias proteções tanto no gcc quanto no sistema operacional. Aliás esse kernel que vc está utilizando eu não conheço, é Mac?
Tente isso para tirar a proteção ASLR:
echo 0 > /proc/sys/kernel/randomize_va_space
E compile novamente o programa adicionando esse parâmetro do gcc: -fno-stack-protector
Talvez isso funcione, mas têm algumas proteções que não me recordo, em breve vou fazer um post novo sobre as proteções e como desativá-las nos sistemas atuais.
Abraço!
Não tenho certeza...vc era aquele cara q tinha cabelo grande?...se for fizemos em dezembro 2010...
ResponderExcluirDe qualquer forma vou dar uma olhada...
to estudando assembly novamente..o da faculdade nao da pra aprender nada...vc recomenda algum bom livro na area?? to terminado este..
http://www.submarino.com.br/produto/1/253985/fundamentos+em+programacao+assembly+para+computadores+ibm-pc...
Fernandes,
ResponderExcluirSou eu mesmo. Esse livro que vc está lendo parece ser bom. Sugiro que vc estude o assembly gerado pelos compiladores, ou seja, o disassembly.
Escrever um software em assembly é diferente do assembly que os compiladores geram, existem muitas otimizações de código, os livros de engenharia reversa tratam disso, eu tenho o Reversing Secrets of Reversing Engineering e acho muito bom. E para consulta eu uso o Art Of Assembly.
http://www.crimesciberneticos.com/p/bibliografia.html
Abraço!
Pessoal,
ResponderExcluirParabéns a todos. Programo pouco em VB e estou estudando C e assembler (para microcontroladores). Poxa entendi legal tudo aqui postado. Pena que não domino Linux. Esse curso que vcs fizeram foi em São Paulo ?? Se puderem me dar a referência agradeço.
Ulisses Fontoura.
Olá Ulisses, tudo bem?
ResponderExcluirAgradeço os comentários, legal que tenha entendido o post.
Na verdade não fizemos esse curso, estávamos comentando que no Brasil quase não tem curso desse tipo. Você conhece a lista de discussão Exploits-Brasil?
http://www.crimesciberneticos.com/2011/03/grupo-sobre-exploits-e-vulnerabilidades.html
O Luiz, que é um dos idealizadores da lista está montando alguns cursos EAD sobre esses temas, talvez possa se interessar. Você pode entrar na lista e ver os tópicos antigos ou se quiser falar com ele diretamente o email é: luizwt gmail com.
Abraços!
A poucos minutos o meu anti vírus (Comodo) deu esse alerta quando acionei o Firefox, não permitindo a abertura do programa. Como isso pode ocorrer? Troiano?
ResponderExcluirAbs
Olá Roberto,
ResponderExcluirMensagem de "Buffer Overflow"? Pode ser muitas coisas, não dá pra saber só assim, tem que ser feita uma varredura completa na máquina. Pode tentar a reinstalação do Firefox também.
Abraços.
Este comentário foi removido pelo autor.
ResponderExcluirParabéns pelos excelentes artigos !!!
ExcluirUm grande abraço.
Olá Roberto Lima !!!
ResponderExcluirParabéns pelos seus artigos !!! Explicações claras, concretas e objetivas.
Gerson Raymond
www.backtrackbrasil.com.br