El problema con los desbordamientos de búfer es que un búfer está sobrepasado, esto no tiene sentido, es decir, es un error, después de lo cual el comportamiento del código de la aplicación deja de seguir el plan preestablecido.
El método clásico, digamos incluso primitivo , para explotar un desbordamiento de búfer es sobrescribir la ranura de dirección de retorno de una función, de modo que la ejecución se descarrile en una ubicación que el atacante controla. Esto funciona solo para buffers basados en pila, y la industria ha ideado varias contramedidas para dificultar la explotación del atacante, por ejemplo. canaries (para detectar un desbordamiento antes de usar la ranura de dirección de retorno) y ASLR (para que el salto sea controlado de forma menos confiable por el atacante).
La arquitectura SPARC incluye registrar ventanas , que puede verse como una pila dedicada en la CPU, mantenida fuera del espacio de direcciones de la memoria principal. Por lo tanto, se puede interpretar que SPARC es de alguna manera "inmune" a los desbordamientos de búfer ya que la ranura de dirección de retorno no se puede sobrescribir con un acceso basado en memoria. Sin embargo, esto no es cierto, por las siguientes razones:
-
Las ventanas de registro solo están en un número limitado (como máximo 32 en la definición de arquitectura); cuando la profundidad de la llamada excede el número de ventanas en la CPU, se produce una excepción y una rutina dedicada vacía algunas de ellas en la RAM, para volver a cargarlas más tarde. Por lo tanto, las ventanas realmente funcionan como un caché sobre RAM; la consecuencia es que una ranura de dirección de retorno todavía puede sobrescribirse en algunos casos.
-
Hay más que la ranura de dirección de retorno en la vida. Básicamente, cualquier campo que contenga funcionalmente un puntero a algún código es un buen objetivo para los atacantes. Los lenguajes orientados a objetos como C ++ están llenos de tales ranuras, tanto en la pila como en la RAM principal (se denominan vtables ). La ranura de la dirección de retorno solo es tradicionalmente el objetivo principal del atacante, porque hace 20 años era el más fácil de alcanzar. (Un famoso exploit que aprovechó esos punteros de función no apilados después de un desbordamiento de búfer fue el Jailbreak de PS3 .)
-
Cualquier sobrescritura de datos puede ser útil para el atacante; aunque inyectar su propio código le da el mayor poder, otros tipos de desbordamiento pueden llevar a una explotación exitosa. Piense, por ejemplo, en el error del corazón que estaba de moda hace unos meses; hizo que miles de administradores de sistemas y los llamados expertos en seguridad gritaran y corrieran por el pánico ("como pollos sin cabeza", como dicen por aquí); y, sin embargo, solo fue un desbordamiento de lectura , donde no se sobrescribió nada en absoluto.
Un punto crucial es que todos estos canarios y ASLR y las ventanas de registro son solo formas de tratar de hacer frente a las consecuencias del desbordamiento. La aplicación todavía se ha descarrilado y los datos aún están dañados. Sería mucho mejor actuar un poco antes, y evitar que se produzca el desbordamiento. Idealmente con un análisis riguroso en tiempo de compilación (posiblemente con el ayuda del compilador), o al menos bloqueando el intento de desbordamiento en el tiempo de ejecución, convirtiéndolo en una excepción: la aplicación todavía deja de funcionar correctamente, pero al menos lo hace de manera limpia, sin seguir a ciegas las estructuras de memoria dañadas.
Por lo tanto, para la defensa contra desbordamientos de búfer, la tecnología interesante adquirida (y luego eliminada) por Oracle no es SPARC, sino Java.