Introduction
Windows의 커널 암호화 드라이버인 cng.sys에서 발생한 buffer overflow 취약점 CVE-2020-17087을 분석하고 In the Wild에서 쓰였던 버그인 만큼 local privilege escalation까지 도달 할 수 있는 방법을 연구해보려고 한다. 분석은 Windows 10 1909(OS build 18363.418)에서 진행 하였다.
About CNG
MSDN에 따르면 CNG는 기존의 Cryto API를 대체하기 위해서 만들어졌다고 한다. 또한 확장성이 좋게 설계 되었다고 한다. MSDN에서 여러 예제나 사용방법을 확인 할 수 있다.
The Vulnerability
bug class는 16-bit integer truncation로 인한 buffer overflow이다. 해당 취약점은은 IOCTL 0x390400 처리 중 cng!CfgAdtpFormatPropertyBlock에서 발생한다. 해당 루틴은 다음과 같은 call로 호출된다. 다른 드라이버들 처럼 IOCTL에 따라 dispatch하는 루틴을 쉽게 확인 할 수 있다.
call stak
1 | |
cng!CfgAdtpFormatPropertyBlock code snippet
1 | |
위 로직을 보면 BcryptAlloc에서 integer overflow가 발생한다. buffer size는 uint16 type으로 선언 되어있으나 buffersize * 6을 수행했을때 0x10002이나 타입이 uint16이므로 0x2만 남게된다. 아래는 디버깅 결과이다.
1 | |
BcryptoAlloc()의 인자가 2로 세팅된것을 확인 할 수 있다.
추가적으로 overflow가 발생한 상황에서 우리가 원하는 값을 완전히 적을 수 없다. do-while로 감싸진 부분을 보면 input buffer로 들어온 값을 특정 연산을 수행한 후에 output buffer에 적는 것을 확인 할 수 있다.
PoC
1 | |
Exploit Condition
해당 취약점을 사용해서 exploit을 수행해기 위해서는 다음과 같은 제약 조건이 있다.
- overflow는 0x10000~0x5FFFA byte만큼 덮어 쓸 수 있다.
- overflow가 발생하는 buffer는
NonPagedPoolNx를 통해 할당되며 0x2~0xFFFF사이의 크기를 가진다. - 덮여 쓰여지는 값은
XX 00 XX 00 20 00의 형태를 가지며 XX는 0x30~0x39, 0x61~0x66의 범위를 가진다.