Question:
Comment expliquer le débordement de tampon à un profane
KnightOfNi
2014-03-22 04:57:24 UTC
view on stackexchange narkive permalink

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 avec un non-sens et écrase le pointeur pour pointer vers ce que je veux qu'il pointe "). A cette époque, la plupart des gens sont devenus suicidaires ... Quelle est la bonne manière d'expliquer un débordement de tampon aux profanes? Si possible, veuillez inclure un composant "débordement", mais aussi au moins une introduction expliquant pourquoi cela signifie que l'attaquant peut obtenir ce qu'il veut. Rappelez-vous, les personnes d'intelligence moyenne (et inférieure à la moyenne) devraient pouvoir avoir une idée de ce dont je parle, alors que vous devriez absolument vous sentir libre (encouragé, en fait) d'expliquer ce que représente chaque partie de votre métaphore (analogie?) , ne vous fiez pas à des descriptions super-techniques ...

PS, une question connexe expliquant en termes techniques ce que fait le buffer overflow: Qu'est-ce qu'un buffer overflow?

10 livres de sucre dans un sac de 5 livres.
@Elsporko Voir ma discussion avec tylerl, je cherche quelque chose qui donne au moins une idée de pourquoi diable le composant de débordement permet à l'attaquant d'obtenir ce qu'il veut. Comme je n'ai pas précisé cela, plusieurs personnes ont fourni des exemples similaires, je vais donc modifier ma question en conséquence. Merci pour votre contribution!
Sept réponses:
user253751
2014-03-22 07:00:25 UTC
view on stackexchange narkive permalink

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

Name | Amount owing

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

Vous payez à quelqu'un un dépôt de 500 $ sur une voiture de 5000 $, alors vous lui devez 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 vous les effacez du tableau, donc maintenant votre tableau 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 Smithxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx9999999999) dans votre tableau. Votre tableau ressemble maintenant à ceci:

John Smithxxxxxxxxxxxxxxxxxxxxxxx|x99999999990

(le dernier 0 de 1000 n'a pas été écrasé. Cela n'a pas d'importance.)

Lors de l'écriture nom, vous ne vous êtes pas arrêté lorsque vous êtes arrivé à la fin de la colonne «nom», et avez continué à é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.

Une excellente réponse; Je peux l'utiliser la prochaine fois que je dois présenter à des non-techniciens.
C'est toujours agréable de voir une bonne analogie utilisée pour transporter un concept technique dans un contexte simple.
Le seul problème que j'ai avec cette explication est que la plupart des gens écrivent de gauche à droite; c'est-à-dire que la colonne «Montant dû» serait écrite _après_ la colonne «Nom», donc devrait afficher le montant attendu («1000 $»). Vous feriez probablement mieux d'écrire l'entrée pour `Nom` dans la ligne suivante, de sorte que le montant de la ligne actuelle puisse être écrit en toute sécurité (notez que vous n'auriez même pas besoin d'énormes quantités ici - la personne pourrait simplement être dans le table deux fois).
Désolé si c'est une question stupide, mais quelle est la signification du liquide correcteur?
@KnightOfNi: Vous pouvez écrire sur les 0 avec des 9 et obtenir des 9, au lieu d'un hybride de 0 et 9.
Je vois. Personnellement, je préférerais l'expliquer comme suit: «vous écrivez toujours le montant que vous devez en premier (ce serait la valeur préexistante) et ne lisez que le nombre le plus récemment écrit dans l'espace». C'est peut-être juste comment mon esprit fonctionne, mais cela me semble un peu plus clair que le fluide correcteur magique (peut-être parce que le reste de l'analogie est si réaliste ...)
Si vous écrivez les deux dans le même espace, vous obtiendrez quelque chose comme ceci: http://puu.sh/7KTwk.png. Comment sauriez-vous s'il faut lire des 9 ou des 0?
"Vous ne lisez que le numéro le plus récemment écrit dans l'espace." J'écris fréquemment sur des choses que j'avais précédemment écrites sans prendre la peine de les effacer, et je suis toujours capable de voir clairement quelle chose j'ai écrite en dernier (généralement, je passe plusieurs fois en revue les nouvelles lettres pour en faire le choix évident). C'est non seulement plus réaliste dans la vie réelle, mais c'est aussi plus proche de ce que fait réellement un ordinateur (il n'efface pas les données, il écrit juste dessus).
«Vous avez un stylo étrange avec un liquide correcteur intégré» me gâche en quelque sorte l'analogie - je sais ce que vous dites, mais comme il n'existe pas dans la vraie vie, cela semblerait étrange à quelqu'un que je pense.
@SilverlightFox, vous pouvez couper quelques 9, donc vous vous retrouvez avec 999 $ ... 9991000 et pas de chiffres qui se chevauchent.
Je pense qu'@immibis dit simplement que si vous écrasez quelque chose avec une écriture normale, lorsque vous allez le lire, vous pouvez généralement dire qu'une nouvelle écriture a corrompu une écriture antérieure.Lorsque vous écrasez quelque chose dans la mémoire de l'ordinateur, il n'y a généralement pas de telles preuves.
tylerl
2014-03-22 09:35:01 UTC
view on stackexchange narkive permalink

L'idée d'utiliser plus d'espace que vous n'en avez reçu, et donc de déborder dans un champ différent, est assez simple à visualiser. Mais il n'est probablement pas clair comment cela peut conduire un méchant à exécuter son propre code.

Ceci est assez simple à expliquer si vous le comprenez assez bien. Assurez-vous simplement de toucher le contexte 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 pour travailler, et quand c'est fait, elle ramène le pointeur là où elle l'a trouvé.

  • La pile s'agrandit. en arrière. Donc, pour vous donner 100 octets sur la pile, vous soustrayez 100 du pointeur de pile plutôt que de l'ajouter. Si la pile de la fonction précédente commençait à 1000 et je veux 100 octets, alors ma pile commence à 900.

  • Cela signifie que si vous utilisez plus d'espace que vous ne vous en avez donné, vous avez gagné ne continuez pas à écrire dans un espace vide, vous allez en fait commencer à écraser les valeurs précédentes de la pile.

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

  • Cela signifie que si mon la fonction écrase sa pile, la toute première chose qu’elle va écraser est l’adresse de retour. Si l'attaquant fait attention à ce avec quoi il remplit la pile, il peut spécifier l'adresse de retour qu'il veut.

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

Exemple simple

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

  Pointeur de pile Préc. Stack Ptr + ---------------------------------- + ------------- - + ................ | Votre nom ici | Retour Addr | Ancienne pile ... + ---------------------------------- + --------- ----- + ................  

Mais le méchant rend son nom assez long pour déborder d'espace. Et non seulement cela, au lieu de taper un vrai nom, il tape du mauvais code, du remplissage et l'adresse de ce mauvais code.

  + --------- ------------------------- + -------------- + ......... ....... | [Code maléfique] xxxxxxxxxxxxxxxxxxxxxx Adresse maléfique | Ancienne pile ... + ---------------------------------- + --------- ----- + ................ ▲ ──────────────────────────── ───────┘  

Maintenant, au lieu de revenir à l'appelant précédent, vous passez directement au [Evil Code] . Maintenant, vous exécutez son code au lieu de votre programme. À partir de là, la partie est pratiquement terminée.

Atténuation et autres techniques

Deux des techniques utilisées pour réduire l'efficacité du smashing de pile sont le DEP et l'ASLR.

DEP ("Data Execution Prevention") fonctionne en marquant la pile comme non exécutable. Cela signifie que le [Evil Code] sur la pile ne fonctionnera pas, car l'exécution de code sur la pile n'est plus autorisée. Pour contourner cela, 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 à tour de rôle. Ils appellent cela "Programmation orientée retour", 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, créer une chaîne ROP n'est pas si facile - chaque fois que le programme s'exécute, toutes les adresses se trouvent à des endroits différents. Ainsi, lorsque l'attaquant écrase l'adresse de retour avec sa propre adresse malveillante, il ne saura pas quels numéros utiliser car le code est toujours à des endroits différents.

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

+1 pour être très clair et informatif, mais j'espérais une métaphore de 45 secondes que je pourrais utiliser pour l'expliquer à quelqu'un qui ne veut pas vraiment connaître tous les détails techniques.
Les analogies pour de simples débordements de tampon sont assez faciles, mais c'est un concept intuitif qui nécessite rarement beaucoup d'explications. L'exécution de code arbitraire en raison d'un débordement de pile est une autre affaire. Il n'y a vraiment pas de parallèle réel car cela dépend de l'interaction des règles et des conventions qui sont propres à ce sujet. Les gens comprennent assez facilement que vous pouvez déborder d'un champ dans un autre, mais cela laisse généralement la question, "pourquoi diable cela signifie-t-il que l'attaquant peut maintenant faire ce qu'il veut?"
Eric G
2014-03-22 20:48:28 UTC
view on stackexchange narkive permalink

Les autres réponses sont encore assez techniques, donc je vous 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 trou peut contenir une chaussure. Donc, pour chaque élève, vous fournissez deux compartiments.

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

Lorsque le professeur appelle Bad Billy Bad Billy veut jouer avec Stupid Sally . Les trous de Billy sont les nombres 5 et 6 et Sally's sont les nombres 7 et 8 . Billy met ses émissions dans 5 et 6 puis dépasse sa limite définie et met un crapaud gluant dans le cubby de Sally numéro 7 .

Parce que l'enseignant n'applique aucune protection sur la limite définie pour l'utilisation des cagettes dans l'ordre adjacent, Billy est capable de dépasser sa limite et de jouer avec Sally's stockage. Maintenant, lorsque Sally ira chercher sa chaussure, elle recevra un crapaud gluant à la place yuck !


  + ---- --------------- + -------------------- + ------------- ------ + -------------------- + | CUBBY 5 | CUBBY 6 | CUBBY 7 | CUBBY 8 | + ------------------- + -------------------- + ----- -------------- + -------------------- + | | | | || Chaussure gauche de Billy | Chaussure droite de Billy | Chaussure gauche de Sally | Chaussure droite de Sally | + ------------------- + -------------------- + ---- --------------- + -------------------- +  

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

  + ------------------- + -------------------- + - ---------- + -------------------- + | CUBBY 5 | CUBBY 6 | CUBBY 7 | CUBBY 8 | + ------------------- + -------------------- + ----- ------- + -------------------- + | | | | || Chaussure gauche de Billy | Chaussure droite de Billy | Slimy Toad | Chaussure droite de Sally | + ------------------- + -------------------- + ---- -------- + -------------------- +  

Un buffer overflow aurait pu être évité si le L'enseignant accordait plus d'attention et veillait à ce que chaque élève n'utilise que l'espace de stockage prévu.

Bien que cela ait un excellent composant de «débordement», il ne montre pas vraiment comment un dépassement de tampon peut être utilisé pour exécuter un script (voir les exemples de livre de recettes et de tableau des prix, qui permettent à l'attaquant d'obtenir quelque chose).
Si la fonction est SallyPutsOnShoe (), alors quand Sally va chercher sa chaussure, elle obtient un crapaud à la place. Billy peut rire. Le but de Billy est simplement de changer le résultat. Ne considérez-vous pas cela comme un déni de service contre Sally qui met ses chaussures pour qu'elle puisse sortir et jouer? Il est prévu que la grenouille remplace la chaussure et ne met pas simplement le crapaud dans la chaussure.
Oui, mais le but d'un débordement de tampon n'est pas seulement de faire en sorte que le programme vulnérable ne fonctionne pas, c'est de faire fonctionner le programme pour vous. Billy cause un peu de chaos, mais ce serait l'équivalent de moi écrasant une pile puis écrasant l'EIP avec "xxxxxx". Ça ne fait vraiment rien pour moi.
Je crois que la question posait simplement un dépassement de tampon, pas un débordement de pile. Vous pouvez insérer une instruction arbitraire comme une attaque ou vous pouvez insérer de nouvelles données. Imaginez que vous ayez des espaces adjacents en mémoire pour le montant d'argent qui vous est dû par la Banque, si vous dépassez la première allocation de mémoire et que vous pouvez écrire dans la seconde pour laquelle vous n'avez pas la permission, maintenant la Banque vous doit plus d'argent . Vous avez modifié illégalement l'entrée en une fonction légitime à votre avantage, pourquoi introduire un nouveau code pour vous donner plus d'argent si vous pouvez simplement changer l'entrée illégalement?
Assez juste, +1 pour être original!
Wedge
2014-03-24 19:37:58 UTC
view on stackexchange narkive permalink

Je vais essayer ceci sans utiliser d'analogies.

Un ordinateur est fondamentalement 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 de quelqu'un qui peut être très courte (a@b.com) ou très longue (prénom.nom- milieu.nom@mycustomdomainname.co.uk). 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 continuerait 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 pourrait lui donner une adresse e-mail très soigneusement conçue qui était très long et comportait des caractères spéciaux à la fin. L'idée étant que lorsque le programme stockait l'adresse e-mail en mémoire, il écrirait 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 n'importe quoi programme ces caractères spéciaux traduits en, en code informatique. De cette façon, il serait possible pour quelqu'un de faire exécuter à l'ordinateur tout ce qu'il veut, simplement en élaborant soigneusement les données qu'il a fournies au programme.

Bien que ce soit une réponse assez précise et très concise, je recherche en fait une analogie ...
Anti-weakpasswords
2014-03-22 07:07:52 UTC
view on stackexchange narkive permalink

Bonne question. Voici une analogie qui n'est pas la plus précise techniquement, mais qui 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 processeur).

  • 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 juste toutes les instructions sur la page sur laquelle ils se trouvent
  • Le cuisinier commence au début (bootloader) et continue jusqu'à ce que l'instruction soit "close book"
    • Même si l'instruction est de passer à une autre page ( Rendez-vous à la page 394)

Donc, normalement, vous écririez sur la première page "Rendez-vous à la page 200 (gaufres)", ouvrez le classeur, et mettez les gaufres à la page 200. Ensuite, faites démarrer le cuisinier - le cuisinier devrait faire des gaufres!

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

Le cuisinier n'a jamais été invité à faire uniquement ce qui est imprimé sur la feuille d'origine (dans l'espace tampon normal) - le cuisinier fera aussi n'importe quoi après cela (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 là, inutilisé, jusqu'à ce qu'il pourrisse et moisisse (éteint 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 grimper dans le fenêtre.

Alors, quel est le cuisinier?
Le CPU, exécutant aveuglément des instructions; J'ai légèrement mis à jour la réponse pour la rendre plus claire.
En regardant à nouveau cela, cela ressemble un peu plus à une injection SQL qu'à un débordement de tampon. Pouvez-vous ajouter un composant "débordant"? Merci.
Oh! Ou dites-vous qu'en ajoutant de nouvelles pages, l'attaquant peut mettre SES instructions à la page 200? Un peu de tampon faible, mais cela aurait beaucoup de sens.
Un attaquant peut mettre ses propres données en "mémoire" (le livre) où bon lui semble. En outre, si vous considérez que le «tampon» est «la ligne de texte à l'intérieur des marges», le «débordement» est «l'écriture dans les marges». L'injection SQL n'est pas vraiment si différente à ce niveau élevé (la vue à 60000 pieds) - l'attaquant met des choses là où elles ne devraient pas être exécutées, et elles sont quand même exécutées.
Pourquoi le vote négatif?
David
2014-03-25 00:36:14 UTC
view on stackexchange narkive permalink

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

J'ai réfléchi à cela, mais comme @tylerl l'a mentionné, il n'y a pas un excellent moyen d'expliquer comment cela conduit l'attaquant à pouvoir faire / obtenir ce qu'il veut. Pensées?
Warbo
2014-03-24 19:53:48 UTC
view on stackexchange narkive permalink

Comment ça se passe?

Les données d'un ordinateur sont stockées sous forme d'une longue liste de numéros, 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ù chacune commence.

Les listes de pistes se trouvent facile pour la musique, puisque chaque chanson a une longueur connue. Avec un ordinateur, la quantité de données que nous devons stocker peut ne pas être encore connue, par exemple si elles proviennent d'Internet. Si la piste que nous utilisons se remplit, nous devons passer à une autre, 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 «bande sur» la piste suivante. Lorsqu'un programme essaie de lire cette 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 pourraient avoir été un ensemble d'instructions à transporter en dehors. Si tel est le cas, l'ordinateur exécutera désormais les instructions téléchargées directement depuis Internet!

J'aime bien à quel point votre métaphore se marie bien avec la vie réelle, mais c'est un peu déroutant ... serait-il plus juste de dire que la RAM dans son ensemble est un (vraiment gros) album, et chaque pile est une bande? Si oui, pourriez-vous modifier votre réponse pour refléter cela?
Je ne pense pas qu'il soit nécessaire de mentionner explicitement les piles, même si elles sont couramment exploitées via des débordements de tampon. Les débordements de tampon sont eux-mêmes un bogue plus général. C'est comme essayer d'expliquer "injection SQL", qui nécessite d'expliquer les bases de données, au lieu de "injection de code", qui est plus générale.


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