CPU-Z 커널 드라이버에 대한 로컬 권한 에스컬레이션 악용.
CPU-Z 응용 프로그램은 Usermode에서 커널 데이터에 액세스하기 위해 취약한 서명 드라이버를 설치합니다. v1.81 이전에 CPU-Z 드라이버는 usermode 응용 프로그램이 제어 레지스터를 읽고 물리적 메모리에서 DWORDS를 읽고 DWORDS를 물리적 메모리에 기록하는 3 개의 IOCTL을 노출했습니다. 우리는이 기능을 남용하여 전체 커널 모드 코드 실행을 얻고 개념 증명으로 시스템 쉘을 생성합니다.
이 악용은 Windows XP -Windows 10 1607을 지원합니다.
이 악용은 CPU-Z v1.76을 사용하여 다음 시스템에서 테스트되었습니다.
* Windows 1703 이상에서 CFG (Cernel Control Flow Guard)는 기본적으로 [1]을 활성화하여 Kernel_security_check_failure 버그 확인을 초래합니다.
이 익스플로잇을 실행하려면 CPU-Z 응용 프로그램을 시작하고 일반 사용자로 명령 프롬프트에서 exploit.exe를 실행하십시오. 성공하면 시스템으로 실행되는 새로운 CMD.exe 프로세스를 스폰해야합니다. NTQuerySystemInformation의 사용으로 인해 저지성 프로세스에서 실행되면이 악용이 실패합니다.
v1.81 이전의 CPU-Z 커널 드라이버를 사용하면 Usermode 응용 프로그램을 통해 제어 레지스터를 읽고 물리적 메모리에서 DWORDS를 읽고 DWORDS를 물리적 메모리에 씁니다. 우리는이 기능을 남용하여 전체 가상 메모리 공간에 임의의 읽기/쓰기 프리미티브를 구축하기 위해 CR3을 읽고 페이지 테이블을 통과합니다.
전체 읽기/쓰기를 사용하면 SMEP (Supervisor Mode Execution Prevention)를 우회하기 위해 페이로드가 포함 된 PTE (Page Table Entry)의 사용자/감독자 비트를 뒤집습니다. 그런 다음 nt! haldispatchtable [1]에서 함수 포인터를 덮어 쓰고 ntqueryintervalprofile을 호출하여 페이로드를 트리거합니다.
개념 증명으로 페이로드는 시스템 토큰을 일시 중단 된 CMD.EXE 프로세스에 할당하고 프로세스를 재개합니다. 이로 인해 NT Authority/System으로 새로운 명령 프롬프트가 발생해야합니다. 페이로드는 정적 오프셋에 의존하지 않으므로 Windows XP+에서 작동해야합니다.
지난 2 년 동안이 악용의 효과를 제한하는 다수의 완화가 도입되었습니다. 간단한 설명은 다음과 같습니다.
버전 1.81 현재 CPU-Z와 함께 제공되는 드라이버는 장치 객체를 열 수있는 발신자 세트를 제한하여 일부 IOCTL 구현이 제거되었습니다. 드라이버 장치 객체를 열도록 요청하면 현재 프로세스에 SeloaddriverPrivilege가 활성화되어 있는지 확인합니다. 이 특권이 누락되거나 비활성화되면 운전자는 status_access_denied로 요청을 거부합니다. 관리자로 실행할 때는 Usermode에서 이러한 권한을 제공하는 것이 사소한 일입니다. 또한, 제어 레지스터를 읽기위한 IOCTL이 제거되었습니다 (물리적 메모리 읽기/쓰기 구현은 남아 있지만). CR3에서 페이지 테이블베이스를 읽을 수 없으면이 프로젝트의 악용 방법을 더 이상 실현할 수 없습니다. CPU-Z 드라이버는 자의적 모델 별 레지스터를 읽거나 쓰는 등 악용에 사용할 수있는 수많은 다른 IOCTL을 제공합니다.
Windows 10 1703 (Creators Update)에서 커널 제어 흐름 가드는 기본적으로 x86_64에서 활성화됩니다. HaldisPatchTable을 통한 통화는 CFG에 의해 보호되므로 Kernel_security_check_failure 버그 점검을 초래합니다. 가상화 기반 보안 (VBS)이 활성화되지 않은 경우 CFG를 우회하기 위해 유효한 통화 대상으로 페이로드를 추가 할 수 있어야합니다.
가상화 기반 보안 (VBS)이 활성화되면이 악용의 대부분을 죽일 것입니다. PTE가 하이퍼 바이저에 의해 보호되므로 SMEP를 비활성화하는 데 사용되는 PTE 조작은 더 이상 불가능합니다. 또한, 커널 CFG 비트 맵은 쓸 수 없으므로 HaldisPatchTable을 통해 코드 실행을 얻으려면 X86_64에서 CFG 바이 패스가 필요합니다.
이 악용에 사용 된 취약점은 CVE-2017-15302 및 CVE-2017-15303에 자세히 설명되어 있습니다. 또 다른 개념 증명은 CPUZ-DSEFIX [5]에서 볼 수 있습니다.
[1] https://community.osr.com/discussion/283374/control-flow-guard-question
[2] https://www.cvedetails.com/cve/cve-2017-15302/
[3] https://www.cvedetails.com/cve/cve-2017-15303/
[4] https://github.com/akayn/bugs/blob/master/cpuid/cve-2017-15302/readme.md
[5] https://github.com/samlarenn/cpuz-dsefix
또한,이 익스플로잇에 사용 된 HaldisPatchTable 초과 쓰기 방법은 일반적으로 사용되는 벡터로서 커널 읽기/쓰기 프리미티브에서 코드 실행을 얻습니다. 이 기술에 대한 자세한 내용은 아래 리소스를 참조하십시오.
[6] http://poppopret.blogspot.com/2011/07/windows-kernel-exploitation-basics-part.html
[7] https://www.abatchy.com/2018/01/kernel-exploitation-7
[8] https://osandamalith.com/2017/06/14/windows-kernel-exploitation-arbitrary-overwrite/
[9] https://rootkits.xyz/blog/2017/09/kernel-write-whate-where/