내가 이해한 바로는 환경 변수에 저장될 정보를 누구나 제공하도록 허용하는 것이 일반적으로 안전한 것으로 간주됩니다. Shellshock 취약점은 새로운 bash 인스턴스가 시작될 때 환경 변수 내의 함수 정의 끝 부분에 있는 코드가 실행되고 분명히 누구도 실행할 수 없도록 하기 때문에 문제가 됩니다. 당신의 서버에서 그들이 좋아하는 코드는 무엇이든. 함수 정의 자체는 분명히 보안 위험을 나타내지 않으며 코드를 실행하려면 명시적으로 호출해야 하기 때문에 허용됩니다.
내 질문은 왜 악의적인 사용자가 단순히 함수를 정의하고 악성 코드를 일반 명령으로 포함시킨 ls
다음 스크립트(또는 실행 중인 모든 항목)가 어느 시점에서 이 명령을 사용하기를 바라지 못하는가입니다.
내 생각의 예:
$ export ls='() { echo "doing bad things..."; }'
$ bash -c ls
doing bad things...
답변1
이는 보안 위험입니다. 이것이 일반적으로 다른 컨텍스트로 전환할 때(시스템 원격 제어, 사용자 변경 등) 이 작업을 수행할 수 없는 이유입니다.
필요한 환경 변수를 생성할 수 있는 경우 임의 코드를 실행할 수 있는 방법은 여러 가지가 있습니다. 예를
들어 $LD_PRELOAD
. 해당 변수를 설정할 수 있는 경우 라이브러리 함수를 대체하고 코드를 여기에 붙여넣을 수 있습니다. 이 변수를 설정 $DISPLAY
하고 프로그램이 연결된 X 디스플레이를 리디렉션하여 응용 프로그램을 제어할 수 있습니다.
sudo
그렇기 때문에 모든 변수의 환경을 제거 하려는 것입니다 . sudo
선택된 몇 가지 변수만 통과할 수 있습니다. 이러한 변수의 경우 해당 변수를 삭제합니다(변수를 전달 $TERM
하지만 비정상적인 문자가 포함된 경우에는 전달하지 않음).
답변2
내가 말하려는 것은 bash가 /bin/sh일 때입니다. 이것은 Bourne 쉘의 기능이 아니며 Posix 쉘의 기능도 아닐 것입니다. 사실 그들은 아마도 이 기능을 명시적으로 비활성화하려고 할 것입니다.
Bash는 이름과 해당 기능을 갖춘 유일한 Korn 유사 쉘이라는 사실에도 불구하고 Bash는 실제로 bourne 쉘보다 korn 파생 쉘에 더 가깝습니다. 제 생각에는 실제 장점이 없는 부엌 싱크대 기능입니다. 표준 bash 기능(예: bourne 쉘, posix 쉘 또는 최신 쉘에 공통적인 ksh88 하위 집합) 사용을 피하는 개발자, 즉 소프트웨어가 시작될 때 모범 사례와 표준 관용구를 고수하는 개발자는 Linux에 충격을 받았습니다. 익스플로잇 작성자는 자신의 의도와 상관없이 "bashism"을 자유롭게 사용할 수 있기 때문에 Mac은 이제 취약할 수 있습니다. 호환성 측면에서 /bin/sh로 호출되면 bash는 /bin/sh가 로그인 쉘이거나 korn 쉘이 아닌 대화형 쉘인 경우에만 다른 korn 쉘 파생 제품보다 bourne 쉘처럼 작동합니다. 이 스크립트는 bash가 할 수 있는 모든 작업을 자유롭게 수행할 수 있으며 실제 korn 쉘 기능이나 bash 고유 기능을 사용하고 있다고 불평하거나 경고하지 않습니다.
이것이 부엌 싱크대 기능이라는 것을 확신시키려고 노력할 것입니다. 두 가지 시나리오가 있습니다. 당신은 라우터, 네트워크 연결 스토리지 등을 만드는 임베디드 개발자입니다. 첫 번째는 더 큰 환경이며, 이는 더 많은 메모리 등을 의미합니다. 비용은 더 많이 들지만 이익은 적습니다. 그래서 이것이 bash의 이 기능 사용을 고려해야 하는 이유라면 FPATH와 자동 로드, ksh88 기능을 대신 사용해야 하지 않습니까? 환경에서 전체 함수를 바이트 단위로 전달하는 대신? ^$(.*)$ 등을 필터링하는 등 변수를 잘못 구문 분석할 수 있는 셸 스크립트를 입력하기 전에 환경을 일괄 구문 분석하고 정리하는 것을 고려할 수도 있습니다.
이는 변수가 무엇인지는 중요하지 않으며 스크립트는 변수를 참조하거나 사용할 필요가 없으며 여전히 취약할 수 있다는 점을 강조합니다.
#!/bin/sh
exec /usr/local/myapp/support/someperlscript.pl
태양 아래 다른 모든 것과 마찬가지로 위의 내용은 Perl 스크립트만큼 안전해야 하며 변수를 사용하지 않는데 어떻게 변수를 잘못 구문 분석할 수 있습니까? 로 변경
#!/bin/bash -norc
exec /usr/local/myapp/support/someperlscript.pl
또한 이것이 ENV 또는 그와 유사한 것과 아무 관련이 없다는 것도 도움이 되지 않습니다. bash는 고유해야 하기 때문에 모든 사람이 화상을 입습니다. Bash 버전 2에 이 문제가 있다는 사실이 나에게 요점을 증명합니다.이 기능을 사용한 사람은 아무도 없습니다그렇지 않으면 그렇게 해야 하기 때문에 그들의 신청을 위해아니요이미 주변에 숨어있어요이것긴. 더 나쁜 것은 이것을 피하는 것이 기본적으로 불가능하다는 것입니다.특징. 예를 들면 다음과 같습니다. 'su -'를 사용하여 누군가에게 물어보면 환경이 삭제된다는 설명이 있습니다. 매뉴얼 페이지를 확인하면 99.9%의 경우에 불과하다는 것을 알 수 있습니다. 이 시스템에서는 /bin/sh가 루트의 로그인 셸이고 /bin/sh가 bash이기 때문에 올바른 방법을 테스트했습니다.하지만, 이 예에서 나는노력하다내 .bash_profile을 강화하세요. 기존 이름을 루트(활성화)로 바꾸었지만 내 생각은 su라면 아마도 sudo일 것입니다. 어쨌든 다음으로 변경했습니다.
exec env -i TERM=vt102 LOGNAME=root USER=root HOME=/var/root /bin/ksh -i
그래서 실제로 환경을 완전히 버리고 최소한의 환경을 사용하고 문제가 발생하지 않아야 하는 현재 프로세스 대신 쉘을 실행했습니다. 그런 다음 표준 예제 대신 시도해 보십시오.
%dock='() { echo -e "\e[2t\c"; echo dockshock;} ; dock' su
이는 특정 기능을 구문 분석하는 것과는 아무런 관련이 없으며 익스플로잇이 해당 기능을 참조하고 사용할 수 있음을 보여줍니다. 함수에 루트인지 테스트하는 논리가 있다고 상상할 수 있습니다. 이 경우에는 꽤 표준적인 이스케이프 시퀀스를 사용하여 터미널 창을 아이콘화하거나 도킹하는 수정된 기능일 뿐입니다. 따라서 아이콘 제거를 클릭하면 Dockshock이 표시됩니다. 하지만 그래서 어떻게 될까요? 이제 이것을 시도해 보세요:
%TERM='() { echo -e "\e[2t\c"; echo dockshock;} ; TERM' su -
뭔지 맞춰봐? 창문이 바닥으로 빨려 들어갑니다. 나중에는 이런 모습이었는데...
%TERM='() { echo -e "\e[2t\c"; echo dockshock;} ; TERM' su -
Password:
dockshock
# env
_=/usr/bin/env
HOME=/var/root
LOGNAME=root
TERM=vt102
USER=root
# echo $0
/bin/ksh
#
그래서 그게 다입니다! 내보낸 함수는 실제로 rc 스크립트보다 우선합니다. 당신은 그것으로부터 숨을 수 없습니다.