[하루한줄] CVE-2022-21999: Windows Print Spooler 권한 상승 취약점

URL

SpoolFool: Windows Print Spooler Privilege Escalation (CVE-2022-21999)

Target

  • Windows 기반 시스템

Explain

Windows Workstation 및 Server에 기본적으로 제공되는 구성 요소인 Print Spooler에서 권한 상승 취약점이 발견되었습니다. 해당 취약점은 CVE-2020-1030 패치를 두 번 우회하여 동작합니다.

문서를 프린트할 때 미리 정의된 ‘spool directory’ 위치에 프린트 작업이 spool 됩니다. spool directory는 각 프린터에서 구성할 수 있고 모든 사용자에게 FILE_ADD_FILE 권한을 허용해야 합니다. spool directory는 프린터 레지스트리 키 HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Printers\<printer>SpoolDirectory로 정의됩니다.

Print Spooler는 데이터를 관리하기 위해 EnumPrinterData, GetPrinterData, SetPrinterData, DeletePrinterData와 같은 API를 제공합니다. SetPrinterDataEx를 사용하여 프린터 구성을 수정할 수 있습니다. 이 함수를 사용하기 위해서 PRINTER_ACCESS_ADMINISTER 권한이 필요합니다.

PRINTER_ACCES_ADMINISTER 권한을 가진 프린터를 열거나 생성할 때 SpoolDirectory를 수정할 수 있습니다. SetPrinterDataEx가 호출되면 localspl.dll!SplSetPrinterDataExSYSTEM 콘텍스트를 복구하고 localspl.dll!SplRegSetValue를 통해 레지스트리를 수정하기 전에 권한을 검사합니다.

CVE-2020-1030에 대한 패치로 인해 SpoolDirectory 값을 설정할 때 localspl.dll!SplSetPrinterDataEx는 레지스트리 키를 업데이트하기 전 localspl.dll!IsValidSpoolDirectory를 통해 유효한 디렉터리인지 확인합니다.

localspl.dll!IsValidSpoolDirecotrylocalspl.dll!AdjustFileName을 통해 경로를 canonical path로 변환합니다.(ex. C:\spooldir\ -> \\?\C:\spooldir\) 그 후 localspl.dll!IsValidSpoolDirectory는 현재 사용자가 GENERIC_WRITE 권한으로 디렉터리를 생성하거나 열 수 있는지 확인합니다. 권한을 가지고 있는 경우 디렉터리 링크 수가 1보다 크지 않은지 확인합니다.

유효성 검사가 성공하면 print provider는 프린터의 SpoolDirectory 레지스트리 값을 수정합니다. 이때 유효성 검사를 진행하는 동안 디렉터리를 생성하여 권한 상승을 할 수 있습니다. CopyFiles 레지스트리 키를 가지고 SetPrinterDataEx를 호출하면 Spooler가 자동으로 모듈 값에 할당된 DLL을 자동으로 로드합니다. pszKeyName 인자가 CopyFiles\ 문자열로 시작하면 localspl.dll!SplCopyFileEvent가 호출되어 레지스트리 키 값을 읽고 유효성 검사를 수행한 후 LoadLibrary를 사용하여 모듈 로드를 시도합니다.

유효성 검사를 진행할 때, 프린터 드라이버 디렉터리인 C:\Windows\System32\spool\drivers\x64\는 하위 디렉터리의 파일 또한 유효성 검사를 통과합니다. 이를 통해 프린터 드라이버 디렉터리에 악성 DLL을 Spooler 서비스로 로드하여 관리자 권한 생성 등의 악용이 가능합니다.