d'exploitation de la sécurité informatique qui permet à un attaquant d'exécuter du code malgré la présence de défenses de sécurité qui l'empêcheraient autrement, telles que la protection de l'espace exécutable et la signature de code .
pile d'appels pour détourner le flux d'exécution du programme , puis exécute des séquences d'instructions machine soigneusement sélectionnées , déjà présentes en mémoire et appelées « gadgets ». Chaque gadget se termine généralement par une instruction de retour et se situe dans une sous-routine du programme existant et/ou du code de la bibliothèque partagée. Enchaînés, ces gadgets permettent à un attaquant d'effectuer des opérations arbitraires sur une machine dotée de défenses qui bloquent les attaques plus simples.
DrawLinea été appelée DrawSquare. Notez que la pile croît vers le haut dans ce diagramme.La programmation orientée retour est une version avancée d'une attaque par débordement de pile . Généralement, ce type d'attaque survient lorsqu'un attaquant manipule la pile d'appels en exploitant une faille du programme, souvent un dépassement de tampon . Lors d'un tel dépassement, une fonction qui n'effectue pas de vérification des limites avant de stocker des données fournies par l'utilisateur en mémoire accepte plus de données en entrée qu'elle ne peut en stocker correctement. Si les données sont écrites sur la pile, l'excédent peut saturer l'espace alloué aux variables de la fonction (par exemple, les variables locales dans le schéma de pile à droite) et écraser l'adresse de retour. Cette adresse sera ensuite utilisée par la fonction pour rediriger le flux de contrôle vers l' appelant . Si elle a été écrasée, le flux de contrôle sera dévié vers l'emplacement spécifié par la nouvelle adresse de retour.
Lors d'une attaque par dépassement de tampon classique, l'attaquant écrit simplement le code malveillant (la « charge utile ») sur la pile, puis écrase l'adresse de retour avec l'emplacement de ces instructions. Jusqu'à la fin des années 1990, les principaux systèmes d'exploitation n'offraient aucune protection contre ces attaques. Par exemple, Microsoft Windows n'a intégré aucune protection contre les dépassements de tampon avant 2004. Par la suite, les systèmes d'exploitation ont commencé à lutter contre l'exploitation des failles de dépassement de tampon en marquant la mémoire où les données sont écrites comme non exécutable, une technique appelée protection de l'espace exécutable . Une fois cette protection activée, la machine refuse d'exécuter tout code situé dans les zones mémoire accessibles en écriture par l'utilisateur, empêchant ainsi l'attaquant de placer la charge utile sur la pile et d'y accéder par écrasement de l'adresse de retour. Plus tard, des composants matériels ont été développés pour renforcer cette protection.
Grâce à la prévention de l'exécution des données, un attaquant ne peut exécuter directement les instructions écrites dans un tampon, car la zone mémoire de ce tampon est marquée comme non exécutable. Pour contourner cette protection, une attaque par programmation orientée retour n'injecte pas d'instructions malveillantes, mais utilise des séquences d'instructions déjà présentes dans la mémoire exécutable, appelées « gadgets », en manipulant les adresses de retour. Une implémentation classique de prévention de l'exécution des données est inefficace contre cette attaque, car l'attaquant n'exécute pas directement le code malveillant, mais combine des séquences d'instructions légitimes en modifiant les adresses de retour stockées ; le code utilisé est donc marqué comme exécutable.
Technique de retour en bibliothèque
Dans une attaque par retour dans une bibliothèque, un attaquant détourne le flux d'exécution du programme en exploitant une vulnérabilité de dépassement de tampon, comme décrit précédemment. Au lieu de tenter d'écrire une charge utile d'attaque sur la pile, l'attaquant choisit une fonction de bibliothèque disponible et écrase son adresse de retour avec son adresse d'entrée. D'autres adresses de la pile sont ensuite écrasées, en respectant les conventions d'appel applicables , afin de transmettre soigneusement les paramètres appropriés à la fonction et lui permettre d'exécuter une fonctionnalité utile à l'attaquant. Cette technique a été présentée pour la première fois par Solar Designer en 1997 et a ensuite été étendue à l'enchaînement illimité d'appels de fonctions
Fragments de code empruntés
L'avènement des processeurs x86 64 bits a entraîné une modification de la convention d'appel des sous-programmes, imposant le passage des premiers arguments d'une fonction dans les registres plutôt que sur la pile. De ce fait, un attaquant ne pouvait plus configurer un appel de fonction de bibliothèque avec les arguments souhaités en manipulant simplement la pile d'appels via une faille de dépassement de tampon. Les développeurs de bibliothèques partagées ont également commencé à supprimer ou à restreindre les fonctions effectuant des actions particulièrement utiles à un attaquant, telles que les wrappers d'appels système . Par conséquent, les attaques par retour dans la bibliothèque sont devenues beaucoup plus difficiles à mener à bien.
L'évolution suivante a consisté en une attaque utilisant des fragments de fonctions de bibliothèque, plutôt que des fonctions entières, pour exploiter les vulnérabilités de dépassement de tampon sur des machines protégées contre les attaques plus simples. Cette technique recherche des fonctions contenant des séquences d'instructions qui dépilent des valeurs dans des registres. Une sélection rigoureuse de ces séquences de code permet à un attaquant de placer les valeurs appropriées dans les registres adéquats afin d'effectuer un appel de fonction selon la nouvelle convention d'appel. Le reste de l'attaque se déroule comme une attaque par retour dans une bibliothèque.
Attaques
La programmation orientée retour s'appuie sur l'approche des blocs de code empruntés et l'étend pour fournir à l'attaquant des fonctionnalités Turing-complètes , notamment des boucles et des branchements conditionnels . Autrement dit, la programmation orientée retour fournit un « langage » pleinement fonctionnel qu'un attaquant peut utiliser pour faire exécuter à une machine compromise n'importe quelle opération. Hovav Shacham a publié cette technique en 2007 et a démontré comment toutes les constructions de programmation importantes peuvent être simulées à l'aide de la programmation orientée retour sur une application cible liée à la bibliothèque standard C et contenant une vulnérabilité de dépassement de tampon exploitable.
Une attaque par programmation orientée retour (REP) surpasse les autres types d'attaques évoqués, tant par sa puissance d'expression que par sa résistance aux mesures de défense. Aucune des techniques de contre-exploitation mentionnées précédemment, y compris la suppression pure et simple des fonctions potentiellement dangereuses des bibliothèques partagées, n'est efficace contre une attaque par programmation orientée retour.
Sur l'architecture x86
Bien que les attaques par programmation orientée retour puissent être menées sur diverses architectures, l'article de Shacham et la majorité des travaux ultérieurs se concentrent sur l'architecture Intel x86 . Cette architecture utilise un jeu d'instructions CISC à longueur variable . La programmation orientée retour sur x86 exploite la grande densité de ce jeu d'instructions : toute séquence d'octets aléatoire est susceptible d'être interprétable comme un ensemble valide d'instructions x86.
Il est donc possible de rechercher un opcode qui modifie le flux de contrôle, notamment l'instruction de retour (0xC3), puis de remonter dans le binaire pour trouver les octets précédents qui constituent des instructions potentiellement utiles. Ces ensembles d'instructions, appelées « gadgets », peuvent ensuite être chaînés en écrasant l'adresse de retour, via une exploitation de dépassement de tampon, avec l'adresse de la première instruction du premier gadget. La première adresse des gadgets suivants est alors écrite successivement sur la pile. À la fin du premier gadget, une instruction de retour est exécutée, ce qui dépile l'adresse du gadget suivant et effectue un saut vers celui-ci. À la fin de ce gadget, la chaîne se poursuit avec le troisième, et ainsi de suite. En chaînant ces courtes séquences d'instructions, un attaquant est capable de produire un comportement arbitraire à partir de code de bibliothèque préexistant. Shacham affirme que, pour toute quantité de code suffisamment importante (y compris, mais sans s'y limiter, la bibliothèque standard C), il existera suffisamment de gadgets pour une fonctionnalité Turing-complète.
Un outil automatisé a été développé pour faciliter le processus de localisation de gadgets et de construction d'une attaque contre un binaire. Cet outil, appelé ROPgadget, parcourt un binaire à la recherche de gadgets potentiellement utiles et tente de les assembler en une charge utile d'attaque qui ouvre un shell permettant à l'attaquant d'exécuter des commandes arbitraires.
Sur la randomisation de la disposition de l'espace d'adressage
La randomisation de l'espace d'adressage (ASLR) présente également des vulnérabilités. D'après l'article de Shacham et al. , l'ASLR sur les architectures 32 bits est limitée par le nombre de bits disponibles pour la randomisation d'adresse. Seuls 16 des 32 bits d'adresse sont disponibles, et une attaque par force brute sur 16 bits peut être contournée en quelques minutes. Les architectures 64 bits sont plus robustes, avec 40 des 64 bits disponibles pour la randomisation. Une attaque par force brute sur 40 bits est possible, mais a peu de chances de passer inaperçue. Outre les attaques par force brute, il existe des techniques pour supprimer la randomisation .
Même avec une randomisation parfaite, toute fuite d'informations sur le contenu de la mémoire permettrait de calculer l' adresse de base , par exemple, d'une bibliothèque partagée lors de l'exécution.
Sans utiliser l'instruction de retour
D'après l'article de Checkoway et al. il est possible de réaliser une programmation orientée retour sur les architectures x86 et ARM sans utiliser d'instruction de retour (0xC3 sur x86). Les auteurs ont plutôt utilisé des séquences d'instructions soigneusement conçues, déjà présentes en mémoire, pour simuler une instruction de retour. Cette instruction a deux effets : premièrement, elle lit la valeur de quatre octets en haut de la pile et positionne le pointeur d'instruction sur cette valeur ; deuxièmement, elle incrémente le pointeur de pile de quatre octets (équivalent à une opération de dépilement). Sur l'architecture x86, les séquences d'instructions jmp et pop peuvent jouer le rôle d'une instruction de retour. Sur ARM, les séquences d'instructions load et branch peuvent remplir ce rôle.
Cette nouvelle approche, n'utilisant pas d'instruction de retour, présente des inconvénients pour la défense. En effet, un programme de défense vérifie non seulement la présence de plusieurs retours, mais aussi de plusieurs instructions de saut, ce qui peut permettre de détecter cette attaque.
Défenses
G-Free
La technique G-Free a été développée par Kaan Onarlioglu, Leyla Bilge, Andrea Lanzi, Davide Balzarotti et Engin Kirda. Elle constitue une solution pratique contre toute forme de programmation orientée retour. Cette solution élimine toutes les instructions de branchement libre non alignées (instructions telles que RET ou CALL que les attaquants peuvent utiliser pour modifier le flux de contrôle) au sein d'un exécutable binaire et protège ces instructions contre toute utilisation malveillante. La manière dont G-Free protège l'adresse de retour est similaire au canari XOR implémenté par StackGuard. De plus, elle vérifie l'authenticité des appels de fonction en ajoutant un bloc de validation. Si le résultat attendu n'est pas trouvé, G-Free provoque le plantage de l'application.
randomisation de la disposition de l'espace d'adressage
Plusieurs techniques ont été proposées pour contrer les attaques basées sur la programmation orientée retour (POR). La plupart reposent sur la randomisation de l'emplacement du code du programme et des bibliothèques, empêchant ainsi un attaquant de prédire avec précision l'emplacement des instructions potentiellement utiles dans les gadgets et, par conséquent, de mener à bien une attaque POR. Une implémentation courante de cette technique, la randomisation de l'espace d'adressage (ASLR), charge les bibliothèques partagées à un emplacement mémoire différent à chaque chargement du programme. Bien que largement déployée par les systèmes d'exploitation modernes, l'ASLR est vulnérable aux fuites d'informations et à d'autres méthodes permettant de déterminer l'adresse de toute fonction de bibliothèque connue en mémoire. Si un attaquant parvient à déterminer l'emplacement d'une instruction connue, la position de toutes les autres peut être déduite et une attaque POR peut être construite.
Cette approche de randomisation peut être poussée plus loin en déplaçant séparément toutes les instructions et/ou autres éléments d'état du programme (registres et objets de pile), et non plus seulement les adresses des bibliothèques. Cela nécessite un support d'exécution important, tel qu'un traducteur dynamique logiciel, pour reconstituer les instructions randomisées à l'exécution. Cette technique permet de rendre les gadgets difficiles à trouver et à utiliser, mais elle engendre une surcharge significative.
le déploiement du logiciel . Une technique consistant à introduire des variations à chaque instance d'un programme en cours d'exécution peut considérablement renforcer l'immunité du logiciel aux attaques ROP (Remote Of Processing). Une attaque par force brute sur Cloud Lambda peut entraîner l'attaque de plusieurs instances du logiciel randomisé, ce qui réduit son efficacité. Asaf Shelly a publié cette technique en 2017 et a démontré l'utilisation de la randomisation binaire dans un système de mise à jour logicielle. Pour chaque appareil mis à jour, le service cloud introduit des variations dans le code, effectue une compilation en ligne et distribue le fichier binaire. Cette technique est très efficace car les attaques ROP reposent sur la connaissance de la structure interne du logiciel. Son principal inconvénient est que le logiciel n'est jamais entièrement testé avant son déploiement, car il est impossible de tester toutes les variations du logiciel randomisé. De ce fait, de nombreuses techniques de randomisation binaire sont applicables aux interfaces réseau et à la programmation système, mais sont moins recommandées pour les algorithmes complexes.
SEHOP
La protection contre l'écrasement des gestionnaires d'exceptions structurés est une fonctionnalité de Windows qui protège contre les attaques par dépassement de capacité de la pile les plus courantes, en particulier contre les attaques ciblant un gestionnaire d'exceptions structuré.
Contre les attaques par flux de contrôle
Avec la prolifération des petits systèmes embarqués due à l'expansion de l' Internet des objets , le besoin de protection de ces systèmes s'accroît également. L'utilisation du contrôle d'accès mémoire basé sur les instructions (IB-MAC), implémenté matériellement, permet de protéger les systèmes embarqués à faible coût contre les attaques par débordement de pile et les attaques par injection de flux de contrôle malveillant. Cette protection peut être assurée par la séparation de la pile de données et de la pile de retour. Cependant, en raison de l'absence d' unité de gestion de la mémoire dans certains systèmes embarqués, cette solution matérielle n'est pas applicable à tous les systèmes embarqués.
Contre les rootkits orientés vers le retour
En 2010, Jinku Li et al. ont proposé qu'un compilateur modifié puisse éliminer les « gadgets » orientés retour en remplaçant chaque instruction par la séquence d'instructions et chaque instruction par la séquence d'instructions , où représente une table immuable de toutes les adresses de retour « légitimes » du programme et représente un index spécifique dans cette table. Ceci empêche la création d'un gadget orienté retour qui retourne directement de la fin d'une fonction à une adresse arbitraire au milieu d'une autre fonction ; les gadgets ne peuvent donc retourner qu'à des adresses de retour « légitimes », ce qui augmente considérablement la difficulté de créer des gadgets utiles. Li et al. ont affirmé que « notre technique d'indirection du retour dégénéralise essentiellement la programmation orientée retour pour revenir à l'ancien style de retour dans la libc ». Leur compilateur de démonstration de faisabilité comprenait une phase d'optimisation par « peephole » pour traiter « certaines instructions machine qui contiennent le code d'opération de retour dans leurs codes d'opération ou leurs opérandes immédiats », comme .ARMv8.3-A introduit une nouvelle fonctionnalité au niveau matériel qui tire parti des bits inutilisés dans l'espace d'adressage des pointeurs pour signer cryptographiquement les adresses de pointeurs à l'aide d'un chiffrement par blocs ajustable spécialement conçu qui signe la valeur souhaitée (généralement une adresse de retour) combinée à une valeur de « contexte local » (par exemple, le pointeur de pile).
Avant d'effectuer une opération sensible (c'est-à-dire, revenir au pointeur enregistré), la signature peut être vérifiée pour détecter toute falsification ou utilisation dans un contexte incorrect (par exemple, l'utilisation d'une adresse de retour enregistrée à partir d'un contexte de trampoline d'exploitation).
Depuis la puce A12, Apple Silicon utilise l'architecture ARMv8.3 et des PAC. Linux a intégré la prise en charge de l'authentification par pointeur au sein du noyau dans la version 5.7 sortie en 2020 ; la prise en charge des applications en espace utilisateur a été ajoutée en 2018.
En 2022, des chercheurs du MIT ont publié une attaque par canal auxiliaire contre les PAC baptisée PACMAN .
Identification des cibles de branche (BTI)
Les instructions BTI sont utilisées dans les pages mémoire de code marquées comme « protégées » par le compilateur et l'éditeur de liens. Toute instruction de branchement indirect arrivant dans une page protégée, à une instruction autre qu'une instruction BTI, génère une erreur.
Les destinations identifiées où une instruction BTI est insérée représentent environ 1 % de toutes les instructions dans un code d'application moyen. Par conséquent, l'utilisation de BTI augmente la taille du code d'autant.
Les dispositifs utilisés dans une attaque ROP peuvent être situés n'importe où dans le code de l'application. Par conséquent, en moyenne, 99 % de ces dispositifs commencent par une instruction qui n'est pas une instruction BTI. Tout branchement vers ces dispositifs entraîne donc une erreur. Étant donné qu'une attaque ROP est constituée d'une chaîne de plusieurs dispositifs, la probabilité que tous les dispositifs d'une chaîne fassent partie des 1 % qui commencent par une instruction BTI est très faible.
Plus d articles de Worldlex Wiki
Revenez a l index pour explorer davantage de pages sur l histoire, la science, la culture, la geographie et la societe en francais.
Explorer l index