web-dev-qa-db-fra.com

Comment expliquer le débordement de tampon à un profane

De temps en temps (quand je pense à voix haute et que les gens m'entendent), je suis obligé d'expliquer ce qu'est un débordement de tampon. Parce que je ne peux pas vraiment penser à une bonne métaphore, je finis par passer environ 10 minutes à expliquer le fonctionnement des programmes (vulnérables) et l'allocation de mémoire, puis j'ai environ 2 phrases sur l'exploit réel ("donc un débordement de tampon remplit le tampon vers le haut avec un non-sens et écrase le pointeur pour pointer vers tout ce que je veux qu'il pointe "). A cette époque, la plupart des gens sont devenus suicidaires ... Quelle est la bonne façon d'expliquer un débordement de tampon aux profanes? Si possible, veuillez inclure un composant de "débordement", mais aussi au moins une explication de la raison pour laquelle cela signifie que l'attaquant peut obtenir ce qu'il veut. N'oubliez pas que les personnes d'intelligence moyenne (et inférieure à la moyenne) devraient être capables de se faire une idée de ce dont je parle, alors vous devriez absolument vous sentir libre (encouragé, en fait) d'expliquer ce que chaque partie de votre métaphore (analogie?) Représente , ne vous fiez pas à des descriptions super-techniques ...

PS, une question connexe expliquant en termes techniques ce que fait le débordement de tampon: Qu'est-ce qu'un débordement de tampon?

52
KnightOfNi

Imaginez que vous ayez une liste de personnes à qui vous devez de l'argent.

Name | Amount owing

De plus, vous avez un stylo bizarre avec un fluide de correction intégré, de sorte que si vous écrivez quelque chose à un endroit particulier, puis écrivez autre chose, il efface la première chose que vous avez écrite. C'est ainsi que la mémoire de l'ordinateur fonctionne, ce qui est un peu différent de la façon dont l'écriture fonctionne normalement.

Vous versez à quelqu'un un dépôt de 500 $ sur une voiture de 5000 $, vous lui devez donc maintenant 4500 $. Ils vous disent que leur nom est John Smith. Vous écrivez le montant (4500) et le nom (John Smith) dans le tableau. Votre table ressemble maintenant à ceci:

John Smith | 4500

Plus tard, votre table vous rappelle de les rembourser. Vous payez les 4500 $ (plus les intérêts) et les effacez de la table, donc votre table est à nouveau vide.

Ensuite, vous obtenez un prêt de 1000 $ de quelqu'un d'autre. Ils vous disent que leur nom est "John Smithxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx9999999999". Vous écrivez le montant (1000) et le nom (John Smithxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx9999999999) dans votre table. Votre table ressemble maintenant à ceci:

John Smithxxxxxxxxxxxxxxxxxxxxxxx|x99999999990

(le dernier 0 de 1000 n'a pas été écrasé. Ce n'est pas important.)

Lorsque vous écrivez le nom, vous ne vous arrêtez pas à la fin de la colonne "nom", et continuez d'écrire dans la colonne "montant dû"! Il s'agit d'un débordement de tampon.

Plus tard, votre tableau vous rappelle que vous devez 99999999990 $ à John Smithxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx. Vous le retrouvez et lui payez près de 100 milliards de dollars.

110
user253751

L'idée d'utiliser plus d'espace qu'on ne vous en a donné, et donc de déborder dans un domaine différent est assez simple à visualiser. Mais on ne sait probablement pas comment cela peut conduire un méchant à exécuter son propre code.

C'est assez simple à expliquer si vous le comprenez assez bien. Assurez-vous de toucher le fond important. Plus ou moins dans cet ordre:

  • La "pile" est un endroit où vous pouvez stocker des informations temporaires. Le "pointeur de pile" détermine où se trouve la fin de la pile. Lorsqu'une fonction s'exécute, elle déplace le pointeur de pile pour se donner de la mémoire avec laquelle travailler, et lorsqu'elle est terminée, elle ramène le pointeur là où elle l'a trouvée.

  • La pile croît vers l'arrière. Donc, pour vous donner 100 octets sur la pile, vous soustrayez 100 du pointeur de la pile plutôt que de l'ajouter. Si la pile de la fonction précédente a commencé à 1000 et que je veux 100 octets, ma pile commence à 900.

  • Cela signifie que si vous utilisez plus d'espace que vous ne vous en êtes donné, vous ne poursuivrez pas simplement l'écriture dans un espace vide, vous commencerez en fait l'écrasement précédent valeurs de pile.

  • Lorsque ma fonction démarre, la valeur la plus élevée laissée sur la pile pour moi par la fonction précédente est l'adresse de retour où je dois aller lorsque ma fonction est terminée .

  • Cela signifie que si ma fonction dépasse sa pile, la toute première chose qu'elle va écraser est l'adresse de retour. Si l'attaquant fait attention à ce qu'il remplit la pile, il peut spécifier l'adresse de retour qu'il souhaite.

  • Lorsque ma fonction existe, quel que soit le code à cette adresse de retour, c'est ce qui sera exécuté ensuite.

Exemple simple

Dans Smashing the Stack for Fun and Profit , où cette technique a été décrite à l'origine, la technique la plus simple et directe a été introduite. Imaginez que la fonction lit votre nom puis revient. Votre pile ressemble donc à ceci:

Stack Pointer                                      Prev. Stack Ptr
+----------------------------------+--------------+................
| Your Name Here                   | Return Addr  |  Old stack ...
+----------------------------------+--------------+................

Mais le méchant fait son nom assez longtemps pour déborder l'espace. Et non seulement cela, au lieu de taper un vrai nom, il tape du code maléfique, du rembourrage et l'adresse de ce code maléfique.

+----------------------------------+--------------+................
| [ Evil Code ]xxxxxxxxxxxxxxxxxxxxxxEvil Address |  Old stack ...
+----------------------------------+--------------+................
  ▲──────────────────────────────────┘

Maintenant, au lieu de revenir à l'appelant précédent, vous passez directement au [Evil Code]. Vous exécutez maintenant son code au lieu de votre programme. De là, c'est à peu près game-over.

Atténuation et autres techniques

DEP et ASLR sont deux des techniques utilisées pour réduire l'efficacité de l'écrasement de pile.

DEP ("Data Execution Prevention") fonctionne en marquant la pile comme non exécutable. Cela signifie que le [Evil Code] sur la pile ne s'exécutera pas, car l'exécution de code sur la pile n'est plus autorisée. Pour contourner ce problème, l'attaquant trouve des morceaux de code existant qui feront des morceaux de ce qu'il veut. Et au lieu de simplement écraser sa propre adresse de retour, il crée une chaîne d'adresses de retour dans la pile pour toutes les fonctions qu'il souhaite exécuter à son tour. Ils appellent cela "Return Oriented Programming", ou ROP. La chaîne de retours est appelée "chaîne ROP". C'est vraiment difficile à faire. Mais il existe des outils pour vous aider.

ASLR ("Address Space Layout Randomization") fonctionne en randomisant les emplacements de toutes les fonctions intéressantes. Maintenant, la création d'une chaîne ROP n'est pas si facile - chaque fois que le programme s'exécute, toutes les adresses sont à des endroits différents. Ainsi, lorsque l'attaquant va écraser l'adresse de retour avec sa propre adresse maléfique, il ne saura pas quels numéros utiliser, car le code est toujours à des endroits différents.

Ni le DEP ni l'ASLR à eux seuls n'offrent beaucoup de protection, mais les deux ensemble rendent une exploitation réussie très difficile. Bien que certaines contournements existent parfois, il n'y a pas de solution de contournement qui fonctionne partout . Si vous pouvez contourner DEP + ASLR, c'est une sorte de succès unique.

16
tylerl

Les autres réponses sont encore assez techniques, donc je propose ceci.

Imaginons que vous ayez une classe de maternelle. Il y a des compartiments pour que chaque élève puisse mettre ses chaussures. Chaque compartiment contient une chaussure. Donc, pour chaque élève, vous fournissez deux compartiments.

Chaque élève se voit attribuer deux trous adjacents. L'enseignant appelle ensuite les élèves au hasard pour mettre leurs chaussures dans les compartiments auxquels ils sont affectés.

Quand l'enseignant appelle Bad Billy Bad Billy veut jouer avec Stupid Sally . Les trous de cuby de Billy sont des nombres 5 et 6 et Sally sont des nombres 7 et 8. Billy place ses émissions dans 5 et 6 puis déborde sa limite définie et place un crapaud gluant dans le nombre de cubby de Sally 7.

Étant donné que l'enseignant n'applique aucune protection à la limite définie pour l'utilisation de compartiments dans l'ordre adjacent, Billy est capable de déborder sa limite et de jouer avec Stockage de Sally. Maintenant, quand Sally va chercher sa chaussure, elle recevra un crapaud gluant à la place beurk!


+-------------------+--------------------+-------------------+--------------------+
|      CUBBY 5      |       CUBBY 6      |      CUBBY 7      |       CUBBY 8      |
+-------------------+--------------------+-------------------+--------------------+
|                   |                    |                   |                    |
| Billy's Left Shoe | Billy's Right Shoe | Sally's Left Shoe | Sally's Right Shoe |
+-------------------+--------------------+-------------------+--------------------+

Billy saisit trois éléments où il est défini, il ne devrait en mettre que 2, c'est ainsi qu'un débordement de pile fonctionne à un niveau élevé, quelqu'un joue avec le stockage pour lesquels ils ne sont pas autorisés, puis lorsque ce stockage est lu, ce n'est pas ce que vous attendiez.

+-------------------+--------------------+------------+--------------------+
|      CUBBY 5      |       CUBBY 6      |   CUBBY 7  |       CUBBY 8      |
+-------------------+--------------------+------------+--------------------+
|                   |                    |            |                    |
| Billy's Left Shoe | Billy's Right Shoe | Slimy Toad | Sally's Right Shoe |
+-------------------+--------------------+------------+--------------------+

Un débordement de tampon aurait pu être évité si l'enseignant accordait plus d'attention et s'assurait que chaque étudiant n'utilisait que la quantité de stockage attendue.

3
Eric G

Je vais essayer cela sans utiliser d'analogies.

Un ordinateur est essentiellement toute la mémoire, c'est la partie importante, le contenu de la mémoire sont des instructions, qui indiquent à l'ordinateur quoi faire, et des données, que les instructions utilisent et peuvent utiliser ou modifier. Il est souvent nécessaire de stocker des données de longueur variable. Par exemple, si un programme doit garder une trace de l'adresse e-mail d'une personne qui peut être très courte ([email protected]) ou très longue (pré[email protected]). Certains programmes ne suivent pas très bien la longueur maximale de leurs enregistrements de données. Donc, si un programme a été conçu avec un maximum de, disons, 100 caractères pour une adresse e-mail et que quelqu'un lui a donné une adresse e-mail avec plus de 100 caractères, le programme continuera simplement à écrire le reste de l'adresse en mémoire après la fin de sa pré -espace alloué. La partie importante à retenir est que la mémoire est tout, le programme lui-même est en mémoire juste à côté des enregistrements de données.

Quelqu'un qui savait exactement comment ce programme fonctionnait pouvait lui donner une adresse e-mail très soigneusement conçue qui était très longue et avait des caractères spéciaux à la fin. L'idée étant que lorsque le programme stockait l'adresse e-mail en mémoire, il écrivait aveuglément ces caractères spéciaux dans une partie de la mémoire où le programme pensait que d'autres parties de lui-même se trouvaient, puis quand il allait exécuter ces parties, il exécuterait à la place ce que programmer ces caractères spéciaux traduits en code informatique. De cette façon, il serait possible pour quelqu'un d'obtenir que l'ordinateur exécute tout ce qu'il voulait, simplement en créant soigneusement les données qu'il a données au programme.

3
Wedge

Je l'explique toujours comme un éclatement de seau. Le seau est là pour protéger le contenu de l'extérieur et vice versa, mais vous utilisez le contenu pour vous rendre à l'extérieur du seau, et donc accéder à des zones du système auxquelles vous ne devriez pas avoir accès autrement.

1
David

Bonne question. Voici une analogie qui n'est pas la plus précise techniquement, mais elle devrait faire passer l'idée.

Imaginez un livre de recettes sur du papier perforé à 3 trous dans un classeur (mémoire) et un cuisinier très stupide (le processeur, c'est-à-dire le CPU).

  • Les gens peuvent ajouter ou supprimer des pages du classeur (charger ou décharger des programmes et des données en mémoire)
  • Le cuisinier suit simplement toutes les instructions sur la page sur laquelle il se trouve
  • Le cuisinier commence au début (bootloader) et continue jusqu'à ce que l'instruction soit "fermer le livre"
    • Même si l'instruction consiste à passer à une autre page (Passez à la page 394)

Donc, normalement, vous écririez à la page un "Tournez à la page 200 (gaufres)", ouvrez le classeur et placez des gaufres à la page 200. Ensuite, faites cuire le cuisinier - le cuisinier devrait faire des gaufres!

Mais attendez ... il y a un attaquant! Ils ont écrit des notes en marge de votre recette de gaufre (en dehors du tampon) - et le cuisinier exécute ces instructions même si elles sont évidemment manuscrites.

On n'a jamais dit au cuisinier de ne faire que ce qui était imprimé sur la feuille d'origine (dans l'espace tampon normal) - le cuisinier ferait également n'importe quoi après (en mémoire après le tampon).

Peut-être que le cuisinier ajoute du vinaigre aux gaufres (corrompt vos fichiers). Peut-être que le cuisinier passe à la page trois cent quatre-vingt-quatorze et laisse simplement l'œuf cru assis, inutilisé, jusqu'à ce qu'il pourrisse et moule (désactive votre antivirus). Peut-être que le cuisinier jette tout dans la cuisine (supprime tous vos fichiers), ou met un verrou sur la porte de votre cuisine pour vous empêcher d'entrer (ransomware), ou ouvre la fenêtre (installe un cheval de Troie/porte dérobée) pour que l'attaquant puisse monter dans le fenêtre.

1
Anti-weakpasswords

Comment c'est?

Les données d'un ordinateur sont stockées sous la forme d'une longue liste de nombres, comme les pistes d'une cassette musicale. Contrairement à la musique, qui est jouée du début à la fin, les ordinateurs doivent passer d'une piste à l'autre, ils ont donc besoin d'une `` liste de pistes '' pour leur dire où commence chacun.

Les listes de pistes sont faciles pour la musique, car chaque chanson a une longueur connue. Avec un ordinateur, la quantité de données que nous devons stocker n'est peut-être pas encore connue, par exemple si elles proviennent d'Internet. Si la piste que nous utilisons se remplit, nous devons passer à une autre piste inutilisée. Si nous ne le faisons pas, par exemple, si nous supposons à tort que nous ne recevrons jamais plus d'une certaine quantité de données, nous pourrions utiliser trop de bande et "passer par-dessus" la piste suivante. Lorsqu'un programme essaie de lire la piste suivante, il récupère une partie de nos données au lieu de ce qui s'y trouvait auparavant.

Cela peut être dangereux, car les données écrasées peuvent avoir été un ensemble d'instructions à exécuter. Si tel est le cas, l'ordinateur exécutera désormais les instructions téléchargées directement depuis Internet!

0
Warbo