独立用户模式 (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 虚拟机监控程序创建,该虚拟机监控程序使用二级地址转换 (SLAT) 在启动时分配内存。 它会在系统运行时动态地继续此操作,保护安全内核指定的内存需要从 VTL0 进行保护,因为它将用于包含机密。 由于为两个 VTL 分配单独的内存块,因此为 VTL1 创建一个安全运行时环境,方法是将独占内存块分配给 VTL1 和具有适当访问权限的 VTL0。

图 1 - IUM 体系结构

diagram 1 - ium architecture

Trustlet

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

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

图 2 - LSASS Trustlet 设计

diagram 2 – lsass trustlet design

独立用户模式 (IUM) 含义

无法附加到 IUM 进程,从而抑制调试 VTL1 代码的能力。 这包括帖子内存转储的验尸调试,以及附加调试工具进行实时调试。 它还包括特权帐户或内核驱动程序尝试将 DLL 加载到 IUM 进程、注入线程或传送用户模式 APC。 这种尝试可能导致整个系统的不稳定。 Windows可能以意外方式破坏 Trustlet 安全性的 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结构所需的定义。 新 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;