fork炸彈(英語:fork bomb),在電腦領域中是一種利用系統調用fork(或其他等效的方式)進行的阻斷服務攻擊[1]。與病毒蠕蟲不同的是,fork炸彈沒有傳染性,而且fork炸彈會使有進程/程式限制的系統無法開起新工作階段,對於不限制進程數的系統則使之停止回應[2]。以fork炸彈為代表的自我複製程式有時亦被稱為wabbit

fork炸彈的概念:進程遞歸式衍生(fork,亦即自我複制),以使系統拒絕服務甚至崩潰

原理與影響

fork炸彈以極快的速度建立大量進程(進程數呈以2為底數指數增長趨勢),並以此消耗系統分配予進程的可用空間使進程表飽和,而系統在進程表飽和後就無法執行新程式,除非進程表中的某一進程終止;但由於fork炸彈程式所建立的所有實例都會不斷探測空缺的進程槽並嘗試取用以新增進程,因而即使在某進程終止後也基本不可能執行新進程。fork炸彈生成的子程式在消耗進程表空間的同時也會佔用CPU主記憶體,從而導致系統與現有進程執行速度放緩,響應時間也會隨之大幅增加,以致於無法正常完成任務,從而使系統的正常運作受到嚴重影響[3]

除了惡意觸發fork炸彈破壞的情況外,軟件開發中有時也會不慎在程式中嵌入fork炸彈,如在用於監聽網絡通訊端並列使客戶端-伺服器結構系統中伺服器端職責的應用程式中可能需要無限地進行迴圈(loop)與衍生(fork)操作(類似下節範例程式所示),而在這種情況下原始碼內的細微錯誤就可能在測試中「引爆」fork炸彈。

範例

以下程式段就是由Jaromil英語Jaromil所作的在類UNIX系統shell環境下觸發fork炸彈的shell指令碼代碼[4],總共只用了13個字元(包括空格):

:(){ :|:& };:

註解如下:

:()      # 定义函数,函数名为":",即每当输入":"时就会自动调用{}内代码
{        # ":"函數起始字元
    :    # 用递归方式调用":"函数本身
    |    # 並用管線(pipe)將其輸出引至...(因为有一个管線操作字元,因此會生成一個新的進程)
    :    # 另一次递归调用的":"函数
# 综上,":|:"表示的即是每次調用函数":"的時候就會產生兩份拷貝
    &    # 調用間脱鉤,以使最初的":"函数被關閉後為其所調用的兩個":"函數還能繼續執行
}        # ":"函數終止字元
;        # ":"函数定义结束后将要进行的操作...
:        # 调用":"函数,"引爆"fork炸弹

其中函數名「:」只是簡化的一例,實際上可以隨意設置,一個較易理解(將函數名替換為「forkbomb」)的版本如下:

forkbomb(){ forkbomb|forkbomb & } ; forkbomb

Windows下則可以批次處理命令如下實作:

%0|%0

POSIX標准下的CC++的實作:

#include <unistd.h>

int main()
{
  while(1)
    fork();
  return 0;
}

Perl語言的實作:

fork while fork

「熄火」

在系統中成功「引爆」fork炸彈後,可重新啟動來使系統恢復正常執行;而若要以手動的方法使fork炸彈「熄火」,那前提就是必須殺死fork炸彈產生的所有進程。為此我們可以考慮使用程式來殺死fork炸彈產生的進程,但由於這一般需要新增進程,且由於fork炸彈一直在探測與佔用進程槽與主記憶體空間,因而這一方法不易實現,雖用kill命令殺死進程後,釋放出的進程會被餘下的fork炸彈線程所產生的新進程佔用,但可以使用迴圈殺死所有進程,不過也會將無關的進程殺死

for ((tmp=1;tmp<10;tmp++));do killall bash;done

在Windows下,用戶可以退出當前用戶對談的方式使系統恢復正常,但此法奏效的前提是fork炸彈是在該用戶的特定對談內觸發的。

預防

由於fork炸彈透過不斷的開新進程來癱瘓系統,一個防止其嚴重影響系統的方法就是限定一個用戶能夠創建的進程數的上限,在Linux系統上,可以透過ulimit這個指令達到相應的效果,例如: ulimit -Hu 30 這個指令可以限制每一個用戶最多只能創建30個進程,還可以通過修改設定檔/etc/security/limits.conf來限制可生成的最大進程數來避開這枚炸彈。而FreeBSD系統的話系統管理者可以在/etc/login.conf底下的設定檔進行相關的設置

參考資料

  1. ^ fork bomb. FOLDOC. [2012-03-31]. (原始內容存檔於2012-03-05) (英語). 
  2. ^ How to: Prevent a fork bomb by limiting user process. nixCraft. [2012-04-01]. (原始內容存檔於2012-06-07) (英語). 
  3. ^ Understanding Bash fork() bomb ~ :(){ :|:& };:. nixCraft (英語). 
  4. ^ Jaromil. ASCII Shell Forkbomb. dyne.org. [2012-03-31]. (原始內容存檔於2012-02-29) (英語). 

參見

本條目部分或全部內容出自以GFDL授權發佈的《自由線上電腦詞典》(FOLDOC)。