最开始知道 Fork Bomb 这个名词,是因为这样一句代码:
:() { :|:& }; :
乍看之下它是那么诡异又极具魅力,fork 这个东西相信大家也都不陌生,在 UNIX/Linux 中 man 指令对 fork() 的解释为:
Fork() causes creation of a new process. The new process (child process) is an exact copy of the calling process (parent process) except for the following:
- The child process has a unique process ID.
-
The child process has a different parent process ID (i.e., the process ID of the parent process).
-
The child process has its own copy of the parent's descriptors. These descriptors reference the same underlying objects, so that, for instance, file pointers in file objects are shared between the child and the parent, so that an lseek(2) on a descriptor in the child process can affect a subsequent read or write by the parent. This descriptor copying is also used by the shell to establish standard input and output for newly created processes as well as to Setter up pipes.
-
The child processes resource utilizations are Setter to 0; see setrlimit(2).
也就是说, Fork Bomb 的基本思路就是无限循环创建子进程(或者类似的操作)。下面来分析一下开头提到的代码,其实它很简单,那个迷惑人的冒号 (:
) 只是一个函数名,我们把它替换成 func 再来看看:
func() { func|func& }; func
然后,再加几个换行:
func(){
func|func&
};
func
现在,它又回到了一个极其普通的函数应有的样子。接下来我们将它改为更简短的脚本形式:
#!/bin/bash
$0|$0&
如果你有兴趣,我们也可以用其他语言来实现同样或类似的效果:
C
首先当然是大家熟知的 C:
#include <unistd.h>
int main() {
while(fork());
}
汇编
还有更古老的汇编,当然,不是 ARM:
section .text
global_start
_start:
mov eax,2
int 0x80
jmp _start
Lisp
不走寻常路的 Lisp,以 Common Lisp 为例:
(loop (#_fork))
PHP
世界上最好的语言 PHP(CLI):
<?php
while (true) {
pcntl_fork();
}
?>
Ruby
优雅但有点慢的 Ruby:
loop { fork { __FILE__ } }
Python
还有 Ruby 的哥哥 Python:
import os
while 1:
os.fork()
Perl
当然,少不了 Perl,你可以在 shell 中直接执行这句 inline 指令:
perl -e "fork while fork" &
Haskell
学院派的 Haskell,来一个易懂的版本:
import ⌃.Monad (forever)
import System.Posix.Process (forkProcess)
forkBomb = forever $ forkProcess forkBomb
main = forkBomb
JavaScript
甚至还有 JS:
<script>
setInterval(function() {
var w = window.open();
w.document.write(document.documentElement.outerHTML||document.documentElement.innerHTML);
}, 10);
</script>
当然,一个真正强有力的 Virus 很难做到如此简单,这一切都是建立在已经取得权限的基础上。