El último post acababa con este figura:
En el que le flecha verde indica el flujo del programa cuando no coincide las contraseñas y la flecha roja señala lo que queremos hacer: que la intrucción RET nos lleve a la dirección de memoria 0x4017F2.
Para conseguirlo sólo tendremos que colocar en la entrada adecuada de la pila el valor 0x4017F2 y habremos conseguido anular el control de contraseñas.
Damos nuevamente una ejecución al programa y previamente pondremos un breakpoint en la instrucción LEAVE, cuando el programa se detenga analizaremos la pila:
Podemos ver, de abajo a arriba y a partir de la dirección 0x22FF18 el espacio reservado para las variables in1 e in2.
A continuación a continuación la memoria reservado para la matriz arr[20] que al ser de tipo integer tiene cada entrada tiene una longitud de 4 octetos. Y encima de ella está la matriz var[20] que tiene una longitud de 20 octetos.
Como dije en el segundo post de esta serie inicialicé las matrices con los valores 6 y 7 para que nos fuera más fácil indentificar dentro de la pila.
Los valores que tenemos en estas variables son:
in1: 0x02
in2: 0x5D (Dec 93)
La tercera entrada de la matriz arr (arr[2]) con el valor 0x5D y el string var tiene en la cadena de caracteres "93" con su finalización en 0x00.
Un poco más abajo encontramos una dirección que también pertenece a nuestro programa y que por su proximidad tiene todas las probabilidades de ser la dirección que debemos modificar. Lo comprobamos pulsando F7 (paso a paso) y confirmamos nuestra suposición.
Esta entrada dentro de la pila está siete palabras más allá de la finalización de la matriz arr (en arr[26]). Ya sabemos que colocar en el primer registro del fichero de parámetros.
El segundo registro contendrá la dirección a donde queremos dirigir el retorno que, como hemos dicho arriba, es la dirección 0x4017F2 (4200434 en decimal).
Nuestro fichero de parámetros debe quedar entonces así:
26
4200434
Hacemos una nueva ejecución con esos valores y vamos a la ventana de ejecución vemos:
Recordemos el código fuente:
if (arr[in1] != tabla[in1])
{
printf("La coordenada no es correcta\n");
return ;
}
printf("La coordenada es correcta\n");
printf(mensaje4);
Al no ser correcta la contraseña vemos el mensaje que nos lo indica y a continuación el programa debería de salir, pero hemos aprovechado una vulnerabilidad del programa que permite aprovechar un desbordamiento de pila y hemos alterado la dirección de retorno para en vez de salir nos lleve a la parte de código que se ejecuta cuando la contraseña es correcta.
Y ni siquiera el tener el bit NX / DX activado hubiera impedido explotar esta vulnerabilidad......
No hay comentarios:
Publicar un comentario