[하루한줄] CVE-2021-26863: race condition을 통한 win32k 커널 UAF 취약점
URL
Target
- win32k kernel
Explain
Google Project Zero팀이 Windows Kernel에서 발생하는 race condition을 통한 UAF 취약점의 세부 보고서를 공개했습니다.
취약점이 존재하는 NtGdiGetDeviceCapsAll
함수는 GDI에서 내부적으로 사용하는 system call입니다.
...
BOOL NtGdiGetDeviceCapsAll(HDC hdc, DEVCAPS *devcaps) {
BOOL bRet = TRUE;
PDEVOBJ *pdevobj;
if (PsGetWin32KFilterSet() == 5 && hdc == 0xFFFFFFFFDCDE5000) {
pdevobj = gpDispInfo->pdevobj;
// DCOBJ scope
} else {
DCOBJ dc(hdc); //[1]
if (!dc.valid) {
EngSetLastError(ERROR_INVALID_HANDLE);
DCOBJ::~DCOBJ(dc);
return FALSE;
}
pdevobj = dc.pdevobj;
DCOBJ::~DCOBJ(dc);
}
// DCOBJ scope
__try {
ProbeForWrite(devcaps, sizeof(DEVCAPS), 1);
vGetDeviceCaps(pdevobj, devcaps); //[2]
}except(EXCEPTION_EXECUTE_HANDLER) {
bRet = FALSE;
}
return bRet;
}
...
해당 함수는 Device Context(DC) 핸들을 얻어 장치 정보를 DEVCAPS
구조체에 저장하는 기능을 수행합니다.
DCOBJ
객체인 dc
를 else
문 내부에서 선언해 해당 객체의 scope가 else
문으로 한정됩니다. 또한 객체가 syscall 전체에서 활성화된 상태를 유지할 수 있는 메커니즘이 존재하지 않아 else
코드를 벗어나면 DCOBJ::~DCOBJ(dc)
소멸자가 자동으로 호출되어 dc
에 대한 참조가 삭제됩니다. 결과적으로 dc
를 참조하는 pdevobj
객체가 race condition의 영향을 받습니다.
위 취약점을 악용해 [1]에서 DCOBJ
생성자에 의해 참조된 이후 다른 스레드가 [2]에서 vGetDeviceCaps()
호출 전 또는 도중 Device Context
를 닫는 경우 해제된 메모리에 액세스 할 수 있습니다.
본 글은 CC BY-SA 4.0 라이선스로 배포됩니다. 공유 또는 변경 시 반드시 출처를 남겨주시기 바랍니다.