分離ユーザー モード (IUM) プロセス
Windows 10仮想セキュア モード (VSM) という名前の新しいセキュリティ機能が導入されました。 VSM では、Hyper-V ハイパーバイザーと第 2 レベル アドレス変換 (SLAT) を利用して、仮想信頼レベル (VTL) と呼ばれる一連のモードを作成します。 この新しいソフトウェア アーキテクチャでは、ある VTL で実行されているプロセスが別の VTL のメモリにアクセスできないようにするためのセキュリティ境界が作成されます。 この分離の利点には、パスワード ハッシュや Kerberos キーなどの資産を保護しながら、カーネルの悪用による追加の軽減策が含まれます。
図 1 は、CPU リング 0 とリング 3 で実行されているカーネル モードとユーザー モード コードの従来のモデルを示しています。 この新しいモデルでは、従来のモデルで実行されているコードは VTL0 で実行され、セキュリティで保護されたカーネルと分離ユーザー モード (IUM) によってコードが実行される、より高い特権を持つ VTL1 にアクセスすることはできません。 VTL は階層的です。つまり、VTL1 で実行されているコードは、VTL0 で実行されているコードよりも特権が高くなります。
VTL 分離は、第 2 レベル アドレス変換 (SLAT) を使用して起動時にメモリを割り当てる Hyper-V ハイパーバイザーによって作成されます。 これはシステムの実行中に動的に続行され、セキュリティで保護されたカーネルが VTL0 からの保護を必要とすることを指定したメモリを保護します。これは、シークレットを格納するために使用されるためです。 2 つの VTL に個別のメモリ ブロックが割り当てられるため、VTL1 に対して適切なアクセス許可を持つ VTL1 と VTL0 に排他的メモリ ブロックを割り当てることによって、セキュリティで保護されたランタイム環境が作成されます。
図 1 - IUM アーキテクチャ
Trustlets
トラストレット (信頼されたプロセス、セキュリティで保護されたプロセス、または IUM プロセスとも呼ばれます) は、VSM で IUM プロセスとして実行されるプログラムです。 VTL0 リング 0 で実行されている Windows カーネルにマーシャリングすることで、システム呼び出しを完了します。 VSM は、VTL1 で実行される小さな Secure Kernel を含む小さな実行環境を作成します (VTL0 で実行されているカーネルとドライバーから分離されます)。 明確なセキュリティ上の利点は、VTL1 の trustlet ユーザー モード ページと VTL0 カーネルで実行されているドライバーの分離です。 VTL0 のカーネル モードがマルウェアによって侵害された場合でも、IUM プロセス ページにアクセスすることはできません。
VSM を有効にすると、ローカル セキュリティ機関 (LSASS) 環境が trustlet として実行されます。 LSASS は、パスワード ハッシュや Kerberos キーなどの機密セキュリティ データを処理しながら、ローカル システム ポリシー、ユーザー認証、監査を管理します。 VSM のセキュリティ上の利点を活用するために、LSAISO.exe (LSA Isolated) という名前のトラストレットは VTL1 で実行され、RPC チャネルを介して VTL0 で実行されているLSASS.exeと通信します。 LSAISO シークレットは、VSM 標準モードで実行されている LSASS に送信する前に暗号化され、LSAISO のページは VTL0 で実行されている悪意のあるコードから保護されます。
図 2 – LSASS Trustlet の設計
分離ユーザー モード (IUM) への影響
VTL1 コードをデバッグする機能を妨げる IUM プロセスにアタッチすることはできません。 これには、メモリ ダンプの事後デバッグと、ライブ デバッグ用のデバッグ ツールのアタッチが含まれます。 また、特権アカウントまたはカーネル ドライバーによる IUM プロセスへの DLL の読み込み、スレッドの挿入、またはユーザー モード APC の配信の試行も含まれます。 このような試行により、システム全体が不安定になる可能性があります。 Trustlet のセキュリティを侵害する Windows API は、予期しない方法で失敗する可能性があります。 たとえば、DLL を Trustlet に読み込むと、VTL0 では使用できますが、VTL1 では使用できません。 ターゲット スレッドが Trustlet 内にある場合、QueueUserApc がサイレント モードで失敗する可能性があります。 CreateRemoteThread、VirtualAllocEx、Read/WriteProcessMemory などの他の API も、Trustlets に対して使用すると期待どおりに機能しません。
IUM プロセスにコードをアタッチまたは挿入しようとする関数を呼び出さないようにするには、次のサンプル コードを使用します。 これには、trustlet でコードを実行するために APC をキューに入れたカーネル ドライバーが含まれます。
解説
IsSecureProcess の戻り状態が成功した場合は、SecureProcess _Out_ パラメーターを調べて、プロセスが IUM プロセスであるかどうかを判断します。 IUM プロセスは、システムによって "セキュリティで保護されたプロセス" としてマークされます。 TRUE のブール値の結果は、ターゲット プロセスが IUM 型であることを意味します。
NTSTATUS
IsSecureProcess(
_In_ HANDLE ProcessHandle,
_Out_ BOOLEAN *SecureProcess
)
{
NTSTATUS status;
// definition included in ntddk.h
PROCESS_EXTENDED_BASIC_INFORMATION extendedInfo = {0};
PAGED_CODE();
extendedInfo.Size = sizeof(extendedInfo);
// Query for the process information
status = ZwQueryInformationProcess(
ProcessHandle, ProcessBasicInformation, &extendedInfo,
sizeof(extendedInfo), NULL);
if (NT_SUCCESS(status)) {
*SecureProcess = (BOOLEAN)(extendedInfo.IsSecureProcess != 0);
}
return status;
}
WDK for Windows 10 "Windows Driver Kit - Windows 10.0.15063.0" には、PROCESS_EXTENDED_BASIC_INFORMATION構造体の必要な定義が含まれています。 構造体の更新されたバージョンは、新しい IsSecureProcess フィールドを使用して ntddk.h で定義されます。
typedef struct _PROCESS_EXTENDED_BASIC_INFORMATION {
SIZE_T Size; // Ignored as input, written with structure size on output
PROCESS_BASIC_INFORMATION BasicInfo;
union {
ULONG Flags;
struct {
ULONG IsProtectedProcess : 1;
ULONG IsWow64Process : 1;
ULONG IsProcessDeleting : 1;
ULONG IsCrossSessionCreate : 1;
ULONG IsFrozen : 1;
ULONG IsBackground : 1;
ULONG IsStronglyNamed : 1;
ULONG IsSecureProcess : 1;
ULONG IsSubsystemProcess : 1;
ULONG SpareBits : 23;
} DUMMYSTRUCTNAME;
} DUMMYUNIONNAME;
} PROCESS_EXTENDED_BASIC_INFORMATION, *PPROCESS_EXTENDED_BASIC_INFORMATION;