¿Siempre tengo que sobrescribir el EIP para poder escribir en la pila en un desbordamiento de búfer? ¿Cómo está organizada la memoria? No puedo encontrar un gráfico adecuado con google
¿Siempre tengo que sobrescribir el EIP para poder escribir en la pila en un desbordamiento de búfer? ¿Cómo está organizada la memoria? No puedo encontrar un gráfico adecuado con google
No siempre tiene que sobrescribir la dirección de retorno para explotar un desbordamiento de búfer basado en la pila (también tiene un gran diagrama de la disposición de la pila). Con un desbordamiento de búfer basado en la pila puede corromper otras variables declaradas en el ámbito local de la función que pueden producir resultados interesantes.
Por ejemplo, digamos que hay una función de autenticación:
//I like to think of the return address as sitting on top of every function.
//void * ret;
boolean login(char * password){
boolean is_logged_in=False;
char buf[5];
strcpy(buf,password);
if(strmp(buf, MASTER_PASSWORD)==0){
is_Logged_int=True;
}
return is_logged_in;
}
El diseño de la pila es tal que is_logged_in
está por encima de buf. El marco de pila, que contiene la dirección de retorno está en algún lugar por encima de is_logged_in
. La dirección de retorno se convertirá en el EIP solo cuando la función regrese. Pero no es necesario que el atacante dañe el marco de la pila para que el atacante aproveche este desbordamiento de búfer. Simplemente sobrescribir el valor de is_logged_in
con un valor que es igual a True
permitirá que el atacante se autentique sin conocer el valor de MASTER_PASSWORD
.
En esta vulnerabilidad de desbordamiento de búfer, el uso de: ASLR, NX Zones y Stack Canaries no impide la explotación. De hecho, también es probable que el mismo exploit funcione sin importar la plataforma (windows / linux / arm / x86 ...).
(Descargo de responsabilidad: creo que leí sobre este método de explotación en "Hacking: The Art of Exploitation")
Es al revés: desbordas un búfer de pila para que sobrescribas el campo con el que se cargará el EIP cuando la función regrese.
En las arquitecturas habituales, la pila crece hacia abajo, de modo que la "dirección de retorno" insertada en la pila cuando se llama la función se encuentra unos pocos bytes después de las variables locales. Al desbordar un búfer local, puede sobrescribir lo que se encuentra después en la RAM, es decir, la dirección de retorno. Cuando la función regresa, el código de operación ret
correspondiente carga la dirección de retorno en EIP, lo que significa que la ejecución salta en esa dirección.
Lea otras preguntas en las etiquetas exploit buffer-overflow shellcode