[하루한줄] CVE-2021-1732: win32kfull.sys 0-day

URL

WINDOWS KERNEL ZERO-DAY EXPLOIT (CVE-2021-1732) IS USED BY BITTER APT IN TARGETED ATTACK

Target

Windows10 1709 ~ 1909 64-bits

Explain

DBAPPSecurity Threat Intelligence가 작년 12월에 BITTER APT의 새로운 컴포넌트를 분석해 win32kfull.sys에서 발생하는 취약점(CVE-2021-1732)을 발견했습니다. CVE-2021-1732는 win32kfull 콜백에 의해 발생하는 System 권한 상승 취약점으로 IE browser, Adobe Reader 등의 sandbox escape에 사용될 수 있습니다.

취약점(out-of-bound access)은 win32kfull!xxxCreateWindowEx가 콜백 함수 xxxClientAllocWindowClassExtraBytes를 호출한 후, 커널 구조 멤버에 대한 설정과 flag값이 서로 상응하지 않을 때 발생합니다.

win32kfull!xxxCreateWindowExWndExtra 영역을 갖는 새로운 창을 만들 때 콜백 함수 user32!_xxxClientAllocWindowClassExtraBytes를 호출해 WndExtra를 할당합니다. 그 후 할당된 WndExtra의 유저 모드 포인터를 반환받아 WndExtra 멤버에 저장합니다.

만약 커스텀 콜백 _xxxClientAllocWindowClassExtraBytes에서 win32kfull!ConsoleControl을 호출해 현재 창에 대한 핸들을 받으면 저장된 WndExtra 멤버를 오프셋으로 변환합니다. 또한 그에 맞게 flag는 현재 멤버가 오프셋임을 나타내도록(0x800) 값이 변경됩니다.

커스텀 콜백이 끝난 직후 NtCallbackReturn를 통해 임의의 값(fake_offset)을 win32kfull!xxxCreateWindowEx에 반환하면 WndExtra 멤버를 해당 반환 값으로 오염시킬 수 있습니다. 하지만 flag값은 여전히 WndExtra 멤버가 오프셋임을 나타내기 때문에 커널 힙 해제 시 발생하는 분기에 영향을 미치게 됩니다.

win32kfull!xxxFreeWindow

  1. Flag값 설정됨

    오프셋을 통해 WndExtra를 free 하는 RtlFreeHeap 호출

  2. Flag가 설정되지 않음

    유저 모드 포인터와 xxxClientFreeWindowClassExtraBytes를 통해 WndExtra를 free

RtlFeeHeap은 Base+offset이 아닌 Base+fake_offset을 free 하게 됩니다.