Les canaris et autres volatiles n'empêchent pas le débordement ; ils essaient juste de faire face aux conséquences d'un débordement qui s'est produit . Le canary tente de détecter le cas d'un débordement qui a écrasé l'adresse de retour dans un cadre de pile. DEP est un pas de plus, il suppose que l'adresse de retour a été écrasée et suivie , et il restreint les zones où l'exécution pourrait sauter. ASLR est encore un pas de plus: il «mélange» les zones où l'exécution est autorisée.
Historiquement, les débordements de tampon étaient exploités pour écraser l'adresse de retour dans la pile, de manière à pour faire sauter l'exécution dans les données mêmes qui ont été utilisées pour déborder le tampon. Le canary tente de détecter cela avant de sauter, et DEP est utilisé pour rendre l'espace de pile non exécutable. DEP fonctionne également en cas de débordement de tampons dans le tas (le canary n'est d'aucune utilité uniquement pour les débordements de tampon de pile, mais le tas peut également contenir des tampons, ainsi que des données sensibles à écraser, telles que des pointeurs vers des fonctions - en particulier dans le contexte de la POO langages tels que C ++). Pour contourner la DEP et le canari, les attaquants ont commencé à chercher des débordements qui permettent d'écraser les pointeurs pour fonctionner, afin de faire sauter l'exécution dans le code de bibliothèque standard qui est forcément "là" et aussi forcément exécutable . C'est pourquoi l'ASLR a été inventé: pour rendre ces jeux plus difficiles. L'ASLR peut encore être vaincu en étant chanceux: comme ASLR doit maintenir l'alignement des pages (4 ko sur x86), dans un espace d'adressage pas trop grand (généralement moins de 2 Go sur x86 32 bits), il n'y a pas tellement d'endroits où le code cible peut être (au plus un demi-million). Selon le contexte de l'attaque et la fréquence à laquelle le script de l'attaquant peut essayer, cela peut être trop bas pour le confort.
Le thème important ici est que les canaris, DEP et ASLR ne neutralisent pas les débordements eux-mêmes, mais ciblent les méthodes d'exploitation génériques de débordement qui ont été traditionnellement employées. Dans n'importe quelle application, un débordement qui écrase des données non pointeuses peut être aussi mortel qu'un exploit de shell distant (par exemple, imaginez un débordement qui modifie un champ de chaîne appelé " authenticated_user_name
"). La course aux armes entre attaquants et défenseurs devient trop spécialisée et, à mon avis, passe de plus en plus à côté. D'une manière générale, il est bien préférable de ne jamais permettre le débordement, c'est-à-dire bloquer / tuer le processus / thread incriminé avant d'écrire des octets en dehors du tampon cible. C'est ce qui se passe avec presque n'importe quel langage de programmation décent (Java, C #, VB.NET, Python, Ruby, Node.js, OCaml, PHP ... le choix est large).