Question:
Débordements de pile - Vaincre les Canaries, ASLR, DEP, NX
sudhacker
2012-09-21 18:09:13 UTC
view on stackexchange narkive permalink

Pour éviter les débordements de tampon, plusieurs protections sont disponibles telles que l'utilisation des valeurs Canary, ASLR, DEP, NX. Mais là où il y a une volonté, il y a un moyen. Je fais des recherches sur les différentes méthodes qu'un attaquant pourrait éventuellement contourner ces schémas de protection. Il semble qu'il n'y ait pas un seul endroit où des informations claires sont fournies. Voici quelques-unes de mes réflexions.

Canary - Un attaquant pourrait comprendre la valeur de Canary et l'utiliser dans son injection de tampon pour empêcher le stack guard de détecter un exploit

DEP, NX - S'il y a des appels à VirtualAlloc (), VirtualProtect () , le l'attaquant pourrait essayer de rediriger le code vers ces fonctions et désactiver DEP, NX sur les pages sur lesquelles il souhaite injecter du code arbitraire.

ASLR - Aucun indice. Comment fonctionnent ASLR et DEP?

[Cet article de 2014] (http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=6956567) décrit une technique qu'ils appellent Blind Return Oriented Programming (BROP) qui est comme ROP mais n'exige même pas connaissance de la source ou du binaire.
Trois réponses:
Polynomial
2012-09-21 20:06:24 UTC
view on stackexchange narkive permalink

Canary
Les canaris de pile fonctionnent en modifiant les régions de prologue et d'épilogue de chaque fonction pour placer et vérifier une valeur sur la pile respectivement. En tant que tel, si un tampon de pile est écrasé pendant une opération de copie de mémoire, l'erreur est remarquée avant l'exécution du retour de la fonction de copie. Lorsque cela se produit, une exception est déclenchée, qui est transmise à la hiérarchie du gestionnaire d'exceptions jusqu'à ce qu'elle atteigne enfin le gestionnaire d'exceptions par défaut du système d'exploitation. Si vous pouvez remplacer une structure de gestionnaire d'exceptions existante dans la pile, vous pouvez la faire pointer vers votre propre code. Il s'agit d'un exploit de gestion structurée des exceptions (SEH), et il vous permet d'ignorer complètement la vérification Canary.

DEP / NX
DEP et NX marquent essentiellement les structures importantes en mémoire comme non exécutables et forcez les exceptions au niveau matériel si vous essayez d'exécuter ces régions de mémoire. Cela rend les débordements de tampon de pile normaux où vous définissez eip sur esp + offset et exécutez immédiatement votre shellcode impossible, car la pile n'est pas exécutable. Contourner DEP et NX nécessite une astuce intéressante appelée Programmation orientée retour.

La ROP consiste essentiellement à rechercher des extraits de code existants du programme (appelés gadgets) et à y accéder, de sorte que vous produisez un résultat souhaité. Puisque le code fait partie de la mémoire exécutable légitime, DEP et NX n'ont pas d'importance. Ces gadgets sont enchaînés via la pile, qui contient votre charge utile d'exploit. Chaque entrée de la pile correspond à l'adresse du prochain gadget ROP. Chaque gadget est sous la forme de instr1; instr2; instr3; ... instrN; ret , afin que le ret passe à l'adresse suivante de la pile après avoir exécuté les instructions, enchaînant ainsi les gadgets ensemble. Souvent, des valeurs supplémentaires doivent être placées sur la pile afin de terminer avec succès une chaîne, en raison d'instructions qui autrement se trouveraient gênantes.

L'astuce consiste à enchaîner ces ROP ensemble afin d'appeler une fonction de protection de la mémoire telle que VirtualProtect , qui est ensuite utilisée pour rendre la pile exécutable, afin que votre shellcode puisse fonctionner, via un jmp esp ou gadget équivalent. Des outils tels que mona.py peuvent être utilisés pour générer ces chaînes de gadgets ROP ou trouver des gadgets ROP en général.

ASLR
Il existe plusieurs façons de contourner ASLR:

  • Écrasement RET direct - Souvent, les processus avec ASLR chargeront toujours des modules non ASLR, vous permettant d'exécuter simplement votre shellcode via un jmp esp .
  • Écrasement partiel d'EIP - N'écrase qu'une partie d'EIP, ou utilise une divulgation d'informations fiable dans la pile pour trouver ce que devrait être le véritable EIP, puis utilise-le pour calculer votre cible. Nous avons encore besoin d'un module non ASLR pour cela.
  • NOP spray - Créez un gros bloc de NOP pour augmenter les chances d'atterrissage sur la mémoire légitime. Difficile, mais possible même lorsque tous les modules sont activés ASLR. Cela ne fonctionnera pas si DEP est activé.
  • Bruteforce - Si vous pouvez essayer un exploit avec une vulnérabilité qui ne fait pas planter le programme, vous pouvez brutaliser 256 adresses cibles différentes jusqu'à ce que cela fonctionne.

Lecture recommandée:

Excellent post, question mineure: je n'ai jamais entendu le terme "NOP spray" mais cela semble équivalent à un "NOP sled" ou "NoOP sled" qui décrit plus précisément l'action de glisser sur la mémoire intermédiaire pour arriver à un bon endroit. Est-ce la même chose que celle dont vous parlez, ou y a-t-il une distinction subtile qui fait du «spray NOP» une chose distincte? Merci...
Oui, un spray NOP et un traîneau NOP sont exactement la même chose. Je viens de jouer avec [heap sprays] (http://en.wikipedia.org/wiki/Heap_spray) récemment, alors j'ai opté pour la terminologie qui était au sommet de ma tête.
@Polynomial: Dans votre réponse ici: http: //security.stackexchange.com/questions/18556/how-do-aslr-and-dep-work, vous aviez mentionné l'application matérielle de NX. Donc, contourner DEP en utilisant ROP (en utilisant `VirtualProtect ()`) fonctionnera-t-il toujours si le bit NX est appliqué par le matériel?
Oui. Le bit NX fournit simplement une application matérielle de l'indicateur de protection de la page mémoire exécutable. Avec NX désactivé, il est trivial d'exécuter des pages qui n'ont pas le bit exécutable défini, car le processeur ne reconnaîtra pas la différence. Avec NX activé, vous ne pouvez pas exécuter de pages non exécutables. Cependant, `VirtualProtect` modifie les indicateurs de protection sur la page, de sorte qu'elle est en fait marquée comme exécutable, ce que le CPU autorisera ensuite.
@Polynomial: Il semble que cela ne s'applique pas aux débordements de tas, n'est-ce pas?
@user2284570, s'il vous plaît ne postez pas le même commentaire sous chaque réponse. Oui, cela s'applique aux débordements de tas.
Une observation reg NX: à partir de Linux 2.6.38 sur l'IA-32, si le processeur le prend en charge, le bit NX sera toujours activé quel que soit le paramètre BIOS de celui-ci.Voir le commit ici: https://github.com/torvalds/linux/commit/ae84739c27b6b3725993202fe02ff35ab86468e1
Thomas Pornin
2012-09-21 19:49:45 UTC
view on stackexchange narkive permalink

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).

+1 pour résoudre le problème réel (langages de programmation qui permettent des débordements). Vous voudrez peut-être mentionner que de nombreux langages de script (en vous regardant, Python) ont des modules écrits en C pour les performances, en particulier des modules qui traitent du réseau (et sont donc potentiellement exposés au débordement)
@devnul3: Je serais très heureux d’obtenir une implémentation pure python de zlib par exemple. * (c'est à cause de ce genre de choses que la plupart des idées de sécurité d'ibm comme / 400 sont en train de mourir) *
@user2284570 Je préférerais une implémentation pure de Rust.Je pense personnellement que C et C ++ sont obsolètes pour cette seule raison.Les directives de base du C ++ peuvent être en mesure de résoudre ce problème, S'ils peuvent créer un sous-ensemble utile de C ++ qui peut être mécaniquement prouvé sans comportement indéfini.
@Demi: Je disais cela parce que j'avais besoin de python.
@user2284570 One pourrait exposer une API C à la bibliothèque Rust.
@Demi: alors vous n'avez pas compris ce que je veux dire.zlib fait partie de python standard, mais il est implémenté comme un wrapper dans la bibliothèque C.Mais aucun C n’est pas mort.C est comme le charbon: nous en avons besoin à cause de son succès, sinon, bonne chance pour faire tourner python ou rouille sur un pic16f877 ou un Z80 :-).
D.W.
2012-09-23 05:47:11 UTC
view on stackexchange narkive permalink

Le niveau de protection de base est ASLR + DEP.

Si vous n'utilisez pas les deux, alors il existe de nombreuses techniques puissantes pour exploiter un dépassement de tampon (par exemple, calcul orienté retour, tas pulvérisation, devinettes répétées). Par exemple, le DEP seul peut être vaincu en utilisant le calcul orienté retour; et ASLR seul peut être vaincu en utilisant une pulvérisation en tas et des tentatives répétées.

Cependant, si la cible utilise à la fois ASLR + DEP, l'exploitation devient beaucoup plus difficile. Les techniques mentionnées ci-dessus ne sont pas suffisantes pour vaincre ASLR + DEP.ASLR + DEP sont comme un double coup de poing qui rend la vie de l'attaquant beaucoup plus difficile. / p>

Mon exemple préféré de méthodes pour vaincre ASLR + DEP est expliqué dans la présentation de diapositives, Exploitation de l'interpréteur: Inférence de pointeur et pulvérisation JIT. Là, l'auteur décrit comment il a exploité une erreur de sécurité mémoire dans Flash. Il a exploité les propriétés du Flash JIT pour organiser la mémoire de manière à lui permettre de monter une attaque par injection de code, malgré la présence d'ASLR + DEP. Rappelez-vous qu'un JIT est un compilateur juste à temps; il compile les bytecodes Flash en code natif. Le code natif sera stocké quelque part en mémoire, et le Flash JIT le marque comme exécutable (malgré DEP). L'auteur a trouvé un moyen de générer des bytecodes Flash qui, une fois compilés, généreraient une séquence d'octets incorporant son shellcode malveillant (décalé d'un octet). Il a ensuite utilisé des techniques de pulvérisation en tas pour s'assurer qu'il y en avait de nombreuses copies en mémoire. Enfin, il a exploité le bogue de sécurité de la mémoire pour faire sauter le programme vers une autre adresse; en raison de l'ASLR, c'était comme sauter à une adresse aléatoire, mais les nombreuses copies garantissaient qu'avec une forte probabilité, cela passerait dans son shellcode. De cette façon, il a contourné à la fois ASLR et DEP - un exploit astucieux.

Une dernière remarque: il convient de mentionner que l'ASLR est beaucoup plus efficace sur les architectures 64 bits. Sur les architectures 32 bits, ASLR peut souvent être vaincu en faisant simplement plusieurs tentatives. Il n'y a tout simplement pas assez de degrés de liberté sur les plates-formes 32 bits pour introduire suffisamment d'aléatoire, de sorte que les chances de l'attaquant de réussir par une stupide chance restent trop élevées, sur les plates-formes 32 bits. Pour une défense optimale, utilisez une plate-forme 64 bits.

Mon cas: Canaries, ASLR, NX combinés. mode long avec System 5 abi. La vulnérabilité se produit avec un [tableau débordant] (https://web.archive.org/web/*/http://codegolf.stackexchange.com/questions/62457/create-a-buffer-overflow-with-unsigned- long-to-signed-int-trunctation-in-git-2) qui est alloué sur le tas. L'exécution de code à distance est-elle possible?
@user2284570, veuillez ne pas utiliser de commentaires pour poser une nouvelle question. Cela devrait peut-être être posé comme une question distincte (mais assurez-vous de rechercher et de rechercher avant de poser la question, et de montrer votre recherche dans la question - il y a beaucoup d'écrit sur la façon de contourner ASLR, alors assurez-vous de lire les ressources standard avant de demander et d'encadrer votre question en conséquence). La réponse dépendra probablement des spécificités de l'application particulière que vous attaquez.
Ok, donc en général * (pour rester sur le sujet) * cela empêche-t-il l'exécution de code à distance basée sur un débordement de tas?
@user2284570, tout dans ma réponse s'applique aux débordements de tas. Comme le dit ma réponse, ASLR + DEP n'empêche pas toujours absolument * l'exécution de code à distance, mais la rend plus difficile ou parfois impossible.


Ce Q&R a été automatiquement traduit de la langue anglaise.Le contenu original est disponible sur stackexchange, que nous remercions pour la licence cc by-sa 3.0 sous laquelle il est distribué.
Loading...