Anatomy of a fork bomb

A little overview


A fork bomb is a snippet of code that's designed to spread, indefinitely, into many different processes, until the computer freezes.



It's not malware, strictly speaking, but it can cause some problems, depending on the circumstances.

If, for example, it is set to start automatically, it could be a real nightmare for an unsuspecting victim, as the computer would be, effectively, useless, at least for that particular user account.

Even if it was given a delay, in order to let the user log in and start doing whatever it is they normally do, it may cause the system to freeze in the middle of something critical.

Pranksters and evil doers alike may post this type of code on different online forums, pretending to be helpful.

The unsuspecting victim will look at the arcane code and, not knowing what the heck it does, will usually just run the thing.

And it can be made to look arcane and meaningless:

That's a typical linux forkbomb.

So, what's with the smiley faces?  How can something like this actually work, let alone cause the computer to freeze?

Let's disect it:

Anatomy of a Linux fork bomb:

:()

This is a function.  In a linux shell, a function can be called whatever, and it is declared a function by appending () to it.  In this case, we have function ":".  And what that means is that when the user enters ":" the shell will execute whatever follows.  Thus, this function could be called "gobbledygook".  It would just be a matter of replacing :() with gobbledygook()

{

 The curly bracket instructs the shell to execute whatever is contained in it as part of the previously declared function.

:

The colon doesn't really mean anything.  It is simply the name that was given to this function.  So, in this case, when function ":" is called, it will execute ":", which means the function is calling itself.

|

The pipe is used to redirect output.  In this case, function ":" calls function ":" and then sends the output (|) somewhere else.

:

Here's the darndest part.  Function ":" calls function ":" and then sends the output to function ":".  So, the thing is executing itself, twice, and sending whatever output it's generating, back to itself.

&

This simply instructs the shell to execute things in the background, meaning that it doesn't have to wait for it to finish.  It'll just instruct the shell to execute the command, and move on to the next one.

}

This curly bracket closes the function.  When ":" is executed, it will summon anything that was contained in {}.  So far, none of this code is being executed, it has, merely, been declared.  At this point, the user would still have to go and execute ":" in order for this to work.

;

The semicolon tells the shell to wait for another command.  It, pretty much, says "hey, we're not finished, hold on".  When a semicolon is passed on to the interpreter, it will use whatever is entered next as a new command.

:

As it was previously mentioned, the colon itself is meaningless.  In this case, it is simply telling the shell to execute the function named ":".  Because it was entered after the semicolon, the system is now recognizing ":" as a command, and is now ready to execute function ":".

So, this is what the smiley faces are actually saying:

Yo, system, I have a function and I want to call it ":" [ :() ], and what i want this function to do is to run function ":" and pipe the output on to itself [ {:|: ], and I want you to do this silently so don't bother me [ & ], you got it? [ }; ]... alright then go run my function [ : ]

And then the system will do as instructed.  It will soon fork into enough processes to use all available system resources.

Anatomy of a Windows fork bomb:


This little souvenir is not exclusive to linux.  It may, very well, be done in windows systems as well.

Here's a simple fork.bat

:b
start %0
%0|%0
goto :b

So, let's disect it:

:b

Here, we declare function "b", sort of... It's really more like a bookmark called "b"... something we can refer to, later on.

start %0

This part tells the interpreter to execute "%0", which is the currently executing .bat file.  Pretty much, it's telling it to start itself

%0|%0

As with the linux forkbomb, this windows version executes itself, and then pipes the output to itself, again.

goto :b


This line indicates the interpreter to go back to ":b" and start from there.

So, what this little sucker is doing is starting itself, then it pipes the output back onto itself, and then starts over, recursively, over and over and over.

What to do?

 Preventing this sort of thing from happening in Linux is not difficult.  It's just a matter of setting a limit on the number of processes that can be executed by a user, or group, at any given time.

To limit user process just add user name or group or all users to /etc/security/limits.conf file and impose process limitations.

The format would be as follows:

<domain> <type> <item> <value>

Where domain can be a user or group, type can be soft or hard, item can be "nproc" (as in number of processes), "maxlogins" (as in maximum number of logins for the user or group), fsize (as in maximum file size), etc...

By issuing the command  groups username one can determine the groups any given username is associated with on that particular machine.

 A quick and dirty fix is to append the following line to the file:

username hard nproc 300

where "username" is your username on that machine.  In this case, we're setting a hard limit to the number of processes that username can run at a time (300).

Setting limits to the number of processes a user can execute won't actually prevent a fork bomb from doing what it's going to do.  It will merely prevent it from crashing the system.  Once it reaches the limit, it won't be able to spawn any further sub processes.  The user should be able to save whatever work needs to be saved.

The downside to this is that there's no easy way to kill the forkbomb.  Once it's forked up to 300 processes, the system won't allow any new process to start.  Not with the same username.

In order to stop it, the user would have to, for example, exit to a virtual tty and log in as root, or another user with administrator privileges, in order to find and kill the process.

Not a very elegant solution, but it gives the user a chance to save important stuff.

And for Windows?  I guess a hard reboot is in order... :)