Voy al grano, me ha dao ultimamente por aprender sobre los buffers overflows y la programación de shellcodes (la verdad es que me estaba hasta ahora resultado mas sencillo de lo que siempre habia pensado :s), pero me he topado con un problema que no consigo incarle bien el diente y me siento un poco como buscando por donde no es, les explico.
Tengo este pequeño codigo de C:
unsigned char exploit[] = "\xe9\x28\x00\x00\x00\x5e\x89\x76\x08\xc7\x46\x0c"
"\x00\x00\x00\x00\xb8\x0b\x00\x00\x00\x89\xf3\x8d"
"\x4e\x08\xba\x00\x00\x00\x00\xcd\x80\xb8\x01\x00"
"\x00\x00\xbb\x00\x00\x00\x00\xcd\x80\x2f\x62\x69"
"\x6e\x2f\x73\x68\x00\xde\xad\xbe\xef\xde\xad\xbe"
"\xef";
int main()
{
int *ret;
ret = (int *)((&ret) + 2);
(*ret) = (int)exploit;
}
Weno el exploit supongo que todos os imaginais lo que es, el shellcode, y el main pos lo unico que pretende es sobreescribir la direccion de retorno con la direccion del exploit para que empiece a ejecutarlo. NOTA: Estoy sobre linux, ubuntu dapper y compilando con gcc 4.0.3 para ser mas exactos. Depuro con gdb
El shellcode lo he escrito en ensamblador y luego lo mire en binario con el gdb tb, aki pongo el codigo:
.text
.globl exploit
exploit: pushl %ebp
movl %esp, %ebp
subl $0x10, %esp
jmp 0x2c
popl %esi
movl %esi, 0x8(%esi)
movl $0x0, 0xc(%esi)
movl $0xb, %eax
movl %esi, %ebx
leal 0x8(%esi), %ecx
movl $0x0, %edx
int $0x80
movl $0x1, %eax
movl $0x0, %ebx
int $0x80
call -0x29
.string "/bin/sh"
.int
.int 0
leave
ret
.globl main
main: pushl %ebp
movl %esp, %ebp
subl $0x10, %esp
call exploit
leave
ret
No tiene mucha ciencia el main lo que hace es llamar a la funcion exploit y en esta otra pos primero hago las tipica rutina (prolog) que hace toda llamada a funcion y luego empieza lo que seria el exploit que tengo en C.
Desde el jmp hasta los 8 bytes posteriores a la ristra "/bin/sh" estan en el array de C. El jmp salta al call de abajo y este justo al pop %esi que hay debajo del jmp.
Este programa ensamblador no tira, da un segmentation fault y si se por que es o eso creo, en la instruccion "movl %esi,0x8(%esi)" se intenta escribir justo debajo de la ristra "/bin/sh" lo contenido en %esi que en ese caso es la direccion de la ristra, al intentar escribir en zona de codigo el SO las tiene marcadas "solo lectura" y por eso da el fallo.
Siento que esto se haga tan largo pero el problema es profundo
, si ya has llegado aqui eres un maxote! (o maxota si eres una tia xD), no te heches atras y sigue leyendo hombre!
.Para comprobar que el programa funcionaba y que crea el shell y tal hice el siguiente codigo:
.data
consola: .string "/bin/sh"
vector: .int consola
.int 0
.text
.globl rompete
rompete: pushl %ebp
movl %esp, %ebp
subl $0x10, %esp
# Rutinilla de toda funcion
movl $0xb, %eax
movl $consola, %ebx
leal vector, %ecx
movl $0x0, %edx
int $0x80
# Esto crea el shell
movl $0x1, %eax
movl $0x0, %ebx
int $0x80
# Esto hace un exit
leave
ret
.globl main
main: pushl %ebp
movl %esp, %ebp
subl $0x10, %esp
call rompete
# Se llama a la funcion, no retorna aqui nunca
leave
ret
Tpc tiene mucha ciencia, llamo al "rompete" que lo que hace es crear un shell... a mi me lo crea, solo le falta el jmp, el call y los movimientos de datos con pop y movl que hay en el otro, el por que de esas instrucciones son que cuando se empiece a ejecutar el exploit, no se sabe en que direcciones se colocan las cosas, tanto el jmp como el call pueden usar entre otras formas de direccionamiento, direccionamiento relativo, dependiendo de donde esten, se resta tal o cual cantidad de bytes como se les especifique y alli van, al ejecutar el jmp se va al call, y con este se vuelve al pop, PERO! al hacerlo metemos en la pila la direccion de la siguiente instruccion... la siguiente "instruccion" es "/bin/sh" xDD, es decir, tendriamos en pila la direccion absoluta de la ristra, por lo que ya sabemos en que direcciones rondamos. Se que para algunos esto sera obvio, pero si alguien lo mira pa aprender lo pongo por si acaso :s... sigamos.
Bueno volvemos a retomar la historia, el programa que hace la prueba para ver si creo shell funciona, el programa con jmp y demas lo desamble para crear el buffer del programa C con todas las instrucciones y datos necesarios, me he fijado en ponerlo en little endian pk lo estoy ejecutando sobre x86...
Pos bien, el programa C, esta explotando con un SIGSEGV, o sea, con un segmentation fault, lo he ejecutado paso a paso, y lo que es el main esta bien, se escribe en la direccion de retorno la direccion de "exploit" y se intenta ejecutar esto, pero nada mas ir a ejecutar la primera instruccion es donde esta petando y no se porque es... esta en little endian, he comprobado y recomprobado mil veces los numeros, es memoria de datos por lo tanto es de lectura-escritura... ¿ustedes que creen que puede ser?
Pongo aqui la ejecucion que hice con el gdb pa que miren un poco, esta no es la unica que he hecho, la trigesima tal vez xD
Breakpoint 1, main () at pruebaexplota.c:12
12 ret = (int *)((&ret) + 2);
(gdb) p /x &ret
$1 = 0xbf85cd14
(gdb) p /x $ebp
$2 = 0xbf85cd18
(gdb) s
13 (*ret) = (int)exploit;
(gdb) p /x ret
$3 = 0xbf85cd1c
(gdb) s
14 }
(gdb) p /x ret
$4 = 0xbf85cd1c
(gdb) p /x *ret
$5 = 0x8049580
(gdb) p /x &exploit
$6 = 0x8049580
(gdb) s
0x08049580 in exploit ()
(gdb) s
Single stepping until exit from function exploit,
which has no line number information.
Program received signal SIGSEGV, Segmentation fault.
0x080495ae in exploit ()
(gdb)
La idea es que al llegar a la asignacion la pila esta asi:
------------------------
|_____ret_______|
|__antiwo ebp__| <-- ebp
|__antiwo eip___| <-- a sobreescribir con direccion de "exploit"
| lo que sea |
Vemos que la direccion de ret al principio es justo por encima de ebp, como debe ser, vemos que le digo que apunte a justo por debajo de ebp, como debe ser, vemos como se pone la correcta direccion de "exploit", tb vemos como se llega a saltar al retornar de main a exploit, aqui se me olvido imprimir el eip pa que se vea como contiene la direccion y tb lo apuntado por eip (la instruccion jmp) pa que se vea como contiene 0x000028e9, pero haced un acto de fe y creerlo pk ya lo he comprobado varias veces y justo cuando le toca saltar peta...
Niano niano niaaaa...
Ustedes diran explode masters xDD










Autor



En línea



