2012-04-10 3 views
16

공용 라이브러리가있는 bash에 유틸리티 모음을 쓰고 있습니다. 필자가 작성하는 각 스크립트에는 실행 파일에 상대적인 라이브러리의 경로를 결정하는 코드 블록이 있어야합니다. 아니 실제 코드,하지만 예 : 대신 라이브러리를 검색하려고 프리앰블의환경 변수를 신뢰할 수 있습니까?

#!/bin/bash 

DIR="$(cd -P "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 
. $DIR/../lib/utilities/functions 

, 나는 도서관의 위치를 ​​표시하기 위해 환경 변수를 사용하는 밝은 생각을했다.

#!/bin/bash 

. $TOOLS_LIBRARY_PATH 

래퍼 프로그램을 사용하여 해당 환경 변수를 설정하거나 내 경로에서 설정할 수 있습니다. bash 툴셋을 구성하는 더 좋은 방법이 있지만 질문은 다음과 같습니다.

환경 변수를 신뢰할 수 있습니까?

나는 이것들 중 하나입니다. 나는 결코 그런 생각을하지 않았습니다. 다른 언어로 프로그래밍 할 때 경로를 사용하여 라이브러리를 찾는 경우 (예 : LD_LIBRARY_PATH, PYTHONPATH, PERLLIB, RUBYLIB, , NODE_PATH) 나는 그 코드가 안전하지 않을 수있는 방법을 중단하고 생각할 필요가 없었습니다.

실제로 LD_LIBRARY_PATH은 사용을 방해하는 Why LD_LIBRARY_PATH is bad입니다. Ruby 및 Perl 라이브러리 경로 환경 변수는 보안 메커니즘이 호출되면 무시됩니다 ($SAFE-T (taint mode)).

내 생각까지 ...

  • 사용자는 그들이 선택한 라이브러리에 TOOLS_PATH_LIBRARY를 설정할 수 있지만,이 유틸리티는 UID에서 실행됩니다. 악의적 인 라이브러리를 bash으로 직접 실행할 수 있습니다.
  • 내 도구 sudo 몇 가지. 누군가 TOOLS_PATH_LIBRARY을 활용할 수 있습니다. 그러나 도구는 sudo을 통해 실행되지 않으며 여기 저기에만 sudo을 호출합니다. 어쨌든 사용자는 이어야하며 sudo으로 직접 전화 할 수 있습니다.
  • TOOLS_PATH_LIBRARY을 신뢰할 수 없다면 PATH을 신뢰할 수 없습니다. 모든 프로그램 호출은 절대 경로를 사용해야합니다.
  • 쉘 프로그램에서는 절대 프로그램 인 별칭을 사용하므로 ls을 호출하는 대신 LS=/bin/ls과 같은 변수를 사용합니다. 내가 읽은 바에 따르면, 사용자가 프로그램 기본값을 별칭으로 다시 정의하지 못하도록 보호합니다. 참조 : PATH, functions and security. Bash scripting best practices. .
  • Perl의 taint mode은 모든 환경 변수를 "오염 된"것으로 간주하므로 환경의 위험에 대해 추론하려고합니다.
  • 해당 사용자가 root가 아닌 한 한 사용자가 다른 사용자의 환경을 변경할 수 없습니다. 따라서 사용자가 권한을 상승시키기 위해 자신의 환경을 변경하는 것에 대해서만 우려하고 있습니다. 참조 : Is there a way to change another process's environment variables?

나는 종류의 대답에 rubber ducked이를했습니다,하지만 난 여전히 두드려 응답하지 않기 때문에, 그것을 게시거야.

업데이트 : 환경 변수를 사용하여 라이브러리와 실행 파일의 경로를 지정하는 것과 관련된 보안 문제는 무엇입니까?

+5

물론 허용 할 수 없습니다. 아무 것도 믿을 수 없어. 그러나 그것이 맞다고 생각하지 않는다면, 당신은 어디에 있습니까? 너는 아무 것도 할 수 없다. –

+0

추가 변수없이 모든 디렉토리를 해결할 수 있다면 직접적인 사용자에게 친절하십시오. 그러나 백도어를 환경 변수의 형태로두면 라이브러리와 통합하려는 사람들에게 친절하게 남을 수 있습니다.변수가 올바르게 설정되었다고 가정하십시오 (Chris Morgan의 "이유"참조). – bobah

+1

좋은 게시글, 많은 문제를 확인했습니다. 재미있는 일이지만, 분석 마비에 접하는 것 같습니다 (Chris의 말처럼). 보안은 레이어에 관한 것입니다. 사용자를 신뢰할 수 없다면, 더 많은 레이어가 필요합니다. 사람들은 보안 문제에서 PHD를 얻을 수 있으며 MilSpec 또는 은행 보안 시스템을 해킹 당할 수 있으므로 첨부 준비와 성공적인 연결 확률 사이의 균형을 파악해야합니다. 현재 프로젝트, 합법적 인 사용자 및 다른 지분 소유자에게 행운을 빕니다. – shellter

답변

1

짧은 답변 :

사용자를 가정하면 어쨌든 프로그램과 자신이 선택한 임의의 코드를 실행할 수 있습니다, 당신은 환경을 포함하여 그들이 당신을 공급 아무것도, 신뢰 할 필요가 없습니다. 계정이 어떤 방식으로 제한되어 있다면 (셸 액세스가없고 실행을 허용하는 파일 시스템에 대한 쓰기 권한이 없음) 그림이 변경 될 수 있지만 스크립트가 사용자 자신을 할 수있는 한 악의적 인 목적을 방지해야하는 이유는 무엇입니까? 간섭?


긴 대답 :

고려 적어도 두 개의 문제가 보안 ​​문제의 관점에서 :

  • 무엇과 누구를 우리가 방지해야합니까?
    • (밀접하게 관련 질문 : 우리의 프로그램이 실제로 할 수 있으며 잠재적으로 무엇을 깰 수 있을까?) 우리가 그렇게 어떻게
  • 를?

프로그램을 시작한 사용자의 사용자 ID로 프로그램을 실행하고 모든 입력 (즉, 공격을 수행 할 수있는 유일한 사용자)을 제공하는 경우 프로그램을 실행하는 드문 경우가 있습니다 공격으로부터 프로그램을 강화하기 위해 전혀 의미가 없습니다. 안티 카피 보호와 높은 점수 공유는 염두에 두지 만, 그 일군은 입력에만 관심이있는 것이 아니라 사용자가 코드와 메모리를 읽지 못하도록하는 것보다 훨씬 더 중요합니다. 어떤 종류의 suid/sgid 속임수없이 쉘 스크립트의 코드를 숨기는 것은 내가하는 방법을 알 수 없다. 내가 생각할 수있는 최선의 방법은 코드를 왜곡시키는 것입니다.

이 상황에서 사용자가 프로그램을 속일 수있는 모든 사항은 도구를 사용하지 않고도 수행 할 수 있으므로이 사용자의 공격으로부터 "보호"하려고 시도하는 것은 의미가 없습니다. 실제로 공격에 대한 보호가 필요한 것처럼 설명에 표시되지 않습니다.


당신이 보호를 필요합니까 가정 할 때, 당신은 단순히 환경 변수에 의존 할 수 없습니다 - 당신이 LD_LIBRARY_PATHLD_PRELOAD, /bin/id 또는 /bin/ls 같은 절대 경로로도 호출 도구 같은 것들을 다시하지 않을 경우 당신에게 신뢰할 수있는 답변을 제공하지 않습니다 그 도구가 정적으로 컴파일되지 않는 한. 따라서 sudo의 기본값은 env_reset이며, suid 프로그램을 실행하면 특정 환경 변수를 무시해야하는 이유입니다. 즉, TOOLS_PATH_LIBRARYPATH이 동등한 신뢰를 가질 수 있지만 다른 상황의 국경 케이스에서는 그렇지 않을 수도 있습니다. 즉, 시스템 관리자가 sudo 사용을 위해 PATH을 재설정하지만 비표준 환경 변수가 통과하도록 할 수 있습니다. 을 통하여.

위에서 지적한 것처럼 argv[0] (또는 bash 등가물 ${BASH_SOURCE[0]})은 환경 변수보다 더 신뢰할 수 없습니다. 사용자는 단순히 원본 파일의 사본이나 심볼릭 링크를 만들 수있을뿐만 아니라, execve 또는 bash의 exec -a foo bar은 에 무엇이든 넣을 수 있습니다.

+0

아니요, 도움이됩니다. 이게 제가 부탁하는 것입니다. 어쩌면 다음 질문에 더 많은 이야기를 할 것입니다. 코드를 숨기거나 데이터를 보호하려고하지 않습니다. 환경 변수를 라이브러리 경로로 사용하고 타이핑 한 다음 '평가'와 같이 끔찍하다고 생각한 좋은 아이디어가 있습니다. 나는 이것이 보안 결함이있는 얼굴이되어야한다고 생각했다. 내가 그것에 대해 생각할수록 더 생각하지 않았다. 지금 나는 생각하지 않고있다. –

+0

그렇다면 다음과 같습니다. "프로그램을 시작한 사용자의 사용자 ID로 프로그램을 실행하고 모든 입력 (즉, 공격을 수행 할 수있는 유일한 사용자)을 제공하는 경우" 그러면 ** 당신은 ** 환경을 신뢰할 필요가 없습니다. –

+0

사용자가 어쨌든 자신이 선택한 프로그램과 코드를 실행할 수 있다고 가정하면 예. 계정이 어떤 방식으로 제한되어 있다면 (셸 액세스가없고 실행을 허용하는 파일 시스템에 대한 쓰기 권한이 없음) 그림이 변경 될 수 있지만 스크립트가 사용자 자신을 할 수있는 한 악의적 인 목적을 방지해야하는 이유는 무엇입니까? 간섭? –

3

환경 변수의 수정을 막기위한 다양한 프로그램에 메커니즘이 있지만 결론은 환경 변수를 신뢰할 수 없다는 것입니다. 보안 우려는 매우 기본적인 것입니다 :

사용자가 실행될 것으로 예상되는 것을 변경할 수있는 경우 언제든지 취약점이 악용 될 가능성이 있습니다.

케이스 인 포인트 (case-in-point)는 CVE-2010-3847입니다. 따라서 setuid 또는 setgid 바이너리가 포함 된 파일 시스템에 대한 쓰기 권한이있는 취약한 공격자가이 결함을 사용하여 권한을 상승시킬 수 있습니다. 여기에는 사용자가 수정 한 환경 변수가 포함됩니다.

CVE-2011-1095은 SUID 바이너리를 포함하지 않는 또 다른 예입니다. "glibc cve environment"에 대한 Google 검색을 수행하여 사람들이 환경 변수 수정을 통해 수행 할 수 있었던 것들을 확인하십시오. 꽤 교활 해요.

귀하의 관심은 정말 당신의 진술로 요약 :

그들이 선택한 라이브러리에 TOOLS_PATH_LIBRARY을 설정할 수 있습니다 사용자 만이 유틸리티는 자신의 UID에서 실행됩니다. 그들은 단순히 악성 라이브러리를 bash로 직접 실행할 수 있습니다.

여기에서 핵심 구절은 악성 라이브러리을 실행합니다. 이것은 자신의 라이브러리가 자신의 UID에 의해 소유되었다고 가정합니다.

여기가 보안 프레임 워크를 통해 많은 이점을 얻을 수있는 곳입니다. 이 문제에만 초점을 맞추고 내가 쓴 한 당신은 여기에서 찾을 수 있습니다

https://github.com/cormander/tpe-lkm

을 모듈 정지가 execve/mmap에/쓰기, 또는 신뢰할 수있는 사용자 (루트)가 소유하지 않은 파일을 호출 mprotect가 . 신뢰할 수있는 사용자가 소유 한 파일/디렉토리에 악의적 인 코드를 넣을 수없는 한이 방법으로 시스템을 악용 할 수 없습니다.

SUID 바이너리 또는 해당 변수가 포함 된 sudo를 사용하는 경우 "paranoid"및 "strict"옵션을 사용하여 루트가 아닌 소유 바이너리를 트러스트하지 못하게 할 수 있습니다.

이 신뢰할 수있는 경로 실행 방법은 바이너리 및 공유 라이브러리를 통한 직접 실행을 보호합니다. 해석 된 언어에 대해 (있는 경우) 거의하지 않습니다. 왜냐하면 바이트 코드를 파싱하고 직접 실행하지 않기 때문입니다. 따라서 여전히 PYTHONPATH, PERLLIB, CLASSPATH 등으로 어느 정도주의를 기울여야하며 언급 한 언어의 안전 메커니즘을 사용하십시오.

+0

CVE-2010-3847에는 OP가 자신의 SUID 코드를 가지고 있지 않기 때문에 SUID 바이너리가 관련되어 있습니다 (sudo가 자신의 코드에서 벗어나는 이유는 외부에서 쉽게 sudo를 공격 할 수 있기 때문입니다) 이것이 위험하다고 생각하지 않습니까? –

+0

@DouglasLeeder : 그건 단지 예일뿐입니다. 나는 CVE-2011-1095도 포함시켰다. 명부는 계속적으로 간다, 나는 다만 나의 머리의 정상 떨어져 그 모두를 생각할 수 없다. –

+0

"실행될 것으로 예상되는 것을 사용자가 변경할 수있는 경우 언제든지 취약점이 악용 될 가능성이 있습니다." - 다른 보안 수준에서 추가해야한다고 생각합니다. 그렇지 않으면 사용자가 입력하는 명령을 변경하면 사용자가 해당 명령을 파울하게됩니다. –

0

다른 사람의 환경을 절대 신뢰할 수 없습니다.

단순히이 중요한 코드가 모두 포함 된 새 사용자를 만들면 안됩니다. 그런 다음 /etc/passwd에서 직접 정보를 가져 오거나 ~foo 구문을 사용하여 사용자의 홈 디렉토리를 찾을 수 있습니다.

# One way to get home directory of util_user 
DIR=$(/usr/bin/awk -F: '$1 == "util_user" {print $6}' /etc/passwd) 

# Another way which works in BASH and Kornshell 
[ -d ~util_dir ] && DIR=~util_dir 


# Make sure DIR is set! 
if [ -z "$DIR" ] 
then 
    echo "Something's wrong!" 
    exit 
fi 
관련 문제