ClubEnsayos.com - Ensayos de Calidad, Tareas y Monografias
Buscar

ASM Y Buffer Overflows


Enviado por   •  11 de Febrero de 2014  •  5.866 Palabras (24 Páginas)  •  200 Visitas

Página 1 de 24

-[ 0x08 ]--------------------------------------------------------------------

-[ ASM y Buffer Overflows ]--------------------------------------------------

-[ by Doing ]---------------------------------------------------------SET-21-

Asm y buffer overflows

------------------------

By Doing

------------------------

<jdoing@hotmail.com>

Bueno, por fin me he decidido a escribir un articulo para SET, espero que

lo encontreis interesante. Seguro que muchos de los hackers newbies que

ahora estan descubriendo el mundo del hacking habran oido hablar de los

tan famosos exploits, pero todavia no saben que hacen, ni como funcionan;

pues para eso escribo este co~azo.

Para entender esto te ayudara saber algo de C o ensamblador pero no es

indispensable. Voy a empezar explicando que #"@% es eso del stack.

==> El stack (o pila) <==

El stack es una region de memoria que las funciones usan para guardar sus

variables locales y para guadar temporalmente el contenido de los registros

del procesador (por ejemplo, cuando se llama a una funcion, los parametros

se pasan por el stack). El segmento de stack se guarda en un registro del

procesador, el SS. Tambien existe un registro que apunta al lugar en donde

se encuentra la "pila". La pila se usa para guardar temporalmente el

contenido de los registros (eso ya lo he dicho antes). Para guardar el

contenido de un registro en la pila se usa la instruccion push, y para

recuperar el ultimo dato almacenado en la pila su usa la instruccion pop.

Vamos a poner un ejemplo:

Esto es un segmento de stack:

0x00 0xFFFFFFFF

SS ==> [0000000000000000000000000[VAR1][VAR2][SBP][RET][ARGV1][ARGV2]...]

^

STACK POINTER

Como veis, nada mas llamar a una funcion, el ESP se encuentra justo detras

de la ultima variable declarada. Cuando usamos push, guardamos el dato desde

la posicion del ESP hacia ATRAS, y el ESP de decrementa en tantos bytes como

tenga nuestro dato.

Vamos a suponer que guardamos en la pila el reg EAX (4 BYTES)

pushl %eax (La "l" despues de push quiere decir que el operando ocupa 32 bits)

El segmento de antes quedaria asi:

0x00 0xFFFFFFFF

SS ==> [000000000000000000000[EAX][VAR2][VAR1][SBP][RET][ARGV1][ARGV2]...]

^

STACK POINTER

Ahora vamos a recuperarlo en otro registro:

popl %ebx

En este momento el ESP se incrementa en tantos bytes como tenga nuestro dato,

asi que se queda como al principio, usease, como antes de hacer el ultimo

push. Con esto se puede deducir una cosa: los datos que vas sacando de la

pila salen en orden inverso al que fueron introducidos. En jerga "tesnica"

se dice que la pila es una estructura LIFO (Last In, First Out).

Acabais de ver como el procesador accede a la pila, creo haber dicho que el

stack tambien se usa para acceder a las variables locales, pero, comorr?.

Para acceder a memoria necesitamos dos cosas: segmento y despazamiento. Bien,

el segmento ya lo tenemos, el SS, y el offset (NOTA: offset = desplazamiento)

se guarda (seguro que ya lo habeis adivinado ;) en otro registro, el EBP.

El EBP apunta al comienzo de la primera variable declarada.

Volvamos otra vez al segmento de antes:

0x00 0xFFFFFFFF

SS ==> [0000000000000000000000000[VAR2][VAR1][SBP][RET][ARGV1][ARGV2]...]

^ ^

ESP EBP

Vamos a poner otro ejemplo:

void ejemplo(char *argumento){

char buff[4];

}

void main()

{

char *VAR_MAIN;

ejemplo(VAR_MAIN);

}

Compilemos el codigo:

$ gcc ejem.c -o ejem

Ahora vamos a desensamblarlo para entender como llama a la funcion ejemplo y

que hace con los registros:

$ gdb ejem

(gdb) disassemble main

Dump of assembler code for function main:

0x8048458 <main>: pushl %ebp

0x8048459 <main+1>: movl %esp,%ebp

0x804845b <main+3>: subl $0x4,%esp

0x804845e <main+6>: movl 0xfffffffc(%ebp),%eax

0x8048461 <main+9>: pushl %eax

0x8048462 <main+10>: call 0x8048440 <ejemplo>

0x8048467 <main+15>: addl $0x4,%esp

0x804846a <main+18>: leave

0x804846b <main+19>: ret

End of assembler dump.

OK. En <main> guardamos el registro ebp en la pila, esto lo hacen todas las

funciones cuando son llamadas. Hemos dicho que ebp apunta a al comienzo de

las variables locales de una funcion, pero cuando se llama a otra funcion,

esta tambien tiene que almacenar en ebp la direccion de sus variables, asi

que se guarda en la pila para luego restaurarlo. En nuestro segmento esta

en [SBP].

En <main+1> copiamos en ebp el contenido de esp. Asi que tenemos que ebp

y esp apuntan justo detras de [SBP]. Otro dibujito:

0x00 0xFFFFFFFF

SS ==> [0000000000000000000000000000000000000[SBP][RET][ARGV1][ARGV2]...]

^

EBP

ESP

Si ahora hicieramos un push de lo que sea, en este momento escribiriamos

en la seccion de memoria donde queremos guardar VAR_MAIN, asi que en

<main+3> restamos el tama~o de VAR_MAIN a esp, quedando el famosisimo

segmento asi:

0x00

...

Descargar como (para miembros actualizados) txt (21 Kb)
Leer 23 páginas más »
Disponible sólo en Clubensayos.com