Los canarios y otros volátiles no evitan el desbordamiento ; solo tratan de hacer frente a las consecuencias de un desbordamiento que ha sucedido . El canario intenta detectar el caso de un desbordamiento que sobrescribió la dirección de retorno en un marco de pila. DEP es un paso más allá, asume que la dirección de retorno se ha sobrescrito y seguido , y restringe las áreas donde la ejecución podría saltar. ASLR es todavía un paso más allá: "baraja" las áreas donde se permite la ejecución .
Históricamente, los desbordamientos de búfer fueron explotados para sobrescribir la dirección de retorno en la pila, para que la ejecución salte a los mismos datos que se han utilizado para desbordar el búfer. El canario intenta detectar eso antes de saltar, y DEP se usa para hacer que el espacio de pila no sea ejecutable. DEP también funciona cuando se desbordan los búferes en el montón (el canario es de alguna utilidad solo para desbordamientos de búfer de pila, pero el montón puede contener búferes y también datos confidenciales para sobrescribir, como punteros a funciones, especialmente en el contexto de OOP lenguajes como C ++). Para evitar el DEP y el canario, los atacantes han comenzado a buscar desbordamientos que permiten sobrescribir los punteros para que funcionen, a fin de hacer que la ejecución salte al código de biblioteca estándar , que es necesariamente "allí" y también necesariamente ejecutable. . Es por eso que se inventó ASLR: para hacer más difíciles tales juegos. ASLR aún puede ser derrotado siendo afortunado: dado que ASLR debe mantener la alineación de la página (4 kB en x86), dentro de un espacio de direcciones no muy grande (generalmente menos de 2 GB en 32 bits x86), no hay tantos lugares donde puede estar el código objetivo (como máximo medio millón). Dependiendo del contexto del ataque y de la frecuencia con la que el script del atacante puede intentarlo, esto puede ser demasiado bajo para su comodidad.
El tema importante aquí es que los canarios, DEP y ASLR no vencen a los desbordamientos en sí mismos, sino que apuntan a los métodos de explotación de desbordamiento genéricos que tradicionalmente se han empleado. En cualquier aplicación, un desbordamiento que sobrescribe los datos no punteros puede ser tan mortal como un exploit de shell remoto (por ejemplo, imagine un desbordamiento que modifique un campo de cadena llamado " authenticated_user_name
"). La carrera armamentística entre los atacantes y los defensores se está volviendo demasiado especializada y, en mi opinión, cada vez pierde más el punto. En general, es mucho mejor nunca permitir que se produzca el desbordamiento, es decir, bloquear / eliminar el proceso / subproceso ofensivo antes de escribir bytes fuera del búfer de destino. Eso es lo que sucede con casi cualquier lenguaje de programación decente (Java, C #, VB.NET, Python, Ruby, Node.js, OCaml, PHP ... la elección es grande).