隔离用户模式 (IUM) 进程

Windows 10引入了名为虚拟安全模式的新安全功能 (VSM) 。 VSM 利用 Hyper-V 虚拟机监控程序和二级地址转换 (SLAT) 创建一组称为虚拟信任级别的模式, (VTL) 。 这个新的软件体系结构创建了一个安全边界,以防止在一个 VTL 中运行的进程访问另一个 VTL 的内存。 这种隔离的好处包括进一步缓解内核攻击,同时保护密码哈希和 Kerberos 密钥等资产。

图 1 分别描述了内核模式和 CPU 环 0 和环 3 中运行的用户模式代码的传统模型。 在此新模型中,传统模型中运行的代码在 VTL0 中执行,并且无法访问更高特权的 VTL1,其中安全内核和隔离用户模式 (IUM) 执行代码。 VTL 是层次结构,这意味着在 VTL1 中运行的任何代码比在 VTL0 中运行的代码具有更高的特权。

VTL 隔离由 Hyper-V 虚拟机监控程序创建,Hyper-V 虚拟机监控程序在启动时使用二级地址转换 (SLAT) 分配内存。 它在系统运行时会动态地继续,保护安全内核指定需要 VTL0 保护的内存,因为它将用于包含机密。 由于为两个 VTL 分配了单独的内存块,因此,通过向具有适当访问权限的 VTL1 和 VTL0 分配独占内存块,为 VTL1 创建安全运行时环境。

图 1 - IUM 体系结构

图 1 - ium 体系结构

Trustlets

信任 (也称为受信任进程、安全进程或 IUM 进程) 是作为 VSM 中的 IUM 进程运行的程序。 它们通过将系统调用封送到 VTL0 环 0 中运行的 Windows 内核来完成系统调用。 VSM 创建一个小型执行环境,其中包括在 VTL1 中执行的小型安全内核, (与 VTL0) 中运行的内核和驱动程序隔离。 明显的安全优势是将 VTL1 中的 trustlet 用户模式页与 VTL0 内核中运行的驱动程序隔离。 即使 VTL0 的内核模式被恶意软件入侵,它也无法访问 IUM 进程页面。

启用 VSM 后,本地安全机构 (LSASS) 环境作为 trustlet 运行。 LSASS 管理本地系统策略、用户身份验证和审核,同时处理密码哈希和 Kerberos 密钥等敏感安全数据。 为了利用 VSM 的安全优势,名为 LSAISO.exe (LSA 隔离) 在 VTL1 中运行的 trustlet,并通过 RPC 通道与在 VTL0 中运行的LSASS.exe通信。 在将 LSAISO 机密发送到在 VSM 正常模式下运行的 LSASS 之前,会对 LSAISO 机密进行加密,并且 LSAISO 的页面免受 VTL0 中运行的恶意代码的影响。

图 2 - LSASS Trustlet 设计

图 2 - lsass trustlet 设计

独立用户模式 (IUM) 影响

无法附加到 IUM 进程,因此无法调试 VTL1 代码。 这包括内存转储的事后调试和附加用于实时调试的调试工具。 它还包括特权帐户或内核驱动程序尝试将 DLL 加载到 IUM 进程、注入线程或传送用户模式 APC。 这种企图可能导致整个系统的不稳定。 会危及 Trustlet 安全性的 Windows API 可能会以意外方式失败。 例如,将 DLL 加载到 Trustlet 将使它在 VTL0 中可用,但在 VTL1 中不可用。 如果目标线程位于 Trustlet 中,QueueUserApc 可能会以无提示方式失败。 其他 API(如 CreateRemoteThread、VirtualAllocEx 和 Read/WriteProcessMemory)在针对 Trustlet 使用时也不会按预期工作。

使用下面的示例代码阻止调用任何尝试将代码附加或注入到 IUM 进程中的函数。 这包括将 APC 排队以执行 trustlet 中的代码的内核驱动程序。

备注

如果 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;
}

Windows 10的 WDK“Windows 驱动程序工具包 - Windows 10.0.15063.0”包含PROCESS_EXTENDED_BASIC_INFORMATION结构的必需定义。 结构的更新版本在 ntddk.h 中使用新的 IsSecureProcess 字段定义。

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;