sexta-feira, 21 de novembro de 2008

Buffer Overflow Attacks: Detect, Exploit, Prevent

Primeiro eu gostaria de dizer que eu acho que quase demorei mais tempo para escrever esse resumo/resenha do que para ler o bendito livro (tirando que tenho ele a muito tempo e somente comecei ler ele sério mesmo a pouco tempo atrás).





Bem o livro "Buffer Overflow Attacks: Detect, Exploit, Prevent", começa com uma ótima pergunta:
"Will the code you write today headline tomorrow's BugTraq mail list?"

E temos que concordar, não é uma situação muito agradável saber que seu software/sistema contem um bug que pode permitir que um atacante veja dados confidenciais, obtenha acesso de maneira indevida ou mesmo faça a aplicação toda travar. Ainda mais se for algum software que o programador gostou de trabalhar... programadores tem ciúmes de seus códigos ;)

Antes de iniciar o resumo, devo citar que o livro foi escrito por James C. Foster e contou com a ajuda de Vitaly Osipov, Nish Bhalla e Niels Heinen. Foi publicado pela Syngress e a única edição deste livro foi publicada em Fevereiro de 2005, digo isto pois todo o material de exemplo incluso é de até 2004 (e sabemos que a SI é um campo em constante evolução).

O livro contem aproximadamente 500 páginas e foi utilizado um papel, emho, de baixa qualidade.


O próprio autor divide o livre em 3 partes:
1 - Expanding on Buffer Overflows
2 - Exploiting Buffer Overflows
3 - Finding Buffer Overflows

Após cada parte há uma série de casos de estudos, que também irei comentar.



Parte 1 - Expanding on Buffer Overflows
Esta parte contem 4 capítulos com um total de 130 páginas aproximadamente, vamos ver um pouco sobre cada capítulo.


Capítulo 1: Buffer Overflows: The Essentials
Como esperado, é o capítulo de introdução, onde o autor define o que são Buffer Overflows, da algumas estatísticas baseada no número e tipo de falhas encontradas de 2001 a 2004, da um exemplo do site da Madonna hackeado e depois define uma penca de termos relacionados a Hardware, Software e Segurança.


Capítulo 2: Understanding Shellcde
Aqui ele começa introduzindo o que é um Shellcode, ferramentas úteis (NASM, GDB, ObjDumper, Ktrace (BSD), Strace (Linux) e Readelf) e faz uma introdução a assembly (mas espera que o leitor tenha conhecimento prévio) e por fim cita que o código assembly para Windows e Unix são diferentes.

Então ele começa a trabalhar nos detakges ao se escrever um Shellcode: o problema do endereçamento; o problema do byte nulo (NULL Byte, 0x00), como fazer Syscalls e mostra a diferença entre a passagem de argumentos em BSDs e Linux. E por fim da exemplos de Shellcodes para ataques remotos (port-binding) e ataques locais (execve, setuid e chroot), todos acompanhados de seus códigos em C e assembly.


Capítulo 3: Writing Shellcode
Nas 40 primeiras páginas deste capítulo ele pega alguns shellcodes do capítulo anterior (execve, port-binding) e alguns novos (reverse connection, reutilização de socket, reutilização de descritores de arquivos) e mostra a idéia, o que se quer fazer, apresenta um código em C, depois o código em assembly e explica como cada coisa funciona (comenta o código asm todo). Fala sobre codificação do shellcode, para - tentar - evitar a detecção por IDSs

Em seguida aborda como utilizar áreas de memória do próprio programa alvo para guardar dados, quando a área de payload para o shellcode é pequena e depois sobre shellcodes que podem ser utilizados em mais de um SO.

Por último faz uma engenharia reversa em um shellcode, para "descobrir" o que ele faz.


Capítulo 4: Win32 Assembly
Enquanto até agora, o foco foi em sistemas BSDs e Linux, neste capítulo passa a ser exclusivamente sobre Windows.

Ele começa mostrando como funciona o gerenciamento de memória e a Stack e a Heap.

Então ele começa (de novo) a uma introdução em assembly... registradores de índice, de stack, e outros gerais... EAX, EBX, ECX...AX, BX, CX... AL...AH...

Mostra algumas operações básicas em ams (CALL, MOV, INC, DEC, ADD, SUB, etc...) e faz um Hello World.

E foi isso o capítulo. Se isso não estivesse aqui, não faria diferença nenhuma, emho. Me pareceu mais algo que caiu de para-quedas por que a editora disse "Ei cara! Tem que colocar coisa de Windows ai!!!".


De qualquer forma, a parte 1 termina com 4 casos de estudo:

Caso 1.1 - FreeBSD NN Exploit Code
3 página de um código em Perl c/ assembly, ou seja o código do exploit.
Uma análise meia página sobre meia dúzia de linhas.
Realmente, não me acrescentou em nada... pois eu pulei.


Caso 1.2 - xlockmore User Supplied Format String Vulnerability
Começa melhor, pois mostra o trecho do código (em C) da aplicação que contem a vulnerabilidade. Mostra qual o problema. Porém, logo em seguida temos 2 paginas do dump do código do exploit (dessa vez em C + asm) e uma análise de 1/3 de página...
Muito fraco ainda, emho.


Caso 1.3 - Frontpage DoS Utilizing WinSock
Um "overview" de 1/3 de página... depois dump do código do exploit (em C + asm) de 1 página e uma análise de 1/3 de página novamente.
Depois vem um dump do "Hack.h", ocupando 6 páginas + 1 página de comentários, que são as funções de ajuda utilizadas no exploit do Frontpage.


Caso 1.4 - cURL buffer overflow on FreeBSD
Segue o mesmo do resto...2 paginas de dump do código do exploit e uma página de análise.


Eu particularmente, não gostei desses "Casos de estudo".
Primeiro porque *como* buffer overflows e ataques por strings de formatação são apenas explicados na segunda parte do livro.

Segundo por que, eu esperava de "Casos de estudo", estudar o buffer overflow e não o maldito exploit que alguem fez.... algo como desde a analise de um problema (SegFault) até achar onde se encontrava o bug e como fazer para explora-lo.


Depois de ficar um pouco desanimado com estes casos de estudo, vamos a segunda parte...




Parte 2: Exploiting Buffer Overflows
Esta é a parte principal do livro, com aproximadamente 200 páginas e demostra o funcionamento dos Buffer Overflows na stack e na heap e dos ataques via strings de formatação


Capítulo 5: Stack Overflows
Como esperado, começa iniciando com uma explicação de funcionamento da stack, volta a falar um pouco sobre asm básico e fala sobre o que fica na stack: variáveis locais, parâmetros em chamadas de funções, o EBP e o EIP salvos, etc... ou seja, mostra o que é um Stack Frame.
Em seguida vai demostrando alguns overflows na stack e suas consequências, depois passa para métodos para conseguir executar o payload (o shellcode que você colocou na memória) e depois como criar um payload adequado.

Comenta sobre os overflows "off-by-one", onde somente 1 byte a mais (devido a um erro de conta do programador) é sobre-escrito e que mesmo sendo somente 1 byte, pode trazer problemas.
Depois fala sobre as funções da biblioteca padrão do C que não são seguras como gets(), strcpy(), strcat(), sprintf(), etc... e suas versões seguras (que implicam que o programador defina um número máximo do tamanho do buffer... mas que ainda podem ser usadas erradas e causar "off-by-one" quando a conta é feita errada) como fgets(), strncpy(), strncat(), snprintf(), etc...

No final fala da dificuldade em se achar erros desse tipo na análise do código...cita analisadores léxicos (grep-like), semânticos (que funcionam como compiladores), tracers, fuzzers, etc...


Capítulo 6: Heap Corruption
Este capítulo começa com uma pequena descrição da heap e das funções em C para alocação de memória (malloc/calloc/realloc) em seguida um exemplo de Buffer Overflow em uma área alocada na heap.

Em seguida trata sobre como sobre-escrever ponteiros para funções em C++ (pois os ponteiros para as funções de uma classe ficam na heap).

E por fim, uma parte que eu gostei bastante, uma discussão sobre 2 algoritmos de gerenciamento da heap e quais as falhas que estes modelos proporcionam. Esta parte foi muito boa mesmo, tanto pela discussão do algoritmo, quanto das falhas. Os algoritmos discutidos foram o Doug Lea Malloc, que é a base do que o Linux usa hoje e o System V Malloc, utilizado no Solaris e no IRIX.


Capítulo 7: Format String Attacks
Começa com uma descrição do que são Format String, como é feita uma função em C que aceita argumentos variáveis e como utiliza-los através do va_args e mostra como tudo fica na stack e o funcionamento da função printf(), como exemplo.

Em seguida, vem a parte de como explorar strings de formatação, quando estas podem ser definidas pelo usuário e não são tratadas adequadamente pelo programa (assim como todos os problema de Buffer Overflow, que é a falta no tratamento dos dados enviados pelo usuário).

Começa demonstrando a forma mais fácil de explorar esse tipo de ataque que é causando um DoS (em contexto local... BSOD ou Kernel Panic), em seguida como ler e escrever na memória através de strings de formatação maliciosas.

E no final são discutidos os desafios ao tentar se explorar esse tipo de falha.


Capítulo 8: Windows Buffer Overflows
Preciso comentar que quando comecei este capítulo, pensei logo "Ixi... a mesma coisa que o Cap 4, caiu de para-quedas...".

Talvez depois de ler ele todo eu tenha entendido o propósito dele. Enquanto os capítulos 5 e 6, tratavam da teoria dos ataques (porem demonstrando os conceitos, só que em ambiente linux), este capitulo visa juntar toda a teoria que foi aprendida e realmente consturir um exploit para ambiente Windows.

Como eu disse, ele trata mais da construção, ou seja desde a exploração incial até a criação de um shellcode.

Uma coisa nova que ele trata é como usar e exploitar o "Structured Exception Handler" do Windows.



E aqui terminamos a Parte 2, e temos mais 5 casos de estudo:

Caso 2.1 - cURL Buffer Overflow on Linux
Uma falha de 2002, contem uma introdução pequena, 2 paginas com o código em Perl do exploit. Em seguida uma análise com o disassemble do shellcode e mais meia duzia de comentários sobre o código.


Caso 2.2 - SSLv2 Malformed Client Key Remote Buffer Overflow Vulnerability
Esse veio mais completo, contem uma introdução, seguido de detalhes da falha em si, comentários na estrutura de dados que permite a exploração e qual era o erro no código que permitia isto. Em seguida demonstra os problemas ao se tentar explorar esta falha... então a é feito um refinamento sobre a idéia do exploit e no final o código completo do exploit em C com quase 7 páginas ;)

Apesar de muito código, achei bem interessante toda a discussão feita em cima deste caso de uso.


Caso 2.3 - X11 R6 4.2 XLOCALEDIR Overflow
Uma introdução de 1/4 de página e seguido de uma analise bem legal de umas 3 paginas da vulnerabilidade. E por final o código do exploit em C, com 2 páginas aproximadamente.


Caso 2.4 - Microsoft MDAC Denial of Service
Uma introdução de meia página, seguido do código do exploit em C com 3 paginas, onde 80% é um shellcode do codigo de exploração... o que ele faz, só deus sabe. Em seguida mais 7 paginas com o arquivo hack.h de "funções úteis" para criação de exploits em C -_-'

Em seguida uma analise de 2 paginas desse codigo todo...


Caso 2.5 - Local UUX Buffer Overflow on HPUX
A coisa ficou underground agora. Mas continua no mesmo estilo... uma introdução pequena, codigo do exploit em Perl com 2 paginas e comentários sobre o código.


Os casos 2.2 e 2.3 são os que se salvam emho... anyway, continuando para a parte final do livro...



Parte 3: Finding Buffer Overflows
Esta parte contém um único capítulo e alguns casos de estudo.

E quando cheguei nela, achei que ela prometia, e muito!


Capítulo 9: Finding Buffer Overflows in Source
Este séria um dos melhores capítulos deste livro se... ele não falasse apenas de ferramentas. Ferramentas pagas, ferramentas comerciais, ferramentas opensource... cada uma analisando o código do seu jeito, etc...

Mostra como algumas funcionam, o tipo de output gerado, etc...

E é isso... e algumas das ferramentas inclusive ou não existem mais hoje...

Infelizmente, foi uma grande decepção... não que o material seja ruim, mas era melhor chamar o capítulo de "Using X, Y and Z softwares to help you in search for buffer overflows in your code" ou algo do tipo...

Acho que essa foi a parte mais patrocinada do livro :P


Em seguida temos 4 casos de estudo (que não tem nada a ver com esta parte 3...):

Caso 3.1 - InlineEgg I
Tem 2 páginas... uma introdução, o código do exploit e comentários sobre o que o exploit faz.

Alguem aqui viu algo relacionado a "como achar buffer overflows"?


Caso 3.2 - InlineEgg II
Acho que eles estavam ficando sem criatividade para escolher programas...

Uma introdução de 3 linhas (sério) seguido de uma pagina com código em exploit em Python e outra comentado o exploit.


Caso 3.3 - Seti@Home Exploit Code
Mais 4 linhas de introdução, 5 páginas com código do exploit e uma página... comentando o código do exploit.


Caso 3.4 - Microsoft CodeBlue Exploit Code
10 linhas de introdução, 4 paginas com código do exploit e uma página... de novo... comentando o código do exploit.


Apendice A: Tabela de conversão de caracteres para decimal, octal, binário, hexadecimal, etc...
Apendice B: Uma dúzia de syscalls disponíveis em sistemas Linux/BSD.


E pronto, o livro acabou.


Como provavelmente puderam perceber, eu *realmente* não gostei dos casos de estudo. Talvez eu tenha uma visão errada do que eles deveriam ser, mas pegar 10 exploits aleatórios no milw0rm e dizer que são casos de estudo, não me agrada muito.

Uma coisa legal, que esqueci de citar é que no final de cada capítulo há um resumo sobre os pontos vistos, links para sites relacionados aos assuntos abordados ou que foram comentados durante o capítulo e no final um FAQ (com umas perguntas bem aleatórias as vezes...).


Não posso dizer que seja um espetáculo de livro... mas também não é ruim.

Foi bom para revisar todos os conceitos... e sempre acaba-se aprendendo algo novo.

Ficou sendo apenas um livro... "normal".

Nenhum comentário: