O que esse comando criptográfico do Bash significa?

23

Eu estava lendo o aviso do Ubuntu Forum sobre comandos maliciosos e encontrei esta jóia interessante:

:(){ :|:& };:

AVISO: O código acima irá falhar a sua máquina a menos que você tem limites proc estritas no lugar (que você provavelmente não) solicitando um reinício duro.

Considere esse código semelhante à execução sudo rm -rf /.

Mas o que isso significa? Mesmo com minha experiência em programação, nunca vi um comando tão enigmático que não seja linguagem assembly.

TheLQ
fonte
16
Um ponto adicional: isso realmente não é parecido com sudo rm -rf /. Esse comando exclui todos os seus arquivos; este apenas obstrui os recursos da sua máquina até que ela se torne inutilizável e você precise reiniciar.
Jtbandes
@ jtban: Em seguida, edite-o. Ambos os pedaços de código são o que eu consideraria "perigoso" para executar. Sim, sudo rm -rf /é mais perigoso, mas já vi pessoas executando isso em servidores remotos "apenas querendo ver o que ele fez", onde é difícil reiniciar sem acessar o painel de controle.
21710 Josh K
7
É um emotibomb: P
RCIX
Note que poderia ser arbitrary_name(){ arbitrary_name|arbitrary_name& };arbitrary_name. O nome :não apenas torna este comando curto e enigmático, mas também transforma um :builtin que não faz nada em uma função que faz muito . Se você esgueirar sua definição :(){ :|:& }para o ambiente de outra pessoa e deixá-la lá, ela atacará quando a vítima esperar menos .
Kamil Maciorowski

Respostas:

40

É, como você disse, uma bifurcação. O que ele faz é definir uma função e depois chamá-la. A função é chamada :.

Vamos dar um nome forkbombpara que possamos ver melhor o que está acontecendo:

forkbomb(){ forkbomb|forkbomb& };forkbomb

Como você pode ver, e provavelmente adivinhar pela sua experiência em programação, a primeira parte é a definição da função ( forkbomb(){ ... }) e a última :é onde a função é chamada (a ;apenas separa as instruções no Bash).

Agora, o que essa função faz? Se você estiver familiarizado com o Bash, saberá que o |personagem canaliza a saída padrão de um comando / programa para a entrada padrão de outro. Então, basicamente, :|:inicia duas instâncias da função (é aqui que ela "bifurca").

E então a mágica: &colocar esses comandos em segundo plano, permitindo que a função original retorne, enquanto cada instância se bifurca até que as vacas voltem para casa em segundo plano, usando assim todos os seus recursos e derrubando o sistema (a menos que tenha limites imposta a ele).

jtbandes
fonte
1
Ótima resposta! Eu não sabia que você poderia usar: como um nome de função. A renomeação ajuda. Aceitará em 3 minutos.
TheLQ
1
+1 Legal ... Ótima explicação. É como um estouro de pilha para um comutador de tarefas do SO. Ele realmente trava o kernel ou apenas consome recursos até que se torne insuportável de usar?
Evan Plaice
Eu não acho que ele realmente trava o kernel, pelo menos não diretamente. Ele continua criando exponencialmente mais processos, cada um dos quais ocupando CPU e memória, e com o processador tentando lidar com todos eles, torna-se realmente impossível de usar. Pode ser que o kernel acabe travando com a carga (não tenho certeza), mas será inutilizável antes disso.
Jtbandes
3
Não se esqueça de explicar o final :, que realmente executa a função!
Phoshi
@ Phoshi: pensei que sim, mas vou editar para esclarecer!
Jtbandes
9

Retirado do artigo da 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
fonte
7

Quebrado:

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

Mude :para bombe você tem:

bomb(){ bomb|bomb& };bomb

É realmente muito elegante.

Josh K
fonte