쉘 쇼크 점검 명령 설명


32

Shellshock 버그에 대한 bash 쉘을 확인하는 데 사용한 명령은 다음과 같습니다.

env x='() { :;}; echo vulnerable' bash -c "echo this is a test"

누구든지 명령에 대해 자세히 설명해 주시겠습니까?


4
참조 : unix.stackexchange.com/q/157329/70524을 - Fixee의 대답은 도움이 될 수 있습니다.
muru

답변:


45

이 답변은 Creative Commons Attribution-Share Alike 4.0 라이센스에 따라 사용이 허가 된 Matthew Miller의 Fedora Magazine 원본 기사에서 파생 된 것입니다 .

설명하겠습니다 :

env x='() { :;}; echo OOPS' bash -c :

이렇게하면 취약한 시스템에서“OOPS”가 인쇄되지만 bash가 패치 된 경우 자동으로 종료됩니다.

env x='() { :;}; echo OOPS' bash -c "echo this is a test"

이렇게하면 취약한 시스템에서 "OOPS"가 인쇄되지만 인쇄됩니다. “this is a test” bash가 패치 된 경우에는 됩니다.

그리고 환경 변수와 관련이 있다고 들었을 것입니다. 그러나 왜 환경 변수의 코드가 실행됩니까? 글쎄요,하지만 그럴 필요는 없지만, 자신의 이익을 위해 너무 영리하다고 부르는 기능 때문에 결함이 생길 여지가 있습니다. Bash는 터미널 프롬프트로 볼 수 있지만 스크립팅 언어이며 함수를 정의 할 수 있습니다. 당신은 이렇게 이렇게 :

$ Ubuntu()  { echo "Ubuntu is awesome."; }

그리고 새로운 명령이 있습니다. 것을 명심 echo여기에 실제로 아직 실행되지 않고, 새 명령을 실행할 때 발생하는 내용으로 저장되었습니다. 이것은 잠시 후에 중요 할 것입니다!

$ Ubuntu
 Ubuntu is awesome.

유능한! 그러나 어떤 이유로 든 하위 프로세스로 새로운 bash 인스턴스를 실행하고 그 아래에서 멋진 새 명령을 실행하려고한다고 가정 해 봅시다. 명령문 bash -c somecommand은 정확히 다음을 수행합니다. 지정된 명령을 새 쉘에서 실행합니다.

$ bash -c Ubuntu
  bash: Ubuntu: command not found

아 슬퍼. 자식은 함수 정의를 상속하지 않았습니다. 그러나 셸에서 내 보낸 키-값 쌍의 모음 인 환경이 내재되어 있습니다. (이것은 완전히 '너덜 너덜 한 개념이다; 당신이 이것에 익숙하지 않다면, 지금 나를 믿어 라.) 그리고 bash는 함수를 내보낼 수 있다는 것이 밝혀졌다. 그래서:

$ export -f Ubuntu
$ bash -c Ubuntu
  Ubuntu is awesome.

이것이 달성되는 메커니즘이 다소 혼란 스럽다는 것을 제외하고는 모두 훌륭하고 좋은 것입니다 . 기본적으로 환경 변수에서 함수를 수행하기위한 Linux / Unix 매직이 없으므로 내보내기 함수는 실제로 함수 정의를 포함하는 일반 환경 변수를 작성합니다. 그런 다음 두 번째 쉘이 "들어오는"환경을 읽고 함수처럼 보이는 내용을 가진 변수를 만나면이를 평가합니다.

이론적으로 이것은 함수를 정의하는 것이 실제로 실행 되지 않기 때문에 완벽하게 안전 합니다 . 함수 정의의 끝에 도달했을 때 평가가 중단되지 않는 코드에 버그가있었습니다. 그냥 계속 가고있어

로 환경 변수에 저장된 함수가 합법적으로 만들어지면 결코 발생하지 않습니다 export -f. 그러나 왜 합법적입니까? 공격자는 기존 환경 변수를 구성 할 수 있으며, 함수처럼 보이는 경우 새로운 bash 쉘이이를 생각합니다!

첫 번째 예에서

env x='() { :;}; echo OOPS' bash -c "echo this is a test"

env명령은 주어진 변수 세트를 사용해 명령을 실행합니다. 이 경우 x함수처럼 보이는 것으로 설정 합니다. 이 함수는 단지 하나 :입니다. 실제로 아무것도하지 않는 것으로 정의 된 간단한 명령입니다. 그러나 semi-colon함수 정의의 끝을 알리는 뒤에 echo명령이 있습니다. 그것은 거기에 있어야하지 않지만, 우리가 그것을하지 못하게하는 것은 없습니다.

그런 다음,이 새로운 환경에서 실행되도록 지정된 명령은 새로운 bash 쉘이며 다시“ echo this is a test”또는“아무 작업 :”명령을 사용하면 완전히 무해하게 종료됩니다.

그러나-죄송합니다! 새 셸이 시작되고 환경을 읽으면 x변수에 도달 하고 함수처럼 보이므로 평가합니다. 함수 정의는 무해하게로드 된 다음 악의적 인 페이로드도 트리거됩니다. 따라서 취약한 시스템에서 위를 실행하면 “OOPS”다시 인쇄됩니다. 또는 공격자가 인쇄 작업보다 훨씬 더 나쁜 작업을 수행 할 수도 있습니다.


1
이것이 왜 작동하는지에 대한 훌륭한 설명을위한 Muchas gracias.
Doug R.

2
즉주의 env할 필요가 없습니다. 없이 명령을 사용하면 동일한 결과 (Bash가 업데이트되었는지 여부에 따라 합격 / 불합격)를 얻을 수 있습니다 x='() { :;}; echo OOPS' bash -c "echo this is a test". 변수 할당이있는 명령 앞에는 해당 변수와 해당 값이 명령 ( bash -c "..."이 경우) 환경 으로 전달되기 때문 입니다.
추후 공지가있을 때까지 일시 중지되었습니다.

1
...하지만 최신 패치 중 일부에서 필요할 수 있습니다. 상황이 유동적입니다.
추후 공지가있을 때까지 일시 중지되었습니다.

4
@DennisWilliamson env필요 여부 는 테스트중인 쉘이 아니라 테스트를 실행하는 쉘에 의해 결정됩니다. (이것은 동일 할 수 있습니다. 그럼에도 불구하고 우리는 bash가 자체 환경을 처리하는 방법을 테스트하고 있습니다.) Bourne 스타일 쉘은 NAME=value command구문을 허용 합니다. C 스타일 쉘 (예 : csh, tcsh)은 그렇지 않습니다. 따라서 테스트는 좀 더 이식성이 뛰어납니다 env(때로는 작동 방식에 대한 혼란을 야기하는 비용으로).
Eliah Kagan

2

에서 의 패치 버전bash 그것을 저장 환경 변수로 함수 정의 수출.

다음 x과 같이 함수 를 저장하십시오 .

$ x() { bar; }
$ export -f x

그리고 그 정의를 확인하십시오.

$ env | grep -A1 x
x=() {  bar
}

따라서 자신의 환경 변수를 정의하여이를 악용하고이를 함수 정의로 해석 할 수 있습니다. 예를 들어 env x='() { :;}'로 취급 될 것이다

x() { :;
}

shellshock 검사 명령은 무엇을합니까?

env x='() { :;}; echo vulnerable' bash -c "echo this is a test"

에서 man env,

  1. env -수정 된 환경에서 프로그램을 실행하십시오.

  2. :종료 상태로 종료합니다 0. 참조

  3. 패치되지 않은 bash의 새 인스턴스가로 시작 bash -c "echo this is a test"되면 만들어진 환경 변수가 함수로 처리되고로드됩니다. 따라서 출력을 얻는다

    취약
    이것은 시험이다

참고 : bash 시작 중에 함수 정의 외부의 에코가 예기치 않게 실행되었습니다. 함수 정의는 평가 및 악용을 수행하는 단계 일 뿐이며 함수 정의 자체와 사용 된 환경 변수는 임의적입니다. 쉘은 환경 변수를보고 x를보고, 함수 정의가 무엇인지에 대해 알고있는 제약 조건을 충족하는 것처럼 보이고, 의도하지 않게 에코를 실행하여 라인을 평가합니다 (악의적 인 명령이든 상관없이). . 또한 이것을보십시오


패치 된 bash 버전의 자식 셸에서 내보내는 경우 정의 된 bash 함수가 여전히 발견되었습니다. 다음을 참조하십시오 : chayan @ chayan : ~ / testr $ test () {echo "anything"; }; 수출 -f 테스트; bash -c test Ouput : anything 따라서 귀하의 답변은 다소 지시되지 않습니다. 정의 이상으로 변수를 확장하는 것으로 버그에 대한 kasiyA의 설명은 맞습니다.
heemayl

@heemayl이 행동은 자연 스럽습니다. 그러나 당신이 시도 env test='() { echo "anything"; }' bash -c "echo otherthing"하면 출력에서 볼 수 있습니다 otherthing. 패치에서 수정되었습니다. 내가 아직 명확하지 않으면 자유롭게 느끼십시오.
souravc

다시 한 번 명확히 해주세요. 마지막으로 우리는 기본적으로 함수를 정의하고 bash에게 echo를 실행하도록 지시합니다. 이 예에서는 bash에서 함수를 호출하지 않았습니다. 패치 된 패치와 패치되지 않은 bash 모두에서 동일한 출력을 갖지 않습니까? 버그가 기본적으로 bash가 함수 정의 뒤에 배치 된 명령을 실행했기 때문에 버그가 있다는 생각을 가지고 있지만 env test = '() {echo "anything"; }; echo "foo" 'bash -c "echo otherthing". 이 맥락에서 저를 명확히하십시오.
heemayl

@heemayl 내 대답을 편집했습니다. 이제 분명해지기를 바랍니다. 내 마지막 주석의 예에서 우리는 함수를 호출하지 않았습니다. 그러나 차이점은 unpatched bash정의 된대로 함수를 호출 할 수 있지만 패치 bash에는 정의 자체가 없다는 것입니다.
souravc

@heemayl : 아니요, 맞습니다. 패치 된 Bash는 여전히 함수 정의를 자식 환경으로 전달합니다. 패치와 다른 점은 함수 정의 ( echo vulnerable) 를 따르는 코드 는 실행되지 않는다는 것입니다. 최신 패치에서 전달 된 함수에는 특정 접두사 ( env 'BASH_FUNC_x()'='() { :;}; echo vulnerable' bash -c "echo this is a test") 가 있어야합니다 . 일부 최신 패치는 %%첫 번째 패치 대신 사용할 수 있습니다 ().
추후 공지가있을 때까지 일시 중지되었습니다.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.