Tema destacado: Entra al canal IRC oficial de #elhacker.net
Autor
|
Tema: Preguntas sobre Buffer overflows (Leído 2,307 veces)
|
y0mism0
Desconectado
Mensajes: 238
|
Estuve leyendo el manual k pusieron por ai arriba sobre buffers overflows, y tengo algunas dudas k no entendi bien: 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
Mensajes: 6.947
Lavando Platos
|
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: 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: 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.  Saludos!!
|
|
|
|
|
En línea
|
|
|
|
y0mism0
Desconectado
Mensajes: 238
|
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: - 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 : .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. .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
Mensajes: 130
|
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
Mensajes: 6.947
Lavando Platos
|
Ole te explico la diferencia de GAS y Intel  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
Mensajes: 238
|
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: .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
Mensajes: 6.947
Lavando Platos
|
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
Mensajes: 238
|
oki, lo intentare aora con otro manual k viene enfocado al tasm a ver si me salen los programas ,  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
Mensajes: 6.947
Lavando Platos
|
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
Mensajes: 238
|
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
|
|
|
|
|
|