14 abril 2009

Bombas fork, ¿Qué son?

Una bomba fork es sencillamente un tipo de ataque que afecta a cualquier sistema operativo (windows, *nix, etc) que usa la función fork o sus equivalentes para desatar un ataque de tipo bucle recursivo infinito (sí, suena marciano) sobre el sistema, haciendolo colapsar debido a la saturación de la memoria y el procesador, haciendo que el sistema quede inestable e incluso inutilizable (calma, se compone con reiniciar la computadora) ...

Debido a sus características, una vez iniciada una bomba fork, es casi imposible detener la ejecución del ataque puesto que para hacer eso necesitariamos matar los n-ésimos procesos que se han creado, pero como la memoria esta saturada no podríamos ejecutar ni siquiera un comando "kill"

Un ejemplo de estos ataques es la bien conocida instrucción de bash para los sistemas Unix/Linux:
:(){ :|:& };:


La cual, si deseas, puedes probar (bajo tu propio riesgo) escribiéndola en una terminal de bash en cualquier Linux; aunque si decides hacerlo, es recomendable que cierres todos los programas y guardes tus documentos para evitar pérdidas de información; de cualquier forma, el sistema se restaurá con reiniciar el equipo (siempre y cuando no vuelvas a ejecutar la instrucción)

A simple vista, la línea anterior puede parecer una marcianada, por lo que para entender como funciona debemos reescribirla en una forma más entendible, por ejemplo:

bomba()
{
bomba | bomba&
}; bomba

Ahora, como podrás notar, esta es una función recursiva que se llama a sí misma dos veces dentro de la definición de su cuerpo. Además, usa un pipe (|) para mandar la salida de la primera llamada a la segunda llamada.

El & hace que la función llamada se ejecute en segundo plano, por lo que las llamadas hijas no se pueden morir y de esta forma es como la instrucción empieza a comerse todos los recursos de tu máquina.

el último "bomba" es la primera llamada de la función y con la cual se desata la lluvia de llamadas recursivas.

Obviamente, este tipo de "ataques" no son tan críticos para los usuarios de escritorio de linux, dado que con reiniciar la máquina y no volver a ejecutar la función es suficiente, pero si consideramos el riesgo que representan para los servidores, es evidente que debemos buscar una forma para protegerlos.

Una forma muy simple para evitar estos bucles infinitos recursivos (bombas fork) es limitar el número de procesos que pueden ejecutarse simultáneamente por usuario, ésto lo hacemos editando el archivo /etc/security/limits.conf, ejecutando el comando:

sudo nano /etc/security/limits.conf

y agregamos la siguiente línea al final:

% hard nproc 100

Donde 100 es el número máximo de procesos que un usuario puede ejecutar, por lo que si consideras que es muy poco o empiezas a tener errores del tipo "bash: fork:", simplemente incrementa el valor a 1000 o más.

Listo, ahora sólo deberemos guardar y reiniciar la computadora y ya estaremos protegidos contra las bombas fork, aunque para confirmar podemos usar el comando ulimit -a y ver la linea max user processes, si concuerda con el valor que ingresamos, entonces todo esta bien.

Ahora si, si volvemos a probar la instrucción :(){ :|:& };: veremos que no congela el sistema y que al contrario logra sovrevivir a ella. :)



Expandir/Contraer este Post