【程序安全】Fork炸弹
时间:2013-08-08 01:08:26 作者:vaster 标签: Linux shell 安全 分类: Shell
Fork炸弹是一个非常经典的递归程序,程序所做的事情只有一样:以极快的速度创建大量进程(进程数呈以2为底数的指数增长趋势),并以此消耗系统分配予进程的可用空间使进程表饱和,而系统在进程表饱和后就无法运行新程序,除非进程表中的某一进程终止;但由于fork炸弹程序所创建的所有实例都会不断探测空缺的进程槽并尝试取用以创建新进程,因而即使在某进程终止后也基本不可能运行新进程。fork炸弹生成的子程序在消耗进程表空间的同时也会占用CPU和内存,从而导致系统与现有进程运行速度放缓,响应时间也会随之大幅增加,以致于无法正常完成任务,从而使系统的正常运作受到严重影响
Bash中的fork炸弹:
.(){ .|.& };.
乍一样,感觉像乱写的几个符号一样,实际上,它的功能大得很,千万别随便就去执行它。
bash 中的 fork 炸弹的解释
.()
{
.|.&
}
;
.
第 1 行说明下面要定义一个函数,函数名为小数点,没有可选参数。
第 2 行表示函数体开始。
第 3 行是函数体真正要做的事情,首先它递归调用本函数,然后利用管道调用一个新进程(它要做的事情也是递归调用本函数),并将其放到后台执行。
第 4 行表示函数体结束。
第 5 行并不会执行什么操作,在命令行中用来分隔两个命令用。从总体来看,它表明这段程序包含两个部分,首先定义了一个函数,然后调用这个函数。
第 6 行表示调用本函数。
这样,.(){ .|.& };.就很清晰了,如果有兴趣的话,可以在自己的虚拟机上试试,执行完之后,你会发现系统运行巨慢,也杀不死它,最后看到系统的服务一个个被杀死,只能重启才能真正kill它。
谁来引爆fork炸弹:
除了恶意触发fork炸弹破坏的情况外,软件开发中有时也会不慎在程序中嵌入fork炸弹,如在用于监听网络套接字(英语:Network socket)并行使客户端-服务器结构系统中服务器端职责的应用程序中可能需要无限地进行循环(loop)与派生(fork)操作,而在这种情况下源代码内的细微错误就可能在测试中“引爆”fork炸弹。
如何杀死fork炸弹:
在系统中成功“引爆”fork炸弹后,我们可重启来使系统恢复正常运行;而若要以手动的方法使fork炸弹“熄火”,那前提就是必须杀死fork炸弹产生的所有进程。为此我们可以考虑使用程序来杀死fork炸弹产生的进程,但由于这一般需要创建新进程,且由于fork炸弹一直在探测与占用进程槽与内存空间,因而这一方法几乎不可能实现,而且用kill命令杀死进程后,释放出的进程槽又会被余下的fork炸弹线程所产生的新进程占用,
在Windows下,用户可以退出当前用户会话的方式使系统恢复正常,但此法奏效的前提是fork炸弹是在该用户的特定会话内触发的。
如何预防fork炸弹:
1. 写程序尽量严谨
2. 使用ulimit限制每个用户能够创建的进程数
实际上,fork 炸弹只是一个非常简单的递归函数,它并不涉及参数传递、返回值等问题,fork 炸弹让我们认识到了递归函数的强大功能,同时也意识到一旦使用不当,递归函数所造成的破坏将是巨大的。
http://zh.wikipedia.org/wiki/Fork%E7%82%B8%E5%BC%B9