elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.
 
Inicio Ayuda Buscar Ingresar Registrarse
25 Mayo 2012, 14:53  


Tema destacado: Entra al canal IRC oficial de #elhacker.net

+  Foro de elhacker.net
|-+  Seguridad Informática
| |-+  Bugs y Exploits (Moderador: berz3k)
| | |-+  Preguntas sobre Buffer overflows
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Preguntas sobre Buffer overflows  (Leído 2,307 veces)
y0mism0

Desconectado Desconectado

Mensajes: 238


Ver Perfil
Preguntas sobre Buffer overflows
« en: 28 Agosto 2006, 21:46 »

Estuve leyendo el manual k pusieron por ai arriba sobre buffers overflows, y tengo algunas dudas k no entendi bien:


Citar
Bien, cuando el programa o el SO piden "espacio" para alojar una/s variable/s,
un dato, un nombre o lo que sea, dicho nombre normalmente se guarda en la pila
(no entraremos en temas de heap).

Básicamente, lo que se hace es crear un "espacio" entre un nuevo ESP y EBP (cima
y base de la pila) para alojar las variables. Son "nuevos" para no sobrescribir
los variables y valores que ya haya en la pila, de otras funciones o programas.

Posteriormente, se introduce el EBP antiguo en la pila (se pushea), para saber
DONDE estaba la anterior base de la pila, la pila del proceso principal. Esto
también es importante, es el EBP salvado del proceso anterior. Cuando la función
suma acabe, EBP tomara el valor del EBP salvado, y estaremos otra vez en el
"trozo" de pila del proceso principal.

Ahora mismo, la pila esta así:

ESP             | EBP anterior salvado |       EBP - 4
ESP +4bytes     | RET ADDRESS          |       <---- El EBP actual apunta aquí
ESP +8bytes     | argumento 1 de suma  |       EBP +4
ESP +12bytes    | argumento 2 de suma  |       EBP + 8

Tras esto, se "sustrae", se "resta" a ESP tantos bytes como necesitemos de
espacio para nuestra variable. Al sustraerle bytes, la diferencia entre ESP y
EBP son esos bytes, donde irán nuestros datos (nombre, datos, lo que sea). Por
ejemplo, si nuestra variable "nombre", necesita 12 bytes (siempre se hace con
múltiplos de 4, por temas de alineamiento en la pila), pues se le sustrae a ESP
12 bytes:

ESP            | basura, aun no hay nada inicializado| EBP -16 
ESP +4         | basura                              | EBP -12   
ESP +8         | basura                              | EBP -8
ESP +12        | EBP anterior salvado                | EBP -4
ESP +16        | RET ADDRESS                         | EBP (el EBP no cambia)
ESP +20        | argumento 1 de suma                 | EBP +4
ESP +24        | argumento 2 de suma                 | EBP +8               

Como se ve, hay 4+4+4 bytes de basura (basura quiere decir que son datos que
había antes ahí, de anteriores usos de la pila, pero que no nos sirven) para
nuestro nombre o lo que sea, de 12 bytes.

Pero, si esos bytes no son suficientes, al introducir nuestro nombre por
ejemplo, si solo tenemos espacio para 12 bytes (12 caracteres), y introducimos
14, los 2 bytes que sobran, sobrescribirán la memoria contigua a la declarada en
la variable, es decir, sobrescribirán el EBP de la anterior función, si metemos
4 lo sobrescribiremos completamente:

Introducimos AAA...A  (16 As) para ver que pasa (esto no se haría con push, que
aumentan ESP, sino con instrucciones MOV)

ESP            | AAAA                                    | EBP -16 
ESP +4         | AAAA                                    | EBP -12   
ESP +8         | AAAA                                    | EBP -8
ESP +12        | (EBP anterior salvado sobrescrito) AAAA | EBP -4
ESP +16        | RET ADDRESS                             | EBP
ESP +20        | argumento 1 de suma                     | EBP +4
ESP +24        | argumento 2 de suma                     | EBP +8

Y si le metemos otras 4 AAAA, sobrescribiremos el ret, que es lo que nos
interesa :)

Lo k no entiendo bien es este eskema en primer lugar :


ESP             | EBP anterior salvado |       EBP - 4
ESP +4bytes     | RET ADDRESS          |       <---- El EBP actual apunta aquí
ESP +8bytes     | argumento 1 de suma  |       EBP +4
ESP +12bytes    | argumento 2 de suma  |       EBP + 8

Este eskema segun entiendo, es el de la funcion suma y se van introduciendo los datos de abajo a arriba. Cuando el eip recoge el ret address dice k retorna sl programa principal. Pero , ese programa principal, esta en otra pila distinta? Eske viendo ese eskema, veo k cada argumento esta dentro de una cima y una base de la pila, como si fueran pilas distintas. y luego dice k vuelve al programa principal, como si fuera un espacio aparte. Y lo k veo en el eskema eske cada argumento esta en un espacio aparte, entre una base y una cima d la pila. k diferencia ai entre el espacio o direcciones de memoria de estos argumentos y el espacio del programa principal? Porke lo trata como si fueran espacios apartados de estos y no como una direccion de memoria mas?¿
Y luego no entiendo la diferencia entre el ebp salvado y entre el ret address, alguien me la puede explicar?¿

y otra pregunta, :


ESP            | basura, aun no hay nada inicializado| EBP -16 
ESP +4         | basura                              | EBP -12   
ESP +8         | basura                              | EBP -8
ESP +12        | EBP anterior salvado                | EBP -4
ESP +16        | RET ADDRESS                         | EBP (el EBP no cambia)
ESP +20        | argumento 1 de suma                 | EBP +4
ESP +24        | argumento 2 de suma                 | EBP +8     

Donde estan los 4 + 4 +4 bytes de basura?¿ no los veo por ninguna parte, nose a k se le resta.

Nose si habreis entendido mis dudas pero lo intente explicar lo mejor k pude...

Saludos.
En línea
sirdarckcat
Troll Buena Onda y
CoAdmin
***
Desconectado Desconectado

Mensajes: 6.947


Lavando Platos


Ver Perfil WWW
Re: Preguntas sobre Buffer overflows
« Respuesta #1 en: 29 Agosto 2006, 19:51 »

pues te veo un poco confundido..

el STACK, es una \"sección\" de la memoria, donde se tiene permiso de lectura y escritura.

en este se guardan valores.. es decir, tu al hacer, por ejemplo \"printf(variable)\"

haces en ASM:

Código:
push EAX (en EAX, esta el offset a la variable, al hacer push, lo guardas en el stack.)
call printf

y call printf seria masomenos:
Código:
PUSH EIP ;posicion actual de memoria
JMP printf ;vamos a printf
MOV EBP,ESP ;movemos el inicio de la pila

ESP apunta al tope de la pila, y EBP a la base.

entonces:

ESP
ESP+4
ESP+8

etc.. solo son las posiciones relativas de la memoria..
si te fijas:

ESP   = EBP -16 
ESP +4=EBP -12
etc..

hasta:
EBP-4 donde se guarda el valor de EBP anterior y EBP donde esta el valor de retorno de la funcion. ** (lo que hicimos en el ejemplo de printf)

entonces, mira:

tenemos EBP y ESP asi (por ej, EBP/ESP nunca vale 50 xD):

ESP=45
EBP=50

despues llamamos a una funcion..

EBP=40
ESP=45

es decir, se va recorriendo la pila.

si tienes algun debugger, podras verlo graficamente. :P

Saludos!!
En línea

y0mism0

Desconectado Desconectado

Mensajes: 238


Ver Perfil
Re: Preguntas sobre Buffer overflows
« Respuesta #2 en: 2 Septiembre 2006, 03:31 »

y k es el ebp anterior? ya se, la anterior base de la pila, pero a kien pertenece, a k funcion, a main?gracias, algo me aclaro, aunke  no entiendo bien el funcionamiento de la pila y eso k lei ya bastante sobre esto pero ai algo k se me escapa (o mucho) ,jejje, entiendo mejor ( o eso creo) el ASM, asi k de momento are unas preguntas sobre esto, k nose si iran en esta sección del foro, pero ya k esta el post abierto lo escribo aki.
PUes eso posteo mis dudas.
Aver, en primer lugar, yo quiero imprimir por pantalla una cadena de caracteres, y utilizando en debug de win hago esto:

Código:
- a100
2C1B:0100 JMP 011D
2C1B:0102 [ENTER]
- E 102 'Hola, como estas.' 0D 0A '$'
- A011D
2C1B:011D MOV DX,0102
2C1B:0120 MOV AH,09
2C1B:0122 INT 21
2C1B:0123 INT 20

Bueno, esto lo entiendo todo, aunke utiliza un cmd "-e" para escribir la cadena en la memoria, aunke luego debugeando veo k lo unico k ace es poner en la memoria estas instrucciones : db 69...

Pero claro, esto solo me vale para ms2, ya k funciona solo para 16 bits, lo guarda en com y nisikiera puedo debujearlo con programas como el ollydbg.

Entonces kise utilizar el tasm, y despues de compilar y linkear, no me imprime la cadena. A veces incluso, nisikiera me compila y me da un error.

POngo el code, o varios, de los k probe y ninguno me fue :
Código:
.model small
.stack
.data
Cadena1 DB 'Hola Mundo.$'
.code

programa:
   mov ax, @data
   mov ds, ax
   mov dx, offset Cadena1
   mov ah, 9
   int 21h
end programa

Este no me imprime la cadena.

Código:
.model small
.stack
.data
.code

programa:
yo: db 68
   mov ah, 09
   mov dx, yo
   int 21
   int 20
end programa

Este me marca este error : **Error** a.asm(9) Operand types do not match (este lo ice yo utilizando la misma tecnica q utilice en debug, se nota xD)

Tambien probe otros k tampoco me fueron. Nose si es del compilador, o eske no pongo bien las intrucciones. POr ej para imprimir una cadena lo k se ace es, acer k ah contenga la funcion 09 y dx la dire de memoria donde empieza la cadena, no es asi? o ai k llamar a alguna funcion printf del SO?


Y otra preg, para k sirve poner "%" delante de los registro, por ej "%eax"?¿
Y otra cosa, porke cuando pongo los registros con la "e" delante me marca error en el compilador?¿

Saludos.:)
« Última modificación: 2 Septiembre 2006, 03:33 por loko_69 » En línea
Ole

Desconectado Desconectado

Mensajes: 130



Ver Perfil
Re: Preguntas sobre Buffer overflows
« Respuesta #3 en: 2 Septiembre 2006, 14:09 »

Empezare respondiendo por abajo xD.

No estoy seguro 100% de esto, pero me da que msdos solo sirve para cuando los micros de intel eran de 16 bits y no de 32, la "e" delante de un registro hace referencia a que te refieres al registro completo. Los registros pueden ser vistos de diferentes maneras.

EAX (Extended AX): |----------------- 32 bits ----------------------|
AX:                                                 |--------16 bits---------|
AH (Ax High):                                   |---8bits---|
AL (Ax Low):                                                   |---8bits---|

Lo mismo pasa con el resto de registros. Pos msdos creo que solo ve hasta AX, por asi decirlo, no sabe que realmente los registros son mas grandes.

Lo de poner '%' es por otro motivo, hay varias formas de escribir codigo ensamblador de x86, una es con "sintaxis intel" que es la que usas tu. Otra sintaxis distinta es la GAS (Gnu ASsembler) que es la que uso yo, ahora posteo algo y en donde hay diferencias, una de ellas es que para nombrar registros hay que ponerles el % delante ya que si no, podria confundirse con etiquetas. Otra caracteristica importante de GAS por ejemplo es que los operandos de las instrucciones son al reves. Donde tu escribes "mov AX, 0x0011" en GAS seria "mov $0x0011, %ax". Otra caracteristica mas es que en los literales, inmediatos y demas hay que poner un "$" delante, sino lo considera una direccion de memoria. Hay algunas diferencias mas pero no voy a seguir, voy a postearte un codigo en GAS para que veas un poco:

                movb    $0x5, %al
                movl    %esi, %ebx
                addl    $0x10, %ebx
                xorl    %ecx, %ecx
                movb    $0x1, %cl
                int     $0x80
                # Abrir la pantalla

                movl    %eax, %ebx
                xorl    %eax, %eax
                movb    $0x4, %al
                movl    %esi, %ecx
                addl    $0x1c, %ecx
                xorl    %edx, %edx
                movb    $0xc, %dl
                int     $0x80
                # Escribir mensaje

Hay puedes ver un poco como se escribe.

Con respecto a lo de escribir por pantalla en msdos... hice una vez en la facu un programa en ensamblador que debia entre otras cosas imprimir cosas por pantalla y recuerdo que teniamos que escribir en ciertas direcciones de memoria concreta que era donde msdos consideraba la pantalla, esas direcciones eran desde 0xb800 hasta 4000 posiciones mas alla... prueba a ver...
En línea

-= Happy hacking =-
sirdarckcat
Troll Buena Onda y
CoAdmin
***
Desconectado Desconectado

Mensajes: 6.947


Lavando Platos


Ver Perfil WWW
Re: Preguntas sobre Buffer overflows
« Respuesta #4 en: 3 Septiembre 2006, 01:50 »

Ole te explico la diferencia de GAS y Intel :P
Intel es es las comun, y AT&T es otro muy comun, muy pocas veces he visto GAS, pero su sintaxis es muy similar a Intel, solo cambian algunas cosas..

Sobre lo de porque no funciona en el tASM no sabria decirto, yo he usado nASM y mASM y en ambos me funciona con el modelo small.. sinembargo, la mayoria de las veces si voy a programar en ASM, lo hago en un compilador en C, con __asm__{/*codigo asm*/}

en fin..
debes investigar si debes cambiar alguna configuracion, para que tASM te permita escribir en modelo de 16 bits, pero no veo para que si 32 es mas robusto.

Saludos!!
En línea

y0mism0

Desconectado Desconectado

Mensajes: 238


Ver Perfil
Re: Preguntas sobre Buffer overflows
« Respuesta #5 en: 3 Septiembre 2006, 02:11 »

Weno, escribo d nuevo la respuesta, la escribi hace unas horas, pero como esta web va tan mal ultimamente, se kedo en blanco la pantalla y se me jodio en mensaje :(.

En primer lugar uso el compilador "Turbo Assembler  Version 2.01  Copyright (c) 1988, 1990 Borland International".
Cada vez k pongo los registros con la "e" al principio, me dice algo como " nombre indefinido". y eso k trabajo en win de 32 bits, no en ms2.
 Escribi tu codigo y lo intente compilar, me di muchos errores. Para empezar no renoce "ecx" (x la "e"), tp renoce el caracter "$", y muchos mas errores. Puse este code:

Código:
.model small
.stack
.data
.code
                movb    $0x5, %al
                movl    %esi, %ebx
                addl    $0x10, %ebx
                xorl    %ecx, %ecx
                movb    $0x1, %cl
                int     $0x80
                # Abrir la pantalla

Yo no se si es por el compilador, o eske no lo escribo bien, o k ese compilar tiene una sistaxis especifica.... PUede k sea proble del compilador? influye el SO en k lo ejecutas para k funcione o no?

Lo me imprimir una cadena por pantalla, lo probe como me dijiste Ole, y no m funciono. Escuche k se puede hacer llamando a la funcion printf del SO, pero como se hace eso con el ASM? POr ej haciendo una comparacion con el lenguaje C, k es el entiendo, como se haria en ASM un "printf("hola");" ? Que hace exactamente esta instruccion, llama a la funcion printf del SO, o k?¿

En fin, decirme codo puedo escribir esto en ASM, y recomendarme un compilador, o ayudarme con la sintaxis de este, porke no consigo escribir ningun programa con este compilador, solo escribi 1 k copiaba un entero a un registro, solo consigo hacer programas en el debug, pero tiene muchos inconvenientes....

PD: Acabo de leer tu msn, Sdc, y yo no quiero escribir en modelo  d 16 bits, sino en 32 bits :)

Y otra cosa, si escribo en un compilador C, el codigo ASm, tengo k escribir las polladas esa d .model small, .stack, etc...?¿ Me recomiendas k lo escriba desde ahi?

SAludos.
« Última modificación: 3 Septiembre 2006, 02:14 por loko_69 » En línea
sirdarckcat
Troll Buena Onda y
CoAdmin
***
Desconectado Desconectado

Mensajes: 6.947


Lavando Platos


Ver Perfil WWW
Re: Preguntas sobre Buffer overflows
« Respuesta #6 en: 3 Septiembre 2006, 03:30 »

el de Ole es de GAS, no se si sirve en tASM
Esto hace que sea de 16 bits:
.model small

en C no necesitas poner eso, es 32 bits por defecto, incluso las funciones, variables y demas puedes usarlas como etiquetas.

Saludos!!
En línea

y0mism0

Desconectado Desconectado

Mensajes: 238


Ver Perfil
Re: Preguntas sobre Buffer overflows
« Respuesta #7 en: 4 Septiembre 2006, 04:15 »

oki, lo intentare aora con otro manual k viene enfocado al tasm a ver si me salen los programas , :D

EN ese manual tb venia inf sobre la pila y lo entendi algo mejor, posteo las dudas k me kedaron para ver si me la podeis aclarar.

Supongamos k esta es la pila :
 
                                                                                       
                                                               


|------||------||------||------||------||------||------||------||------|
                                                                                    ^
                                                                                  (esp 
                                                                                     y
                                                                                  ebp)

Si llamamos a la funcio call :


    SUB     ESP,2
    MOV     EBP,ESP
    MOV     Word ptr[EBP],EIP
    push eip ; se pone el offset de la siguiente instruccion a               
                 ;ejecutar (el ret addres)
                 ; despues de esto se meteria el valor del segmento     
                 ;CS de =     
                 ;manera k eip
jmp funcion; se iria a la funcion hasta encontrar la instruccion   
                 ;ret y volveria a la dire de memoria almacenada 
                  ;en la pila ( el eip y su respectivo segmento CS)
 la pila estaria asi :

|------||------||------||------||------||CS||EIP||arg||arg|
                                                    ^
                                           ESP y ESP apuntarian aki

Tras el pop, la pila kedaria como en el primer dibujo. Hasta aki es lo k entendi yo. K el esp se va moviendo conforme se van almacenando cosas en la pila y el ebp, le va "siguiendo" para utilizarlo como referencia para almacenar los argumentos, el EIP y el CS. Al final, despues del pop, kedarian los 2 como al principio. Correjirme si me ekivoco xfavor.
Lo k ya no entiendo eso lo de las posiciones relativas de memoria. Segun mi eskema, lo unico k entenderia seria esto:



                                               -10    -9   -8   -4      0
|------||------||------||------||------||CS||EIP||arg||arg|
                                                    ^
                                           ESP y ESP apuntarian aki

En el dibujo de antes.... Suponinedo k los arg ocuapn 4 bytes y el Eip y el CS, 1 byte cada uno (nose si es asi).

En definitiva, nose si entendi bien, lo primero, pero lo q no entendi son los eskemas de las posiciones relativas de memoria 
k me pusiste,,, Aclararme esto xfavor ;)

SAludos. :)

« Última modificación: 4 Septiembre 2006, 04:17 por loko_69 » En línea
sirdarckcat
Troll Buena Onda y
CoAdmin
***
Desconectado Desconectado

Mensajes: 6.947


Lavando Platos


Ver Perfil WWW
Re: Preguntas sobre Buffer overflows
« Respuesta #8 en: 4 Septiembre 2006, 04:41 »

La pila esta asi :

--ESP actual
---DATOS funcion actual
--EBP de la funcion anterior
--EIP (a donde regresar al terminar la funcion actual)
---DATOS funcion anterior
--EBP de la funcion anterior
--EIP (a donde regresar al terminar la funcion)
---DATOS funcion anterior
--EBP de la funcion anterior
--EIP (a donde regresar al terminar la funcion)
---DATOS funcion anterior
--EBP de la funcion anterior
--EIP (a donde regresar al terminar la funcion)
---DATOS funcion anterior
--EBP de la funcion anterior

cuando llamas a otra funcion, se pone en el tope de la pila la direccion de EBP, y despues se sube ESP, y se meten los datos..

ya entiendes?

Saludos!!
En línea

y0mism0

Desconectado Desconectado

Mensajes: 238


Ver Perfil
Re: Preguntas sobre Buffer overflows
« Respuesta #9 en: 4 Septiembre 2006, 18:38 »

Si, lo entiendo, pero si la pila es una estructura lifo, no deberia estar asi :

--ESP actual
--EBP de la funcion anterior
--EIP (a donde regresar al terminar la funcion actual)
---DATOS funcion actual
---DATOS funcion anterior
--EBP de la funcion anterior
--EIP (a donde regresar al terminar la funcion)
---DATOS funcion anterior
--EBP de la funcion anterior
......

Para q al almacenar los datos, sobreescribiera el ret y el ebp anterior? ( se supone q los datos se introducen de abajo a arriba, segun la regla lifo).

Saludos y gracias . ;)
En línea
Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  
Powered by SMF 1.1.16 | SMF © 2006-2008, Simple Machines