
나는 흔히 Pwnkit이라고 불리는 취약점을 학습 목적으로 분석하고 이에 대한 PoC를 작성했습니다. 엄격히 학습 목적으로만 사용하십시오.
면책 조항: 본 자료는 오직 교육 목적으로만 제공됩니다. 대상 시스템 소유자의 서면 동의 없이 익스플로잇을 사용하는 것은 비윤리적이며 법적 처벌을 받을 수 있습니다.
chmod +x build.sh../build.sh../mls_envp. root 권한을 획득하게 됩니다.취약한 버전의 polkit(0.105)에서 작성자 데이비드 조이텐은 pkexec가 항상 콘솔에서 호출될 것이라고 가정했습니다. 그는 argv[0]이 프로그램 자체의 이름이므로 argc(인자 개수)가 항상 1보다 크다고 전제했습니다. 그러나 pkexec는 빈 인자 배열을 전달하여 시스템 호출 execve를 통해 호출할 수 있습니다. 이로 인해 프로그램의 로직이 깨집니다.
pkexec 코드에는 argv가 최소한 하나의 요소를 포함한다는 기대가 하드코딩되어 있습니다. argc가 0일 때도 프로그램은 여전히 argv[1]에 접근하려고 시도합니다. 이는 argv 배열의 경계를 초과하여 envp(환경 변수) 배열의 첫 번째 요소를 읽게 됩니다. 우리의 경우 그곳에는 "exp_exe" 문자열이 들어 있습니다.
pkexec는 g_find_program_in_path 함수를 사용하여 exp_exe 프로그램을 찾으려고 시도합니다. 검색에는 PATH 변수를 사용합니다. 우리는 PATH를 GCONV_PATH=.로 바꿔치기합니다. 결과적으로 pkexec는 우리의 로컬 폴더에서 더미 파일 exp_exe를 찾고 GCONV_PATH=./exp_exe 경로를 반환합니다. argc 버그로 인해 이 경로는 다시 envp[0]에 기록되어 GCONV_PATH 변수를 "합법화"합니다.
프로그램을 실행하기 전에 pkexec는 환경 변수(SHELL 포함)를 검사합니다. 우리는 오류를 유발하기 위해 존재하지 않는 셸(SHELL=xyz)을 전달합니다. 오류를 출력할 때 glibc 메커니즘을 사용하는 log_message가 호출됩니다. Glibc는 CHARSET=bohemcavanna 변수를 확인하고, 표준 컨버터를 찾지 못하면 GCONV_PATH의 디렉터리(우리가 몰래 넣은 것)에 접근합니다. 그곳에서 gconv-modules 파일을 읽고, 우리의 라이브러리 exploit.so를 로드하며, 그 내부의 코드를 root 권한으로 실행합니다.