환경 변수에서 함수를 정의하는 기능 자체가 보안 위험이 아닌 이유는 무엇입니까?


9

내가 알기로, 일반적으로 누구나 환경 변수에 저장 될 정보를 제공하게하는 것이 안전하다고 간주됩니다. 쉘 쇼크 취약점은 환경 변수 내부의 함수 정의 끝의 코드가 새로운 bash 인스턴스가 시작될 때 실행되고 누군가가 서버에서 원하는 코드를 실행하기를 원하지 않기 때문에 여기서 문제가됩니다. . 함수 정의 자체는 분명히 보안 위험이 아니며 코드를 실행하려면 명시 적으로 호출해야하기 때문에 허용됩니다.

내 질문은 악의적 인 사용자가 단순히 악의적 인 코드를 포함하는 기능을 정의하는 것이 불가능한 이유는 ls무엇입니까? 그런 다음 스크립트 (또는 실행중인 것이 무엇이든) 가이 명령을 어느 시점에서 사용하기를 희망합니까?

내가 생각한 것의 예 :

$ export ls='() { echo "doing bad things..."; }'
$ bash -c ls
doing bad things...

답변:


10

보안 위험이 있습니다. 따라서 일반적으로 다른 컨텍스트 (시스템의 원격 제어, 사용자 변경 등)로 전환 할 수 없습니다.

원하는 환경 변수를 만들 수 있다면 임의의 코드를 실행할 수있는 여러 가지 방법이 있습니다.
가지고 $LD_PRELOAD예를 들어. 해당 변수를 설정하는 기능이 있으면 라이브러리 함수를 바꾸고 코드를 거기에 넣을 수 있습니다. $DISPLAY변수 를 설정하고 프로그램이 연결된 X 디스플레이를 리디렉션하여 앱을 제어 할 수 있습니다.

이것이 sudo모든 변수의 환경을 제거하는 것과 같은 이유 입니다. sudo몇 가지 선택 변수 만 허용합니다. 그리고 이러한 변수 중 변수를 삭제합니다 ( $TERM변수를 통과 하지만 이상한 문자가 포함되어 있지는 않습니다).


와우, 나는 항상 BASH에서 수행하는 일부 거대한 스크립트가 sudo로 시작했을 때 이상한 경로가 실패하는 이유, 특히 경로 주위에서 왜 sudo 시작을 확인하고 차단했는지 알았지 만 왜 그런 일이 발생했는지 알지 못했습니다. 환경 변수를 제거하는 좋은 설명 덕분에 문제.
Lizardx

3

bash가 / bin / sh 일 때라고합니다. 그것은 bourne shell의 기능이 아니며 posix shell의 기능이 아니라는 사실을 분명히 알고 있습니다. 사실 그들은 분명히 그것을 금지하고 싶을 수도 있습니다.

Bash는 그 이름에도 불구하고 bourne shell보다 korn 파생 쉘보다 더 많으며 기능이있는 유일한 Korn shell이며 실제로는 실용성이없는 주방 싱크 기능입니다. 현대 쉘이 공통적으로 사용하는, 즉 다시 말해 쉘 쉘, posix 쉘 또는 ksh88 서브 세트와 같은 표준에 대한 bash 기능을 피하는 개발자는 소프트웨어가 켜졌을 때 충격을받습니다. 익스플로잇 작성자는 의도에도 불구하고 'bashism'을 자유롭게 사용할 수 있기 때문에 Linux와 mac은 현재 잠재적으로 취약합니다. 호환성이 훨씬 뛰어나면 다른 korn 쉘 파생 제품에 비해 / bin / sh로 호출 될 때 / bin / sh가 로그인 쉘이거나 대화식 쉘인 경우에만 bash가 korn 쉘보다 Bourne 쉘과 유사하게 동작 할 때만 가능합니다.

나는 주방 싱크 기능을 설득하려고 노력할 것입니다. 두 가지 경우가 있습니다. 당신은 라우터, 네트워크 연결 스토리지 1st env env와 같은 장치를 만드는 임베디드 개발자입니다. 더 많은 메모리, 더 많은 비용, 따라서 이익이 적으므로 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 % 만 나타납니다. 이 시스템 / 빈 / SH 루트의 로그인 쉘, 그리고 / 빈은 / 쉬 배쉬입니다에 있기 때문에 나는 그 올바른 방법을 테스트 하지만 내가이 예에서는 시도내 .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 스크립트보다 우선합니다. 피할 수 없습니다.


1
POSIX는 드래프트 2에서 내보낼 수있는 함수를 허용하고 이후에는이를 허용하지 않았습니다. 이 기능 은 미쳤다.
mikeserv
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.