web-dev-qa-db-fra.com

L'utilisation d'écho pour afficher des données contrôlées par l'attaquant sur le terminal est-elle dangereuse?

Imaginez le code suivant:

ATTACKERDATA="$(cat attackerControlledFile.txt)"
echo "${ATTACKERDATA}"

Un attaquant peut, à travers n'importe quel processus arbitraire, modifier le contenu de attackerControlledFile.txt à tout ce qu'ils désirent. Le contenu peut être ASCII, UTF-8, binaire, etc. Tout va bien. La machine suppose également qu'elle est infiniment rapide, donc même un fichier extrêmement volumineux de plusieurs terrabytes serait lu et imprimé immédiatement.

Est-il possible pour un attaquant, quelle que soit sa probabilité, d'exploiter cela d'une manière ou d'une autre en modifiant le contenu de attackerControlledFile.txt? "Quelque part" fait référence à des choses comme:

  • Ce code ne fonctionne que dans bash
  • Ce code nécessite que la sortie soit imprimée sur un émulateur de terminal spécifique
  • Etc.

Tout le reste suppose un système raisonnablement sain. Cela signifie que les réponses telles que "Si echo est un binaire contrôlé par un attaquant qui est en fait un malware" ne comptent pas, car l'existence d'un malware n'est pas exactement "raisonnablement raisonnable". Les réponses qui nécessiteraient la présence d'un logiciel ou d'une version spécifique de ce logiciel comptent tant que ce logiciel n'a pas été créé à des fins d'exploitation.


Une question similaire demande Est-il possible d'utiliser la commande Linux "echo" avec malveillance? , mais la réponse acceptée concerne en fait une faille dans la conception d'une application web. De plus, cela nécessite que l'attaquant soit capable de faire des redirections, ce que, à ma connaissance, cette construction ne peut pas faire.

47
MechMK1

Est-il possible pour un attaquant, quelle que soit sa probabilité, d'exploiter cela d'une manière ou d'une autre en modifiant le contenu de attackerControlledFile.txt? "Quelque part" fait référence à des choses comme:

Ce code nécessite que la sortie soit imprimée sur un émulateur de terminal spécifique

En fait, oui. Les anciens terminaux comme vt100 ont la possibilité d'utiliser des séquences d'échappement ANSI pour effectuer des tâches spéciales, comme exécuter des commandes. Le site suivant ci-dessous documente cette capacité en utilisant un écho simple, comme vous le décrivez.

https://www.proteansec.com/linux/blast-past-executing-code-terminal-emulators-via-escape-sequences/

L'article est approfondi avec des instructions d'exploitation spécifiques, mais l'idée générale peut être résumée à partir de cet extrait du site:

Séquences d'échappement dangereuses Les émulateurs de terminal prennent en charge plusieurs fonctionnalités, comme décrit ci-dessous [8]:

  • Dump d'écran: une séquence d'échappement de vidage d'écran ouvrira un fichier arbitraire et inscrira le contenu actuel du terminal dans le fichier. Certains émulateurs de terminal n'écriront pas dans des fichiers existants, mais uniquement dans de nouveaux fichiers, tandis que d'autres écraseront simplement le fichier avec le nouveau contenu. Un attaquant pourrait utiliser cette fonctionnalité pour créer un nouveau fichier de porte dérobée PHP dans le DocumentRoot du serveur Web, qui peut ensuite être utilisé pour exécuter des commandes arbitraires.

  • Titre de la fenêtre: une séquence d'échappement existe pour définir le titre de la fenêtre, ce qui modifiera la chaîne de titre de la fenêtre. Cette fonctionnalité peut être utilisée avec une autre séquence d'échappement, qui lit le titre de la fenêtre actuelle et l'imprime sur la ligne de commande actuelle. Puisqu'un caractère de retour chariot est interdit dans le titre de la fenêtre, un attaquant peut stocker la commande dans un titre de fenêtre et l'imprimer sur la ligne de commande actuelle, mais il faudrait tout de même qu'un utilisateur appuie sur Entrée pour l'exécuter. Il existe des techniques pour rendre la commande invisible, comme définir la couleur du texte sur la même couleur que l'arrière-plan, ce qui augmente les changements d'utilisateur en appuyant sur la touche Entrée.

  • Exécution de la commande: certains émulateurs de terminal pourraient même permettre l'exécution de la commande directement en utilisant une séquence d'échappement.

Comme indiqué dans les commentaires, cet exploit particulier a été corrigé il y a des décennies sur les émulateurs de terminaux modernes. Cela s'est avéré justement être un exemple simple qu'une recherche Google de 30 secondes a révélé qui démontre bien le concept qu'il existe encore des logiciels à l'œuvre qui pourraient être exploitables même dans quelque chose d'aussi simple que d'afficher un fichier.

Théoriquement, il pourrait y avoir d'autres problèmes avec les émulateurs de terminaux modernes (débordements de tampon?) Qui pourraient être exploitables.

48
Steve Sether

Si la sortie va vers un terminal, vous avez potentiellement beaucoup de problèmes (quelle que soit la façon dont vous l'imprimez, sauf si vous supprimez les caractères spéciaux), selon les autres réponses.

Si le fichier peut être gigantesque, l'attaquant peut obliger bash à utiliser beaucoup de RAM. Considérez head -c 100000 Au lieu de cat pour définir une limite supérieure de 100 Ko. Ou head -c 10000 | cat -v (Affichez les caractères non imprimables sous la forme ^M Ou autre; cela peut casser les caractères multi-octets UTF-8).

Si vous voulez que les données soient potentiellement géantes, envisagez d'exécuter cette commande directement (pas à l'intérieur d'une capture var=$()), avec la sortie de cat connectée directement à votre sortie standard.


Puisque vous avez les données dans la variable Shell, n'étant pas evaled entre guillemets doubles, vous êtes à l'abri de certaines choses.

par exemple. la substitution de commandes ne fonctionnera pas.

peter@volta:/tmp$ foo='$(touch bar)'
peter@volta:/tmp$ echo "${foo}"
$(touch bar)

Un attaquant peut munger légèrement la sortie en utilisant la chaîne -n, que echo interprétera comme une option au lieu de données littérales.

$ echo "-n"     # notice that this doesn't print a newline.
$ echo ""       # unlike a normal echo "" or echo with no args

$

Mais la fonction intégrée de bash echo ne traite pas "-n foo" Comme une option; c'est imprimé littéralement:

$ echo "-nabcd"
-nabcd

Puisque vous développez la variable Shell entre guillemets doubles, il n'y a aucun moyen qu'elle devienne multiple arguments pour l'écho, comme echo "-n" "leave the cursor at the end of this string"

De même, -e N'est pas possible et n'est pas un danger de toute façon car votre fichier peut déjà contenir des données binaires arbitraires.


/bin/echo From GNU Coreutils prend en charge une option --version, Donc si vous n'utilisez pas d'écho intégré à Shell, un attaquant pourrait demander à votre programme d'imprimer la version logicielle info. Si cette sortie aboutit à quelque chose de visible par un attaquant, elle divulgue des informations sur le système cible.


Pour ces raisons, la recommandation pour portable l'impression de données arbitraires est:

printf "%s\n" "${ATTACKERDATA}"

Fonctionne sur tous les shells POSIX, non soumis aux caprices spécifiques au système de echo.

Mais notez que cela ne fait rien sur les vulnérabilités des terminaux, c'est juste un moyen sûr d'écrire n'importe quelle donnée littéralement sans echo la fusionner.

Et les données binaires traitent toujours \0 (Un octet zéro) comme terminateur dans la plupart des shells, car bash utilise en interne des chaînes C. L'interface OS execve utilise également des chaînes C, mais les commandes internes Shell permettent de contourner cela pour echo/printf, donc est possible par exemple zsh vers les données binaires echo/printf contenant zéro octet.


Et BTW, dans bash, vous n'avez pas vraiment besoin de cat pour lire un fichier. La substitution de commande avec une redirection obtient bash pour faire le se lire.

ATTACKERDATA="$(< attackerControlledFile.txt)"

Mais si vous voulez un traitement, comme head -c Et/ou cat -v, Vous devez utiliser une vraie commande.

11
Peter Cordes

Certains terminaux peuvent faire écho au contenu de l'écran arrière comme s'ils étaient saisis.

Ainsi, vous pouvez éventuellement forcer le "typage" et ainsi l'exécution des commandes avec les bonnes commandes du terminal. Je l'ai fait sur DEC physique VT62-ts. mais je n'ai pas essayé de le faire avec le mode VT-52 de X-term

cet exploit est bien connu, et c'est probablement la raison pour laquelle finger -l username supprime tous les caractères de contrôle (sauf les sauts de ligne et les tabulations) de ~username/.plan etc

alors oui c'est dangereux. pour le rendre sûr, passez-le à travers moins ou col etc.

4
Jasen

Non, l'écho utilisé dans l'exemple ci-dessus est correct

Echo imprime simplement une chaîne dans la sortie standard du tuyau (par défaut)

par: https://superuser.com/a/699500/527937

Les tuyaux ne peuvent pas déborder. Un canal n'est qu'un tampon (une certaine quantité de mémoire, probablement 64 Ko sur un système actuel) entre un producteur et un consommateur. Si le producteur produit plus vite que le consommateur ne consomme, le producteur est bloqué (cela signifie que le programme va dormir) jusqu'à ce que le consommateur fasse à nouveau de la place dans le tampon en lisant.

En remarque, si vous avez une grande quantité de données sur une ligne 1x ... cat peut bloquer et/ou consommer une énorme quantité de mémoire système.

2

L'attaquant pourrait effectuer une attaque par injection de conten , surtout s'il sait à quoi ressemble l'invite du shell.

En incluant quelque chose dans le fichier qui ressemble à une sortie d'une autre partie du système, ils pourraient être en mesure de tromper l'utilisateur et de le faire prendre des mesures.

0
bdsl