보안동향

최신 보안정보를 신속하게 전해드립니다.

[보안동향] CVE-2017-5123 Linux Kernel waitid system call privilege escalation

2019-11-25

개요

waitid는 fork()로 생성된 프로세스의 상태 변화에 따른 제어를 위한 함수이며 waitid system call 의

unsafe_put_user 함수 취약점과 have_canfork_callback을 이용해 root 권한을 획득할 수 있습니다.

 

취약한 버전

4.12 < Linux Kernel <= 4.14.0-rc+

 

취약점 설명 및 분석

waitid() 는 아래와 같이 정의되어 있습니다.

 

취약점이 발생하는 인자는 siginfo_t *infop 이며 siginfo_t 구조체는 아래와 같습니다.

 

waitid syscall call을 처리하는 코드를 보면 infop 인자에 대해 access_ok() 함수가 누락되어

있는것을 확인할 수 있습니다.

 

access_ok() 함수는 주소에 대해 유저 영역의 주소인지 커널 영역의 주소인지를 확인하는 함수 입니다.

해당 함수가 호출되면 SMAP 보호기법이 발동되며 유저 영역에서 커널 영역 주소를 사용할 수 없습니다.

즉, unsafe_put_user 함수를 통해 임의의 커널 주소에 특정 값을 덮어쓸 수 있습니다.

 

또한, infop이 참조할 수 있는 유효한 주소를 가리킨다면 EFAULT를 반환하지 않기 때문에 계속된

waitid system call 호출로 kernel의 base address를 알아낼 수 있으며 KASLR을 우회할 수 있습니다.

 

아래와 같은 코드를 작성해 kernel의 base address를 구할 수 있습니다.

 

kernel의 base address를 구하면 root 자격증명을 위한 prepare_kernel_cred, commit_creds

함수의 주소를 구할 수 있습니다.

 

하지만 아래 put_user의 코드와 같이 unsafe_put_user함수로 인해 Arbitrary write 는 발생하지만

덮어쓰는 값을 제어할 수는 없습니다.

 

입력하는 값을 제어할 수 없으므로 have_canfork_callback과 null pointer dereference를 이용합니다.

 

fork() 함수의 간략한 프로세스는 다음과 같습니다.

fork() -> do_fork() -> copy_process() -> cgroup_can_fork() -> do_each_subsys_mask()

-> for_each_set_bit() -> find_first_bit() -> ......

 

cgroup_can_fork 함수는 아래와 같고 do_each_subsys_mask함수의 인자로 have_canfork_callback

전역 변수를 사용하며 for_each_set_bit 함수는 have_canfork_callback 변수에 설정된 값을 검사합니다.

 

위의 프로세스를 asm언어로 확인해보면 아래와 같습니다. have_canfork_callback 변수를 인자로

find_first_bit함수를 호출하고 해당 함수의 결과값을 3과 비교하여 3보다 크면 0xffffffff810e021e로

jmp하게 됩니다.

 

unsafe_put_user 함수는 infop 주소의 첫번째 bit에 0x11을 설정합니다. 해당 값을 설정하면

find_first_bit 함수의 결과값은 0이 되어 call 0x0 을 만들어낼 수 있습니다.

 

mmap을 이용해 0x0 주소를 할당하고 해당 영역에 shellcode를 삽입한 후 call 0x0으로 root 권한을

획득할 수 있습니다.

 

해당 취약점은 access_ok() 함수의 누락이 문제가 되었기 때문에 access_ok() 함수를 추가하는

것으로 보안 패치가 되었습니다.

 

위협요소

공격자가 일반 사용자의 계정으로 서버의 root 권한을 획득할 수 있습니다. 서버의 root 권한을

탈취당하면 공격자가 서버를 완벽히 제어할 수 있으므로 빠른 보안패치 업데이트가 필요합니다.

 

대응방안

1) Kernel Version 업데이트

 

 

 

 

목록