4/13/2008


Evitar ejecución de forkbombs

Ultimamente han comenzado a circular las Fork Bombs, que no son otra cosa que codigos de programación, los cuales consumen recursos de nuestra PC, dejandola totalmente inutilizable, vamos a ver algunos ejemplos y luego distintas soluciones que podemos darle a este problema
.
Uno escrito con Perl:

perl -e "fork while fork"

Otro con BASH:
:(){ :|:& };:

Este ultimo es el mas conocido y que se ha puesto de moda. Y es una versión ofuscada de:

forkbomb () {
forkbomb | forkbomb &
}
forkbomb

Lo que hace, es una función recursiva que se va llamando a si misma dos veces, creando un bucle interminable y consumiendo toda la memoria de nuestro sistema hasta dejarlo inutilizable, por lo cual no nos queda otra alternativa que reiniciar nuestro sistema.
Para ejecutar este codigo no debemos estar logueados como root, por lo cual cualquier usuario normal lo puede ejecutar y saturar todos los recursos de nuestra PC.

¿COMO SOLUCIONARLO?

Existe un comando interno de BASH llamado ulimit
(para mayor explicacion sobre el comando: man ulimit)
La opcion -u en este comando, nos permite configurar el numero maximo de procesos que los usuarios pueden ejecutar por lo cual, de esta manera al llegar la fork bomb al limite de procesos, no puede sobrepasarlo por lo cual con un valor bien configurado no nos probocaria problemas en el sistema.
Para ello ejecutamos

$: ulimit -u 50
Esta solución seria suficiente para solucionar esto, pero al momento de reiniciar nuestro sistema esta configuración se pierde.
Otra alternativa seria añadirlo al archivo /etc/profile y a /etc/bash.bashrc
Para evitar que se ejecute en sesiones de login y no-login.
Pero la forma estandar de hacerlo es añadiendolo a /etc/security/limits.confNOTA: En todos los script de BASH, como los que veeremos a continuación, todo lo precedido por # se lee como comentario. Siguiendo con el tema en una shell ejecutamos:

$: sudo nano /etc/security/limits.conf

Ponemos nuestra constraseña de usuario y veeremos en pantalla algo como esto:


# /etc/security/limits.conf
#
#Each line describes a limit for a user in the form:
#
#
#
#Where:
# can be:
# - an user name
# - a group name, with @group syntax
# - the wildcard *, for default entry
# - the wildcard %, can be also used with %group syntax,
# for maxlogin limit
#
# can have the two values:
# - “soft” for enforcing the soft limits
# - “hard” for enforcing hard limits
#
# can be one of the following:
# - core - limits the core file size (KB)
# - data - max data size (KB)
# - fsize - maximum filesize (KB)
# - memlock - max locked-in-memory address space (KB)
# - nofile - max number of open files
# - rss - max resident set size (KB)
# - stack - max stack size (KB)
# - cpu - max CPU time (MIN)
# - nproc - max number of processes
# - as - address space limit
# - maxlogins - max number of logins for this user
# - maxsyslogins - max number of logins on the system
# - priority - the priority to run user process with
# - locks - max number of file locks the user can hold
# - sigpending - max number of pending signals
# - msgqueue - max memory used by POSIX message queues (bytes)
# - nice - max nice priority allowed to raise to
# - rtprio - max realtime priority
#
#
##* soft core 0
% hard rss 10000
#@student hard nproc 20
#@faculty soft nproc 20
#@faculty hard nproc 50
#ftp hard nproc 0
% - maxlogins 4
% hard nproc 50
# End of file

Añadimos una linea (en el ejemplo ya esta añadida), con los siguientes valores.

% hard nproc 50

Con esto limitamos a 50 el numero maximos de procesos que puede ejecutar el usuario.
Guardamos la configuracion (Ctrl + O) y salimos (Ctrl + X).
Bien, ya estaria hecho ahora solo basta reiniciar el PC.$ sudo rebootY listo, ya estamos protegidos contra las fork bombs.
¿Como probarlo?, tipeamos lo siguiente:

$ ulimit -a

Y tendremos una salida como esta


core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 20
file size (blocks, -f) unlimited
pending signals (-i) unlimited
max locked memory (kbytes, -l) unlimited
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) unlimited
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 50
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited

Vemos el valor [max user processes] establecido en 50 (50 procesos como maximo puede
ejecutar el usuario).
Por lo cual si somos valientes y nos animamos a probar: :(){ :|:& };: podemos ver que
no pasa absolutamente nada en nuestro sistema y no se cuelga. =)NOTA: Si al configurar el valor de max user processes en 50, reciben cada tanto un error como este: bash: fork: recurso temporalmente no disponible, esto es debido a que su usuario esta ejecutando mas de 50 procesos normalmente, por lo cual para no recivirlo recomiendo modificar el valor a un nivel mas alto, como puede ser 100 (o de acuerdo a la cantidad de procesos que ustedes ejecuten normalmente) pueden saberlo utilizando el comando top.

Fuente

0 comentarios: