La bomba fork è un attacco di tipo denial of service contro un computer che utilizza la funzione fork. L'azione si basa sull'assunto che il numero di programmi e processi che possono essere eseguiti contemporaneamente su un computer abbia un limite.
Una bomba fork agisce creando un gran numero di processi in un tempo molto rapido, così da saturare lo spazio disponibile nella lista dei processi che viene mantenuta dal sistema operativo. Se la tabella dei processi è piena, non possono essere avviati ulteriori programmi finché un altro non termina. Anche se ciò avvenisse, non è probabile che un programma utile all'utente venga avviato, dal momento che le istanze del programma bomba sono a loro volta in attesa di utilizzare per sé gli slot che si liberano nella tabella stessa.
Le bombe fork non si limitano ad utilizzare in maniera invasiva la tabella dei processi, ma impiegano anche del tempo di processore e della memoria. Pertanto il sistema rallenta e può diventare più difficile, se non impossibile da utilizzare.
Le bombe fork possono essere considerate un particolare tipo di wabbit (un programma che si auto-riproduce senza utilizzare funzionalità offerte da servizi o dalla rete).
Le bombe fork tradizionali comprendono la seguente (che utilizza il fork per mezzo dell'interprete Perl):
perl -e "fork while fork" &
e, (utilizzando la Bash shell[1][N 1]):
:(){ :|:& };:
Su un sistema con Microsoft Windows, utilizzando un comando batch (questa versione, al contrario di altre, funziona con tutti i sistemi Windows 9x e con tutti i sistemi della famiglia Windows NT):
:s
start %0
goto s
Oppure:
%0|%0
In C:
#include <unistd.h>
int main(void)
{
while(1) {
fork();
}
return 0;
}
In Python:
import os
while True:
os.fork()
In Haskell:
import Control.Monad
import System.Posix.Process
forkBomb = forever $ forkProcess forkBomb
In Ruby:
def forkbomb
loop { fork { forkbomb } }
end; forkbomb
In Scheme:
(letrec ((x (lambda () (begin (fork-thread x) (x))))) (x))
In assembly:
#solo linux, utilizzo della primitiva fork
#sintassi at&t
#fork bomb
#456b
.text
.global _start
_start:
movb $0x2,%al
int $0x80
jmp _start
In PHP:
<?php
while (true) {
pcntl_fork();
}
?>
Una volta che una bomba fork è stata attivata su un sistema, può essere impossibile ripristinarne la normale operatività senza forzarne un riavvio (boot) [alt + r-sist + r e i s u b], dal momento che l'unica soluzione ad una bomba fork è quella di distruggerne tutte le istanze.
Il tentativo di terminare (kill) i processi indesiderati di norma non ha successo, dal momento che ciò a sua volta richiede la creazione di un altro processo, cosa che potrebbe non riuscire dal momento che è probabile che non ci siano posti liberi nella tabella dei processi o spazio nelle strutture di memoria.
In rari casi, sui sistemi Linux può rivelarsi efficace l'utilizzo del comando skill da parte dell'utente root per eliminare la fork bomb attivata da un utente. Naturalmente, se l'attivatore è root stesso, tale comando si rivela inutilizzabile.
Poiché il sistema di funzionamento di una bomba fork richiede che questa sia in grado di lanciare un grande numero di processi nel minore tempo possibile, il sistema più efficace per prevenirne l'azione è quello di limitare il numero di processi che possono essere avviati da un singolo programma o utente.
Permettere agli utenti non fidati di avviare un limitato numero di processi significa ridurre il rischio di bomba fork, sia essa di origine malevola o non intenzionale. Ciò tuttavia non previene la possibilità che un certo numero di utenti possano collaborare a consumare spazio nella tabella dei processi realizzando un attacco del tutto analogo.
Nota che una bomba fork accidentale è molto improbabile che coinvolga più di un utente. Esiste una patch per il kernel Linux — chiamata grsecurity[2] — che abilita il logging per quegli utenti che hanno avviato una fork bomb.
I sistemi Unix-like tipicamente hanno un limite sui processi, controllata dal comando di shell ulimit[3]. Inoltre, su Linux o BSD, si può editare il file di configurazione dei limiti di pam: /etc/security/limits.conf[4].
Un'ulteriore soluzione è rappresentata dalla possibilità, da parte del kernel, di rilevare attacchi di questo tipo, come ad esempio è stato implementato, sotto forma di modulo, per il kernel Linux, come rexFBD[5], ormai obsoleto.
Una soluzione per i sistemi Linux 2.6 è quella di aggiungere la riga
* hard nproc 300
al file /etc/security/limits.conf, per imporre a tutti gli utenti un numero massimo di processi. Superato questo limite il kernel rifiuterà successive chiamate a fork() visualizzando il messaggio «fork: Risorsa temporaneamente non disponibile».
Persino con le precauzioni sopra citate, gli attacchi con le bombe fork possono avere effetti nefasti per un sistema. Ad esempio, se un server ha 24 CPU e permette agli utenti ordinari di avere fino a 100 processi, una bomba fork può giungere a saturare interamente le 24 CPU tanto da far sì che il sistema non risponda più e non permetta ad un amministratore di effettuare il login per risolvere il problema senza doversi recare fisicamente sul posto.
:()
{
:|:&
};
:
Il codice definisce una nuova funzione il cui nome è ":" (due punti: nella bash il nome di funzione può anche essere un simbolo) che richiama sé stessa ricorsivamente e in background in una subshell, quindi generando un nuovo processo per ogni iterazione, senza una condizione che arresti la ricorsione. Il punto e virgola dopo la definizione della funzione (quella contenuta nelle parentesi graffe) è un'alternativa al ritorno a capo e separa l'istruzione seguente, che semplicemente richiama la funzione ":" precedentemente definita.