[0x16] Explorar Buffer Overflow em uma aplicação vulnerável

9 months ago 49

Este tutorial faz parte do GUIA COMPLETO do professional em Segurança Ofensiva de Software, saiba mais. Aula 22: Como construir um buffer overflow exploit Na aula anterior foi exposto uma introdução teórica sobre a vulnerabilidade de Buffer Overflow. Abaixo será explorado na prática essa vulnerabilidade em uma aplicação. Figura 1: Desabilitar DEP para aplicação vulnerável Será desenvolvido um exploit para explorar a vulnerabilidade de estouro de buffer na pilha existente na aplicação Free MP3 CD Ripper em sua versão 1.0 . Para correto funcionamento do exploit desenvolvido é necessário desabilitar o funcionamento da Prevenção de Execução de Dados no sistema em "Meu Computador" > "Propriedades do sistema" > "Avançado" > "Opções de Desempenho" (Figura 1). Figura 2: Código para gerar arquivo malformatado Foi escrito em Python um código simples, no qual a variável "junk" (lixo) recebe 5 mil caracteres "A" e é gravado no arquivo "overflow.wav" para demonstrar que ocorre um crash na aplicação ao receber um arquivo ".wav" como entrada mal formatada (Figura 2). Para analisar o comportamento da aplicação vulnerável vamos utilizar o software Immunity Debugger. Figura 3: Immunity Debugger attach Para analisar o crash, é necessário adicionar a aplicação vulnerável ao software Immunity Debugger (Figura 3). Para isso basta executar a aplicação e em seguida no Immunity utilizar a opção "Attach" em "File". Figura 4: Inserindo arquivo Após anexar a aplicação aperte o botão "play" para remover a aplicação do estado pausado. Então abra o arquivo criado para analisar o crash (Figura 4). Provavelmente a aplicação irá terminar inesperadamente assim que você carregar o arquivo do exploit. Para ilustrar as diferenças de crash que podem ocorrer dependendo da quantidade de lixo que você está utilizando, suponha que no código do exploit, figura 1, tivéssemos carregado 3000 "A" em vez de 5000 como lixo. Figura 5: Crash com 3000 A Com 3000 o Immunity pausa a aplicação ao identificar um erro de divisão de inteiro por zero (Figura 5). Mas o que acontece quando carregamos o exploit com um pouco mais, no caso 5000 ? Figura 6: Sobrescrita de registradores O Immunity retornou a seguinte mensagem de erro após carregar o exploit: "Don't know how to continue because memory at address 41414141 is not readable. Try to change EIP or pass exception to program."  Note que o registrador EIP foi sobrescrito com um endereço de memória não legível, no caso o registrador foi sobrescrito com o valor "AAAA" (Figura 6). Agora que sabemos que é possível sobrescrever o registrador EIP, vamos utilizar o plugin Mona juntamente com o Immunity. Mona é um script python que pode ser usado para automatizar e acelerar pesquisas específicas enquanto desenvolve exploits. No Github da ferramenta você encontra tutorial de instalação https://github.com/corelan/mona . Figura 7: Mudar diretório de trabalho do Mona Para utilizar o Mona juntamente ao Immunity, primeiramente altere o diretório de trabalho para um local de fácil acesso (Figura 7). Figura 8: Criando pattern com Mona Agora precisamos calcular a quantidade de lixo necessário entre o início do buffer e o endereço de retorno, utilizando o Mona foi gerado 5000 pattern (Figura 8). Patterns são caracteres que possuem um determinado padrão específico para ajudar em determinados cálculos de tamanho da entrada. Figura 9: Código overflow_pattern Adicione os patterns à variável "junk", compile o código e juntamente ao Immunity execute a aplicação e carregue o exploit. Figura 10: Error endereço ilegível Após carregar o exploit, o Immunity nos forneceu o endereço ilegível que foi sobrescrito o EIP 31684630 (Figura 10). Figura 11: Localizando EIP Utilizando o Mona para calcular o offset: a distância do início do buffer até o registrador EIP. Para isso basta utilizar o argumento pattern_offset para usar os patterns que você gerou anteriormente pesquisando pelo endereço ilegível sobrescrito no EIP. Assim foi possível descobrir que o EIP está a 4112 bytes do início do buffer (Figura 11). Figura 12: Testando sobrescrita do EIP e ESP Teste se você consegue sobrescrever os registradores EIP e ESP a partir da informação descoberta. No caso o registrador EIP foi sobrescrito com "BBBB" e o registrador ESP com "CCCC..." (Figura 12). Agora podemos começar a desenvolver finalmente o exploit que explore a vulnerabilidade constatada adicionando um shellcode (um pedaço de código utilizado como payload, conjunto de dados com propósito de serem executados pela aplicação vulnerável).  Mas antes devemos nos atentar ao fato de que bad chars (caracteres ruins) podem existir. Estes caracteres removem ou substituem caracteres funcionais por outros valores tornando nosso shellcode inútil. Então primeiramente devemos descobrir quais badchars nossa aplicação vulnerável possui. Figura 13: Gerando bytearray com Mona Para encontrar badchars com o Mona, primeiramente gera um bytearray. Como exemplo de gerar bytearray sem determinado caractere foi removido de início o caractere de terminador de string "00" (Figura 13). Figura 14: Código para identificar badchars Adapte o código do seu exploit para adicionar o bytearray afim de identificar badchars (Figura 14). Figura 16: Encontrando badchars No Immunity, execute a aplicação e carregue o exploit. Após crashar use o código para identificar os badchar: !mona compare -f bytearray.bin -a ENDEREÇO Substitua ENDEREÇO pelo endereço presente no registrador ESP, lembre da Figura 12. No nosso caso não foi encontrado nenhum badchar. Caso apareça algum badchar, gere um novo bytearray removendo o badchar identificado (igual o exemplo removendo o terminador de string) e adicione ao seu código e faça o procedimento de identificação novamente. Faça isso até não ter mais badchars! Figura 17: Bug com python3 gerou vários badchars Caso esteja usando python3, pode ser que apareça um monte de badchars (Figura 17) caso esteja carregando os valores do bytearray na variável como nosso código de exemplo. Isso é problema de sintaxe, portanto compile com python2 ou altere o código para ficar compatível com python3. Agora precisamos encontrar ponteiros, uma instrução do tipo jump em um módulo como uma DLL por exemplo que não possua proteções de memória. Esse ponteiro será utilizado para posteriormente chamar nosso código malicioso. Figura 18: Encontrar instrução jump No Immunity, execute a aplicação vulnerável dando play sem carregar qualquer arquivo .wav . Depois pesquise utilizando o Mona por uma instrução "jmp esp" evitando módulos protegidos (Figura 18). Comando: !mona find -type instr -cm aslr=false,nx=false,rebase=false,safeseh=false,os=false -s "jmp esp" É possível evitar módulos com badchars adicionando: -cp alphanum No exemplo, vamos utilizar a instrução presente no endereço 0x00419ab5 referente a fcrip.exe , mas poderia ser um arquivo DLL . Figura 19: Add endereço instrução jump Adicione o endereço da instrução de retorno na variável que sobrescreverá o registrador EIP, como os endereços na arquitetura x86 são armazenados no formato little-endian, então devemos escrever o endereço ao contrário: b59a4100 (Figura 19). Figura 20: EIP igual ao endereço breakpoint Para checar que o registrador EIP foi sobrescrito com o endereço de jump adicionado ao código, configurou-se um breakpoint exatamente no endereço referente a instrução "jmp esp".  Para adicionar um breakpoint, primeiramente pesquise pelo endereço ao clicar no primeiro ícone preto (Go to address Disassembler) após o botão de play para a direita, digite o endereço do breakpoint no caso 00419ab5 e em seguida apertar F2 para adicionar o breakpoint.  Agora ao executar a aplicação vulnerável e carregar o exploit, espera-se que o programa será pausado no endereço do breakpoint. Assim que pausar, confira o endereço presente no registrador EIP. Se for igual ao endereço adicionado ao código (o mesmo do breakpoint), significa que conseguimos controlar o jump do programa (Figura 20)! Caso o endereço seja diferente, teste com o endereço de outro módulo até encontrar algum que funcione. Nosso registrador EIP foi sobrescrito corretamente com o valor 00419ab5, agora podemos gerar nosso código malicioso! Figura 21: msfconsole Inicialize o Metasploit (Figura 21). Figura 22: Gerando payload com Metasploit Utilizando o Metasploit configure um payload, como exemplo vamos utilizar o payload do tipo messagebox para Windows, assim quando carregar o arquivo na aplicação vulnerável será exibida uma mensagem "maliciosa". Claro que você pode utilizar outros payload mais interessantes como por exemplo para obter uma shell da máquina alvo.  Quando você adapta um exploit de uma prova de conceito, pode ser necessário limitar o tamanho do payload pois um byte a mais ou a menos pode interferir na forma que é copiado os bytes para a memória deixando de funcionar seu código malicioso.  Neste exemplo que estamos fazendo, sabemos que uma prova de conceito necessitou de 4358 bytes. Se temos 4112bytes de lixo então devemos limitar o tamanho do payload em 246 bytes para garantir o funcionamento. Mesmo assim o Metasploit gerou um payload com 258bytes que ainda assim nos atende. Figura 23: Add payload malicioso ao código Utilizando o payload gerado anteriormente, preencheu a variável shellcode e somou-se alguns NOPS (instruções que não faz operações). Neste exemplo não precisaria dos NOPS mas em alguns caso para garantir que nosso shellcode seja alcançado após o jump você pode precisar adicionar alguns NOPS (Figura 23). Figura 24: Buffer Overflow Compile o código (Figura 23) e gere o arquivo, depois carregue o arquivo "overflow.wav" na aplicação vulnerável e veja a mágica acontecer! Nosso arquivo malicioso executou (Figura 24).  O processo de desenvolvimento de um exploit mais completo pode ser um pouco complexo com apenas este tutorial básico, portanto é recomendo a leitura: Mona manuais: https://www.corelan.be/index.php/2011/07/14/mona-py-the-manual/ https://x3tb3t.github.io/2018/03/29/mona/ Escrever Buffer Overflow exploits: https://www.corelan.be/index.php/2009/07/19/exploit-writing-tutorial-part-1-stack-based-overflows/ https://www.corelan.be/index.php/2009/07/23/writing-buffer-overflow-exploits-a-quick-and-basic-tutorial-part-2/ https://vulp3cula.gitbook.io/hackers-grimoire/exploitation/buffer-overflow https://www.youtube.com/watch?v=3x2KT4cRP9o&list=PLLKT__MCUeix3O0DPbmuaRuR_4Hxo4m3G&index=2 https://ksdpmx.bitbucket.io/2020/04/08/Free-MP3-CD-Ripper-1-1-Local-Buffer-Overflow/ Próxima aula, clique aqui.


View Entire Post

Read Entire Article