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의 범위를 가진다.