KOROMOON

착한 사마리아인이 되고 싶습니다.

1/26/2022

[CVE-2021-4034] pkexec 툴의 로컬 권한 상승 취약점 (Local Privilege Elevation Vulnerability in the pkexec Tool)


( 1 ) 취약점 설명


CVE-2021-4034 취약점은 2022년 01월 25일 Qualys 보안회사의 Bharat Jogi 보안연구원에 의해 공개되었으며 polkit 소프트웨어 제품군 중 하나인 pkexec 툴의 로컬 권한 상승 취약점임.


polkit 소프트웨어 : 권한 없는 응용 프로그램이 권한 있는 서비스 및 인터페이스를 구성하고 액세스할 수 있도록 하는 툴킷

pkexec 툴 : 위 polkit 소프트웨어 제품군 중 하나로 승인된 사용자가 다른 사용자로 실행할 수 있도록 하는 툴

polkit 소프트웨어 홈페이지 : https://gitlab.freedesktop.org/polkit/polkit/


polkit 소프트웨어는 모든 주요 Linux 배포판에 기본적으로 설치되는 SUID 루트 프로그램 중 하나임.

2009년 5월 첫 번째 버전(커밋 c8c3d83, "pkexec(1) 명령 추가") 이후 모든 버전의 pkexec 툴에 취약함.

권한이 없는 사용자가 CVE-2021-4034 취약점을 악용하여 전체 루트 권한을 얻을 수 있음.

현재 polkit 소프트웨어의 최신 버전은 0.120 버전으로 취약점 발표 후 새로운 버전이 나오지 않은 상태임.


취약한 버전 : 

2009 년 이후의 모든 Polkit 버전 (0.120 이하 버전)


< PoC 테스트 - wdormann 님의 트위터 참조 >


추가적으로 PoC 코드는 공개된 상태임.

링크 : https://www.qualys.com/2022/01/25/cve-2021-4034/pwnkit.txt




( 2 ) 취약점 분석


pkexec 툴의 main() 함수 시작 부분은 명령줄 인수(534 ~ 568 줄)을 처리하고 경로가 절대적이지 않은 경우 PATH 환경 변수의 디렉토리(610 ~ 640 줄)에서 실행할 프로그램을 검색함.



불행히도 명령줄 인수 argc 의 수가 0 이면 execve() 에 전달하는 인수 목록 argv 가 비어 있음을 의미함.

즉, {NULL} - argv[0] 은 NULL 이며 인수 목록의 종결자임.


- 534 줄에서 정수 n 은 영구적으로 1로 설정됨.

- 610 줄에서 포인터 경로는 argv[1] 에서 범위를 벗어남.

- 639 줄에서 포인터 s 는 argv[1] 의 범위를 벗어남.



새 프로그램을 execve() 하면 커널은 인수, 환경 문자열 및 포인터(argv 및 envp)를 새 프로그램 스택의 끝에 복사됨.

argv 및 envp 포인터는 메모리에서 연속적이기 때문에 argc 가 0 이면 범위를 벗어난 argv[1] 으로 실제로 첫 번째 환경 변수인 "value" 에 대한 포인터인 envp[0] 임.


- 610 줄에서 실행될 프로그램의 경로는 argv[1] (즉, envp[0]) 에서 범위를 벗어나 읽혀지고 "value" 을 가리킴.

- 632 줄에서 이 경로 "값" 은 g_find_program_in_path() 에 전달됨. (629 줄에서 "value" 이 / 로 시작하지 않기 때문)

- 그런 다음 g_find_program_in_path() 는 PATH 환경 변수의 디렉토리에서 "value" 이라는 실행 파일을 검색함.

- 이러한 실행 파일이 발견되면 632 줄에서 전체 경로가 pkexec 툴의 main() 함수로 반환됨.

- 마지막으로 639 줄에서 이 전체 경로는 argv[1] (즉, envp[0]) 에 대해 범위를 벗어나 작성되어 첫 번째 환경 변수를 덮어씀.


위 내용을 정확하게 풀어쓰자면 다음과 같음.


PATH 환경 변수가 "PATH=name" 이고 "name" 디렉토리가 존재하고(현재 작업 디렉토리에서) "value" 라는 실행 파일이 포함되어 있으면 "name/value" 문자열에 대한 포인터가 envp[0] 범위를 벗어나 기록됨.


또는


PATH 환경 변수가 "PATH=name=." 이고 "name=." 디렉토리가 존재하고 "value" 라는 실행 파일이 포함되어 있으면 "name=./value" 문자열에 대한 포인터가 envp[0] 범위를 벗어나 기록됨.


다시 말해서 이 범위를 벗어난 쓰기를 통해 "안전하지 않은" 환경 변수를 pkexec 툴 권한으로 실행될 수 있음.

원래 "안전하지 않은" 변수는 일반적으로 main() 함수가 호출되기 전에 SUID 프로그램 환경에서 제거됨. (ld.so 에 의해)




( 3 ) 취약점 방어


취약점 발표 후 현재 polkit 소프트웨어의 새로운 버전이 나오지 않은 상태임.

임시 완화 방법으로 제품군으로 포함된 pkexec 툴의 SUID 비트를 제거해야 함.


chmod 0755 /usr/bin/pkexec 




참고 사이트 : 

https://blog.qualys.com/vulnerabilities-threat-research/2022/01/25/pwnkit-local-privilege-escalation-vulnerability-discovered-in-polkits-pkexec-cve-2021-4034

https://www.bleepingcomputer.com/news/security/linux-system-service-bug-gives-root-on-all-major-distros-exploit-released/

https://blog.alyac.co.kr/4448

https://ko.wikipedia.org/wiki/%ED%8F%B4%ED%82%B7

https://gitlab.freedesktop.org/polkit/polkit/

https://twitter.com/wdormann/status/1486107423622545411

https://haxx.in/files/blasty-vs-pkexec.c

https://www.qualys.com/2022/01/25/cve-2021-4034/pwnkit.txt

https://access.redhat.com/security/cve/CVE-2021-4034




============================================================

본 게시물은 KOROMOON 님께서 작성하였으며 CCL (Creative Commons License) 에서 "저작자표시-비영리-동일조건변경허락" 이용조건으로 자료를 이용하셔야 합니다.

댓글 없음:

댓글 쓰기