2012-01-26 2 views
6

ELF 바이너리의 INTERP 섹션에서 set-uid와 상대 경로의 조합은 매우 위험합니다.ELF의 set-uid 및 INTERP (동적 링커)에 대한 상대 경로의 보안 문제

나는이 문제를보고해야한다 방법과 위치를 확실히 모르겠지만, 리눅스/glibc는 작품에 어떻게 동적 링크에 관한 일반적인 보안 문제 같은 날 것 같다, 그래서 내가 그것이 무엇인지 설명하자

ELF INTERP 섹션에서 --dynamic-linker gcc 옵션을 사용하여 동적으로 링크 된 바이너리를 빌드하고 상대 경로를 지정하여 동적 링크 된 상업용 응용 프로그램과 함께 사용자 정의 glibc 버전을 재배포 할 것을 고려하십시오 (링크 할 수없는 곳). LGPL glibc에 대해 정적으로,하지만 여전히 다른 glibc 버전을 가진 다른 리눅스 배포판에서 바이너리 작업을해야합니다.

루트에 바이너리를 설치하고 바이너리에 set-uid 플래그를 넣으면 효과적으로 루트킷이됩니다. 다른 디렉토리에서 실행하면서, 동적 인 링커 실행 파일을 대체 할 수 있습니다. 실행 파일은 루트 권한으로 실행됩니다. 지금이

./issue 

또는처럼 설정-UID 바이너리를 실행하면

#include <stdio.h> 

// 
// build with: 
// gcc -DNAME=\"vulnarable\" -o issue -Wl,--dynamic-linker,.lib64/ld-linux-x86-64.so.2 issue.c 
// sudo chown root issue 
// sudo chmod u+s issue 
// now build some code to be executed with root permissions (we use the same issue.c): 
// mkdir -p .lib64/ 
// gcc -DNAME=\"rootkit\" -o .lib64/ld-linux-x86-64.so.2 --static issue.c 
// 

int main(int argc, char* argv[]) 
{ 
    printf("(%s) euid:%d\n", NAME, geteuid()); 
} 

:이 문제를 설명하기 위해

다음 C 코드 (issue.c)에서보세요 예를 들어,이

ldd issue 

을하는 대신에 당신이 기대하는 것을 점점 :

(vulnarable) euid:0 

당신이 얻을 :

(rootkit) euid:0 

이제 포인트는 당신이 원하는대로와 LD-리눅스 x86-64.so.6 바이너리를 대체 할 수있다.

RPATH에서 $ ORIGIN을 해결하지 않았거나 set-uid 플래그가 설정된 경우 LD_LIBRARY_PATH를 무시하면 비슷한 문제가 해결 된 것으로 보입니다.

ELF의 INTERP가 set-uid 플래그가 설정 될 때마다 (즉, 기본 동적 링커 인 /lib32/ld-linux.so.2 또는/lib64/ld- linux-x86-64.so.2)?

그래서 glibc 또는 커널에서 어디에서 수정하거나보고해야합니까?

+0

'sudo '를 사용하는 것과 관련하여 루트 액세스 권한을 얻는 방법을 제안합니다. 즉 루트 액세스가 필요하다는 의미입니다. – ugoren

+0

어떤 커널과 배포판에서 이것을 테스트 했습니까? 나는 커널 2.6.32-38- 제네릭으로 우분투 10.04에서이 문제를 재현하는 데 어려움을 겪고있다. setuid 프로그램에서 기대할 수있는'(./issue) euid : 0' 만 얻을 수있다. –

+0

@ugoren : 그렇지 않습니다. 취약점이 실제로 있다고 가정 할 때, 공격자는 취약한 setuid 프로그램을 찾는 것이 필요합니다. 명령어에있는'sudo' 명령어는 단지 하나만 만들어서 문제를 증명할 수 있습니다. –

답변

5

네, 안전하지 않은 위치에 상대 경로를 지정했지만 세계 기록 가능한 고정 경로에 동일한 문제가있는 인터프리터를 지정하는 setuid 바이너리를 가지고있는 것은 안전하지 않습니다. 하지만 그것은 ELF 디자인의 논리적 결론이며, setuid 바이너리 용 INTERP 처리에 특별한 경우를 추가하는 것은 방법이 아닙니다. 의 경우 "의사, 내가 이것을 할 때 아파요. -하지 마세요. " 예,이 조합은 안전하지 않으므로 사용하지 마십시오! 어쨌든 ELF 통역사와 함께하는 것은 다소 진보 된 것이므로, 자신이하는 일을 이해하지 않는 한 그것을하지 말아야합니다.이 경우 논리적으로 무엇이 안전한지 또는하지 말아야하는지 결론 지을 수 있습니다.

ELF/POSIX/Unix의 고급 기능/강력한 성능을 발휘할 수있는 강력한 방법을 제공합니다.가능한 모든 나쁜 상황을 없애고 싶다면 시스템에 유연성이없고 프로그램하기가 훨씬 어려울 것입니다.

+0

동의. 이것은 절대 경로가 아닌 명령으로 setuid 프로그램에서'system()'을 호출하는 것과 같습니다. 프로그램에 libc의 커스텀 버전을 사용하고 싶다면 상대적인 INTERP를 사용하지 말라. 그냥 정적으로 대신 연결하십시오. LGPL은 일반적으로이를 허용합니다. – Dolda2000

+0

@ F'x : 좋은 대답입니다. set-uid 플래그를 어디에 두어야할지에 동의합니다. 그러나 인수는 ELF의 RPATH/RUNPATH 또는 LD_LIBRARY_PATH env var에도 적용됩니다.이 경우 (set-uid 플래그), RPATH/RUNPATH와 LD_LIBRARY_PATH는 모두 무시됩니다. 그렇다면 왜 INTERP를 무시하지 않습니까? – siddhadev

+2

LD_LIBRARY_PATH는 실행 파일 작성자가 아닌 사용자가 설정할 수 있으므로 LD_LIBRARY_PATH에는 적용되지 않습니다. 나는 RUNPATH가 실제로 처리되는 것이 이상하다고 생각한다. – Dolda2000