martes, 8 de julio de 2014

Programación dirigida por retorno. (III) - Atacando el programa

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