포스트

[프로세스와 잡] (안전한 프로세스)

[프로세스와 잡] (안전한 프로세스)
  • 윈도우는 디바이스 가드와 자격증명 가드 같은 새로운 가상화 기반의 보안 기능을 가진다. 이들은 하이퍼바이저를 이용해 운영체제와 유저 데이터의 안전성을 향상시킨다.
  • 이러한 환경은 여전히 비특권 상태(Ring 3)이지만 가상 신뢰 레벨 1(VTL 1)을 가지며, NT 커널(Ring 0)과 애플리케이션(Ring 3) 둘 다가 살아가는 일반적인 VTL 0으로부터 자격증명 가드를 보호한다.

트러스트릿 구조체

  • 트러스트릿은 일반적인 윈도우 이식 가능 실행 파일일지라도 다음과 같은 일부 IUM 특징적인 속성을 가진다.
    • 자신이 이용할 수 있는 시스템 호출의 한정된 번호로 인해 윈도우 시스템 DLL(C/C++ 런타임, KernelBase, Advapi, RPC 런타임, CNG Base Crypto, NTDLL)의 제한적인 것으로부터만 임포트할 수 있다.
    • 트러스트릿이 이용할 수 있는 IUM 한정적인 시스템 DLL로부터 임포트할 수 있다. 이 시스템 DLL은 iumbase로 불리며, 메일슬롯과 스토리지 박스, 암호 등에 대한 지원을 포함한다. 이 라이브러리는 iumdll.dll로 호출하며, 안전한 시스템 호출(안전한 커널에 의해 구현되지만 일반적인 VTL 0 커널로는 전달되지 않는 시스템 호출)을 포함한다.
    • s_IumPolicyMetadata라는 익스포트된 전역변수를 가진 .tPolicy로 불리는 PE 섹션을 포함한다. 이는 안전한 커널이 트러스트릿에 대한 VTL 0 접근을 허용하는 정책 설정을 구현하기 위한 메타데이터 역할을 한다.
    • 격리된 유저 모드 EKU를 포함하는 인증서로 서명된다.
  • 트러스트릿은 IUM 내에서 자신들의 실행을 요청하고, 시작 속성을 지정하기 위해 CreateProcess를 사용할 때 특수한 프로세스 속성을 사용해 시작되어야 한다.

트러스트릿 정책 메타데이터

  • 트러스트릿이 VTL 0으로부터 어떻게 접근 가능할까를 구성하는 다양한 옵션이 정책 메타데이터에 존재한다. 이는 앞서 언급한 s_IumPolicyMetadata에 존재하는 구조체에 의해 기술되며, 버전 번호와 존재하는 트러스트릿 중에서 특정 트러스트릿을 식별하는 고유 번호를 포함한다.
  • 메타데이터는 정책 옵션에 대한 배열을 가진다. 이들 정책은 서명된 실행 파일 데이터의 일부분이므로 이를 변경하려는 시도는 IUM 스명을 무효화시키고 실행을 하지 못하게 막는다.

트러스트릿 속성

  • 트러스트릿을 시작하기 위해 PS_CP_SECURE_PROCESS 속성의 올바른 사용이 요구된다. 이 속성은 호출자가 실제로 트러스트릿의 생성을 원함을 인증하고, 호출자가 실행한다고 트러스트릿이 실제로 실행되는 그 트러스트릿인지를 검증하는 데 사용된다.
  • 이는 정책 메타데이터에 포함된 트러스트릿 ID와 일치하는 트러스트릿 식별자를 속성에 삽입함으로써 이뤄진다.
  • 트러스트릿 속성
    • 메일박스 키: 메일박스 데이터를 회수하기 위해 사용된다. 메일박스는 트러스트릿 키가 알려져 있다면 트러스트릿으로 하여금 VTL 0 세상과 데이터를 공유하게 허용한다.
    • 협업 ID: 안전한 스토리지 IUM API를 사용할 때 사용하는 협업 ID를 설정한다. 안전한 스토리지는 동일한 협업 ID를 가진다면 트러스트릿으로 하여금 서로간에 데이터를 공유하게 허용한다. 협업 ID가 존재하지 않는다면 대신 트러스트릿 인슨턴스 ID가 사용된다.
    • TK 세션 ID: 암호화 동안에 사용되는 세션 ID를 식별한다.

시스템 내장 트러스트릿

  • 윈도우 10은 자신들의 식별 번호에 의해 식별되는 다섯 개의 상이한 트러스트릿을 포함한다. 트러스트릿 ID 0은 안전한 커널 자신을 나타낸다.
바이너리 이름설명정책 옵션
lsaiso.exe자격증명과 키 가드 트러스트릿ETW 허용, 디버깅 비활성화, 암호화된 크래시 덤프 허용
vmsp.exe안전한 가상머신 작업자(vTPM 트러스트릿)ETW 허용, 디버깅 비활성화, 암호화된 크래시 덤프 비활성화, 안전한 스토리지 기능 활성화,
부모 보안 디스크립터가 S-1-5-83-0(NT VIRTUAL MACHINE\Virtual Machine)인지 확인
UnknownvTPM 키 설치 트러스트릿알려지지 않음
bioiso.exe안전한 생체 인식 트러스트릿ETW 허용, 디버깅 비활성화, 암호화된 크래시 덤프 허용
fsiso.exe안전한 프레임 서버 트러스트릿ETW 비활성화, 디버깅 허용, 안전한 섹션 기능 활성화, 시나리오 ID 사용

트러스트릿 신분

  • 트러스트릿은 시스템에서 사용할 수 있는 여러 형태의 신분을 가진다.
    • 트러스트릿 식별자나 트러스트릿 ID: 트러스트릿 정책 메타데이터에 하드코딩된 정수. 이 값은 트러스트릿 프로세스 생성 속성에도 사용된다. 이는 소수의 트러스트릿이 존재하며, 예상하는 트러스트릿을 호출자가 시작하고 있음을 시스템이 인지한다는 것을 보장한다.
    • 트러스트릿 인스턴스: 안전한 커널에 의해 생성되는 암호로, 안전한 16바이트 난수이다. 협업 ID 사용이 없다면 트러스트릿 인스턴스는 안전한 스토리지 API가 자신의 스토리지 블랍에 트러스트릿의 이 인스턴스 하나만이 데이터를 가져오고 넣는 것을 허용함을 보장하는 데 사용된다.
    • 협업 ID: 트러스트릿은 동일하며 안전한 스토리지 블랍에 대한 접근을 공유하기 위해 동일한 ID를 가진 다른 트러스트릿이나 같은 트러스트릿의 다른 인스턴스를 허용할 수 있다. 이 ID가 존재하면 Get 또는 Put API를 호출할 때 트러스트릿의 인스턴스 ID가 무시된다.
    • 보안 버전(SVN): 서명된 암호화 데이터의 출처에 대해 강도 높은 암호적 입증을 요구하는 트러스트릿에 사용된다. 이는 자격증명과 키 가드에 의한 AES256/GCM 데이터를 암호화할 때 사용되고, 암호 보고 서비스에 의해서도 사용된다.
    • 시나리오 ID: 안전한 섹션처럼 이름이 있는 안전한 커널 객체를 생성하는 트러스트릿에 사용된다. 이 GUID는 네임스페이스 내의 이들 객체에 해당 GUID를 태깅함으로써 트러스트릿이 예견된 시나리오의 일부로서 이런 객체를 생성하고 있음을 검증한다. 따라서 동일한 이름의 객체를 오픈하고자 하는 다른 트러스트릿은 동일한 시나리오 ID를 가져야 한다. 하나 이상의 시나리오 ID가 실제로 존재할 수 있지만, 현재는 어떤 트러스트릿도 하나 이상의 ID를 사용하지 않는다.

격리된 유저 모드 서비스

  • 트러스트릿으로 실행하는 이점은 일반적인 세상(VTL 0)으로부터의 공격을 보호하고 안젆란 커널에 의해 트러스트릿에 제공되는 특권화되고 보호된 안전한 시스템 호출에 접근할 수 있다는 점이다.
  • 안전한 장치(IumCreateSecureDevice, IumDmaMapMemory, …)
    • VTL 0에서 접근될 수 없으며, 안전한 커널에 의해 독점적으로 소유된 안전한 ACPI/PCI 장치에 대한 접근을 제공한다.
    • 관련 기능을 가진 트러스트릿은 VTL 1 IUM 내에 이런 장치의 레지스터를 매핑할 수 있으며, 다이렉트 메모리 접근 전송을 잠재적으로 수행할 수 있다.
    • 트러스트릿은 SDFHost.dll에 위치한 안전한 장치 프레임워크를 사용해 이런 하드웨어 용도의 유저 모드 디바이스 드라이버 역할을 할 수 있다.
    • 이런 기능은 안전한 USB 스마트카드나 웹캠/지문 인식 센서 같은 윈도우의 안전한 생체 인식 시스템인 Hello에 이용된다.
  • 안전한 섹션(IumCreateSecureSection, IumFlushSecureSectionBuffers, …)
    • 노출된 안전한 섹션을 통해 물리 페이지를 VTL 0 드라이버와 공유하고, 안전한 섹션으로 명명된 VTL 1 내에서만 데이터를 다른 트러스트릿이나 동일한 트러스트릿의 다른 인스턴스와 공유하는 능력을 제공한다.
    • 이런 기능을 사용하기 위해 트러스트릿 정책 메타데이터의 안전한 섹션 기능을 필요로 한다.
  • 메일박스(IumPostMailbox)
    • 트러스트릿으로 하여금 4KB까지의 데이터에 대해 8개까지의 슬롯을 일반(VTL 0) 커널 내의 컴포넌트와 공유하게 한다.
    • 슬롯 식별자와 비밀 메일박스 키를 전달하면서 VslRetrieveMailbox를 호출할 수 있다.
    • 예를 들어 VTL 0의 vid.sys는 이를 사용해 vmsp.exe 트러스트릿으로부터 vTPM 기능에 의해 사용되는 다양한 비밀 정보를 가져온다.
  • 신분 키(IumGetIdk)
    • 트러스트릿으로 하여금 고유한 복호화 키와 서명 키를 식별하게끔 한다.
    • 이 키는 머신에서 고유한 것으로 트러스트릿으로부터만 구해질 수 있다.
    • 이는 자격증명이 IUM으로부터 온 것과 머신을 고유하게 인증하기 위한 자격증명 가드 기능의 필수적인 부분이다.
  • 암호 서비스(IumCrypto)
    • TPM 바인딩 핸들과 안전한 커널의 FIPS 모드를 구하고, IUM에 대한 안전한 커널에 의해 생성되는 랜덤 번호 생성 시드를 구하기 위해 트러스트릿으로 하여금 IUM에 의해서만 사용 가능한 안전한 커널이 생성한 로컬/부트별 세션 키를 가진 데이터를 암호화하고 복호화하게끔 한다.
    • 암호 서비스를 통해 IDK-서명과 SHA-2 해시, 신분을 가진 타임스탬프 보고서, 트러스트릿의 SVN, 디버거에 연결됐는지에 관계없이 자신의 정책 메타데이터 덤프, 요청된 여타 트러스트릿 제어 데이터를 생성할 수 있다.
    • 이것은 트러스트릿이 조작되지 않았음을 입증하기 위해 트러스트릿에 대한 일종의 TPM 같은 판단 기준으로 사용될 수 있다.
  • 안전한 스토리지(IumSecureStorageGet, IumSecureStoragePut)
    • 안전한 스토리지 기능을 가진 트러스트릿으로 하여금 자신들의 고유한 트러스트릿 인스턴스에 기반을 두거나 다른 트러스트릿과 동일한 협업 ID를 공유함으로써 임의의 크기 스토리지 블랍을 저장하고 추후에 이들을 회수하게끔 한다.

트러스트릿 접근 가능 시스템 호출

  • 안전한 커널은 자신이 공격받을 수 있는 부분과 노출을 최소화하려고 하므로 일반 애플리케이션이 사용할 수 있는 수백 개의 시스템 호출 중 일부만을 제공한다. 이들 시스템 호출은 트러스트릿이 사용할 수 있는 시스템 DLL과 RPC 런타임 및 ETW 트레이싱 지원에 필요한 특정 서비스와의 호환성을 위해 엄격하게 최소한으로 필수적인 것이다.
    • 파일이나 실제 물리 장치이든 간에 디바이스 I/O와 같은 동작은 불가능하다. (우선 CreateFile API가 존재하지 않음)
    • 프로세스의 생성이나 이런 저런 종류의그래픽 API 사용도 불가능하다. (VTL 1 내의 win32k.sys 드라이버가 존재하지 않음)
  • 트러스트릿은 ALPC 통신 메커니즘이나 노출된 안전한 섹션만을 갖는 자신의 복잡한 전면에서 격리된 배후의 작업자 역할을 한다.
안전한 프로세스 식별하기
  • 안전한 프로세스는 커널 디버거를 통해 두 가지 방식으로 식별할 수 있다.
  • 안전한 프로세스는 안전한 PID를 가진다. 이 PID는 프로세스에 스레드를 생성하거나 자신의 종료를 요청할 때 일반 커널(VTL 0)에 의해 사용된다.
  • 스레드 자신은 자신들과 연관된 스레드 쿠키를 가진다. 이는 안전한 커널 스레드 테이블에서 자신드르이 인덱스를 나타낸다.
  • 커널 디버거에서 다음과 같이 시도해보자.
    • !for_each_process .if @@(((nt!_EPROCESS*)${@#Process})->Pcb.SecurePid) {.printf "Trustlet: %ma (%p)\n", @@(((nt!_EPROCESS*)${@#Process})->ImageFileName), @#Process }
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.