¿Qué significa este comando críptico de Bash?

23

Estaba leyendo la advertencia de Ubuntu Forum sobre comandos maliciosos y encontré esta joya interesante:

:(){ :|:& };:

ADVERTENCIA: El código anterior se bloquee la máquina a menos que tenga límites estrictos en lugar proc (que es probable que no) que provocó un reinicio duro.

Considere este código similar a la ejecución sudo rm -rf /.

Pero ¿qué significa eso? Incluso con mi experiencia en programación, nunca he visto un comando tan críptico que no sea lenguaje ensamblador.

TheLQ
fuente
16
Un punto adicional: esto no es realmente de ninguna manera similar a sudo rm -rf /. Ese comando elimina todos sus archivos; este solo obstruye los recursos de su máquina hasta que se vuelve inutilizable y tiene que reiniciar.
jtbandes
@jtban: luego edítelo. Ambas piezas de código son lo que consideraría "peligroso" ejecutar. Sí, sudo rm -rf /es más peligroso, pero he visto a personas ejecutar esto en servidores remotos "solo quería ver lo que hacía" donde tiene dificultades para reiniciar sin acceso a un panel de control.
Josh K
77
es un emotibomb: P
RCIX
Tenga en cuenta que podría ser arbitrary_name(){ arbitrary_name|arbitrary_name& };arbitrary_name. El nombre :no solo hace que este comando sea corto y críptico, sino que también convierte una función :incorporada que no hace nada en una función que hace mucho . Si :(){ :|:& }introduce su definición en el entorno de otra persona y deja que permanezca allí, golpeará cuando la víctima menos lo espere .
Kamil Maciorowski

Respuestas:

40

Es, como dijiste, una bifurcación. Lo que hace es definir una función, luego llamarla. La función se llama :.

Vamos a nombrarlo forkbombpara que podamos ver mejor lo que está sucediendo:

forkbomb(){ forkbomb|forkbomb& };forkbomb

Como puede ver, y probablemente adivine por su experiencia en programación, la primera parte es la definición de la función ( forkbomb(){ ... }), y la última :es donde se llama a la función (la ;simple separa las declaraciones en Bash).

Ahora, ¿qué hace esta función? Si está familiarizado con Bash, sabrá que el |personaje canaliza la salida estándar de un comando / programa a la entrada estándar de otro. Básicamente, :|:inicia dos instancias de la función (aquí es donde se "bifurca").

Y luego la magia: &pone esos comandos en segundo plano, permitiendo que la función original regrese, mientras que cada instancia se bifurca hasta que las vacas lleguen a casa en segundo plano, utilizando todos sus recursos y eliminando el sistema (a menos que tenga límites) impuesto sobre él).

jtbandes
fuente
1
¡Gran respuesta! No me di cuenta de que podría usar: como un nombre de función. El cambio de nombre ayuda. Aceptará en 3 minutos.
TheLQ
1
+1 Genial ... Gran explicación. Esto es como un desbordamiento de pila para un conmutador de tareas del sistema operativo. ¿Realmente bloquea el núcleo o simplemente consume recursos hasta que se vuelve demasiado insoportable para usar?
Evan Plaice
No creo que realmente bloquee el núcleo, al menos no directamente. Simplemente sigue creando exponencialmente más procesos, cada uno de los cuales ocupa CPU y memoria, y con el procesador tratando de manejarlos todos, se vuelve realmente imposible de usar. Puede ser que el kernel finalmente se bloquee bajo la carga (no estoy seguro), pero será inutilizable antes de eso.
jtbandes
3
¡No olvides explicar el final :, que realmente ejecuta la función!
Phoshi
@Phoshi: pensé que sí, ¡pero editaré para aclarar!
jtbandes
9

Tomado del artículo de 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
fuente
7

Desglosado:

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

Cambia :a bomby tienes:

bomb(){ bomb|bomb& };bomb

Es realmente bastante elegante.

Josh K
fuente