[하루한줄] CVE-2021-1647: Windows Defender MpEngine 모듈의 RCE 취약점

URL

Analysis of CVE-2021-1647 vulnerability exploitation techniques

Target

Microsoft Malware Protection Engine ≤ 1.1.17600.5

Explain

실제 해커들이 활발하게 악용하고 있는 것으로 확인된 Windows Defender의 원격 코드 실행 취약점의 세부 정보가 공개되었습니다.

취약점은 Asprotect로 패킹된 PE 파일을 압축 해제하는 CAsprotectDLLAndVersion::RetrieveVersionInfoAndCreateObjects 함수에 존재합니다.

...
for (i = (unsigned int *)((char *)v2 + 28); ; i += 2 )
{
	if ( v28 >= 3 )
		v83 = (*((_DWORD *)v2 + 14) + 4095) & 0xFFFFF000;
		sectionindex = i64; 
		v33 = (_DWORD ((char *)v2 + 32); 
		v34 = (__int64) v2 + 32; 
		while ( sectionindex < 4 )
		{
			if (*(_DWORD *)(v34 - 4) & 0xFFF )
				goto LABEL_123; 
			if (*(_DWORD *)(v34 - 4) > sectionva )
			{
				sectionva = *(_DWORD *)(v34 - 4); 
				sectionsize = (*(_DWORD *)v34 + 4095) & 0xFFFFF000;
			}
			v35 = v82[sectionindex++]; 
			V34 += 8i64; 
			if ( v35 <= v27 )
				v35 = v27;
			v27 = v35;
		}
...

섹션 배열 v2 + 28에는 8 bytes 크기인 4개의 배열 요소가 있습니다. 첫 4 bytes는 섹션의 virtual address를 나타내는 sectionva이며 마지막 4 bytes는 섹션의 크기를 나타내는 sectionsize입니다. 해당 함수는 sectionsizesectionva 를 구한 뒤 이 둘을 더한 크기의 메모리를 할당해 압축 해제된 섹션을 저장합니다. 그러나 sectionva 크기가 이전 sectionva 크기와 같은 경우를 고려하지 않아 취약점이 발생합니다.

섹션 배열이 [0,0], [0,0], [0x2000,0], [0x2000,0x3000] 로 마지막 sectionva와 이전 sectionva 값이 같은 경우 할당된 메모리는 0x2000 + 0 = 0x2000 가 되어 마지막 sectionsize0x3000 크기 섹션의 압축을 풀 때 heap overflow가 발생합니다.

해당 취약점을 악용하면 객체와 포인터 필드를 조작해 arbitrary read/write를 트리거할 수 있고 원격 코드 실행까지 이어질 수 있습니다. 또한 Windows Defender의 파일 스캔 과정에서 트리거 되므로 단순히 해커가 제작한 악성 파일을 다운로드하기만 해도 트리거가 가능한 점에서 심각한 취약점으로 평가되었습니다.