Que signifie cette commande cryptique Bash?

23

Je lisais l'avertissement du forum Ubuntu sur les commandes malveillantes et j'ai trouvé ce joyau intéressant:

:(){ :|:& };:

AVERTISSEMENT: Le code ci - dessus va planter votre machine si vous avez des limites strictes de proc en place (que vous ne probablement pas) incitant un disque redémarrage.

Considérez ce code similaire à l'exécution sudo rm -rf /.

Mais qu'est ce que ça veut dire? Même avec mon expérience de programmation, je n'ai jamais vu de commande aussi cryptique que ce n'est pas un langage d'assemblage.

TheLQ
la source
16
Un point supplémentaire: ce n'est vraiment pas du tout similaire à sudo rm -rf /. Cette commande supprime tous vos fichiers; celui-ci obstrue simplement les ressources de votre machine jusqu'à ce qu'elle devienne inutilisable et que vous deviez redémarrer.
jtbandes
@jtban: éditez-le ensuite. Je considère que les deux morceaux de code sont «dangereux» à exécuter. Oui, sudo rm -rf /c'est plus dangereux, mais j'ai vu des gens exécuter cela sur des serveurs distants "je voulais juste voir ce qu'il faisait" où vous avez du mal à redémarrer sans avoir accès à un panneau de contrôle.
Josh K
7
c'est une émotibombe: P
RCIX
Notez que cela pourrait l'être arbitrary_name(){ arbitrary_name|arbitrary_name& };arbitrary_name. Le nom :rend non seulement cette commande courte et cryptique, mais transforme également une fonction :intégrée qui ne fait rien en une fonction qui en fait beaucoup . Si vous glissez sa définition :(){ :|:& }dans l'environnement de quelqu'un d'autre et la laissez y rester, elle frappera lorsque la victime l'attendra le moins .
Kamil Maciorowski

Réponses:

40

C'est, comme vous l'avez dit, une fourchette. Ce qu'il fait, c'est définir une fonction, puis l'appeler. La fonction est appelée :.

Appelons-le forkbombpour mieux voir ce qui se passe:

forkbomb(){ forkbomb|forkbomb& };forkbomb

Comme vous pouvez le voir et probablement deviner à partir de votre expérience de programmation, la première partie est la définition de la fonction ( forkbomb(){ ... }), et la toute dernière :est l'endroit où la fonction est appelée (les ;instructions juste séparent dans Bash).

Maintenant, que fait cette fonction? Si vous connaissez Bash, vous saurez que le |personnage dirige la sortie standard d'une commande / d'un programme vers l'entrée standard d'une autre. Donc, fondamentalement, :|:démarre deux instances de la fonction (c'est là qu'elle "bifurque").

Et puis la magie: le &met ces commandes en arrière-plan, permettant à la fonction d'origine de revenir, tandis que chaque instance bifurque jusqu'à ce que les vaches rentrent à la maison en arrière-plan, utilisant ainsi toutes vos ressources et supprimant le système (sauf s'il a des limites imposée).

jtbandes
la source
1
Très bonne réponse! Je ne savais pas que vous pouviez utiliser: comme nom de fonction. Le renommage aide. Acceptera dans 3 minutes.
TheLQ
1
+1 Cool ... Grande explication. Cela ressemble à un débordement de pile pour le sélecteur de tâches du système d'exploitation. Fait-il vraiment planter le noyau ou consomme-t-il simplement des ressources jusqu'à ce qu'il devienne trop insupportable pour être utilisé?
Evan Plaice
Je ne pense pas que cela bloque réellement le noyau, du moins pas directement. Il continue de créer de manière exponentielle plus de processus, chacun occupant du CPU et de la mémoire, et avec le processeur essayant de les gérer tous, il devient vraiment impossible à utiliser. Il se peut que le noyau se bloque finalement sous la charge (je ne suis pas sûr), mais il sera inutilisable avant cela.
jtbandes
3
N'oubliez pas d'expliquer la finale :, qui exécute en fait la fonction!
Phoshi
@Phoshi: pensé que je l'ai fait, mais je vais modifier pour clarifier!
jtbandes
9

Tiré de l'article Wikipedia Forkbomb :

:()      # define ':' -- whenever we say ':', do this:
{        # beginning of what to do when we say ':'
    :    # load another copy of the ':' function into memory...
    |    # ...and pipe its output to...
    :    # ...another copy of ':' function, which has to be loaded into memory
         # (therefore, ':|:' simply gets two copies of ':' loaded whenever ':' is called)
    &    # disown the functions -- if the first ':' is killed,
         #     all of the functions that it has started should NOT be auto-killed
}        # end of what to do when we say ':'
;        # Having defined ':', we should now...
:        # ...call ':', initiating a chain-reaction: each ':' will start two more.
James T
la source
7

En panne:

: () // Define ':' as a function. When you type ':' do the following
{
    : // Call ':' 
    | // Redirect output
    : // Into ':'
    & // Push process to the background
}; // End of ':' def
: // Now do ':'

Changez :pour bombet vous avez:

bomb(){ bomb|bomb& };bomb

C'est vraiment assez élégant.

Josh K
la source