UAC 的目标

UAC 旨在使用户能够使用标准用户权限(而不是管理权限)运行。管理权限使用户能够读取和修改操作系统的任何部份,包括其他用户的代码和数据 — 甚至是 Windows® 本身。如果没有管理权限,用户不会意外(或有意)修改系统设置,恶意软件无法改变系统安全设置或禁用防病毒软件,用户也不会危及共享计算机上其他用户敏感 信息的安全。因此,使用标准用户权限运行可以减少企业环境中紧急咨询台呼叫的次数,减轻恶意软件的影响,使家庭计算机的运行更顺畅,并保护共享计算机上的 敏感数据。

要使通过标准用户帐户运行切实可行,UAC 必须要解决几个问题。首先,在 Windows Vista™ 之前,Windows 使用模型一直是某种假定的管理权限。软件开发人员假定他们的程序可以访问和修改任何文件、注册表或操作系统设置。甚至当 Windows NT® 引入了安全性并区分了授予管理用户帐户和标准用户帐户的权限后,仍指导用户完成一个设置过程,使他们能够使用内置的 Administrator 帐户或 Administrators 组的成员帐户。

UAC 必须解决的第二个问题是用户有时需要管理权限来执行某些操作,如安装软件、更改系统时间以及在防火墙中打开端口。

UAC 针对这些问题的解决方案是使用标准用户权限运行大多数应用程序,始终避免对管理员权限的需要,并鼓励软件开发人员创建使用标准用户权限运行的应用程序。 UAC 通过以下方式来实现这些方面:减少对管理权限的需求频率,使旧应用程序能够使用标准用户权限运行,使标准用户在需要时能够方便地访问管理权限,甚至使管理 用户像标准用户那样运行。


作为标准用户运行

在 Windows Vista 的开发过程中,通过对所有管理操作的全面审核,确定了许多可以为标准用户启用而不会有损系统安全性的操作。例如,即使是为其 Windows XP 桌面系统采用了标准用户帐户的企业也无法从 Administrators 组中删除其移动用户,唯一的原因是 Windows XP 并不区分更改时区与更改系统时间之间的差别。如果便携式计算机用户希望配置本地时区以便旅行时能够在其日历中正确显示预约时间,他们必须具有“更改系统时 间”特权(在内部称为 SeSystemTimePrivilege),在默认情况下该特权仅授予管理员。

安全协议(如 Kerberos)中通常会使用时间,但是时区仅影响时间的显示方式,因此 Windows Vista 添加了一个新特权“更改时区”(SeTimeZonePrivilege),并将其分配给 Users 组,如图 1 所示。这样许多企业便有可能使其便携式计算机用户在标准用户帐户下运行。

图 1 “更改时区”特权
图 1 “更改时区”特权 (单击该图像获得较大视图)

Windows Vista 还允许标准用户在连接到无线网络时配置 WEP 设置、创建 VPN 连接、更改电源管理设置以及安装重要 Windows 更新。此外,它还引入了“组策略”设置,使标准用户能够安装 IT 管理员批准的打印机和其他设备驱动程序,以及从管理员批准的站点安装 ActiveX® 控件。

对于不能以标准用户帐户正确运行的客户和业务线 (LOB) 应用程序该如何处理?虽然某些软件确实需要管理权限,但许多程序都毫无必要地将用户数据存储在系统全局位置。Microsoft 建议希望使用管理权限来运行的全局应用程序安装程序在 %ProgramFiles% 目录下创建一个目录来存储应用程序的可执行文件和辅助数据,并在 HKEY_LOCAL_MACHINE\Software 下为其应用程序设置创建一个注册表项。当执行某个应用程序时,它可以使用不同的用户帐户运行,因此它应当在针对每个用户的 %AppData% 目录中存储用户特定数据,并在 HKEY_CURRENT_USER\ Software 下的用户注册表配置文件中保存每个用户的设置。标准用户帐户不具备 %ProgramFiles% 目录或 HKEY_LOCAL_MACHINE\Software 的写访问权限,但是因为多数 Windows 系统都是单用户的,并且在 Windows Vista 之前多数用户都是管理员,所以错误地将用户数据和设置保存到这些位置的应用程序仍能工作。

通过文件系统和注册表命名空间虚拟化的帮助,Windows Vista 使这些旧应用程序能够在标准用户帐户下运行。当应用程序修改文件系统或注册表中的系统全局位置并且该操作由于访问被拒绝而失败时,Windows 会将该操作重定向到特定于用户的区域;当应用程序从某个系统全局位置读取时,Windows 将首先检查每个用户区域中的数据,如果数据不存在,则允许从该全局位置进行读取尝试。

针对此虚拟化目的,如果某个进程是 32 位的(与 64 位相对)、不是使用管理权限运行,并且没有指令清单文件表明它是为 Windows Vista 编写的,那么 Windows Vista 会将其视为旧进程。根据此定义,对于任何操作(包括网络文件共享访问),如果它不是源于分类为旧进程的进程,则不会将其虚拟化。进程的虚拟化状态存储为其 令牌中的一个标志,它是跟踪进程安全环境的内核数据结构,包括其用户帐户、组成员身份和特权。

您可以通过向“任务管理器”的“进程”页添加“虚拟化”栏来查看进程的虚拟化状态。图 2 显示大多数 Windows Vista 组件(包括桌面窗口管理器 (Dwm .exe)、客户端服务器运行时子系统 (Csrss.exe) 和资源管理器)或者因为它们有 Windows Vista 指令清单而禁用了虚拟化,或者是使用管理权限运行而因此不允许虚拟化。Internet Explorer® (iexplore.exe) 启用了虚拟化,因为它可以承载多个 ActiveX 控件和脚本,并且必须假定它们没有编写为使用标准用户权限即可正确操作。

图 2 “任务管理器”显示虚拟化状态
图 2 “任务管理器”显示虚拟化状态 (单击该图像获得较大视图)

为旧进程虚拟化的文件系统位置为 %ProgramFiles%、%ProgramData% 和 %SystemRoot%,其中不包括某些特定子目录。但是,任何具有可执行文件扩展名的文件(包括 .exe、.bat、.scr、.vbs 等等)都将从虚拟化中排除。这意味着,使用标准用户帐户进行自我更新的程序将失败,而不会创建对于运行全局更新程序的管理员不可见的专有可执行文件版本。 要向排除列表中添加其他扩展名,请在以下注册表项中输入它们并重新启动:

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Luafv\Parameters\ExcludedExtensionsAdd 

 

使用一种多字符串类型来分隔多个扩展名,并且不要在扩展名中包含前导点。

旧进程对虚拟化目录的修改将重定向到用户的虚拟根目录 %LocalAppData%\VirtualStore。例如,如果我的系统上运行的某个虚拟化进程要创建 C:\Windows\Application.ini,那么它实际创建的文件为 C:\Users\Markruss\AppData\Local\VirtualStore\Windows\Application.ini。该路径 的本地部分表明这样一个事实,即当帐户具有漫游配置文件时,虚拟化文件不会随配置文件的其余部分漫游。

如果在资源管理器中导航到一个包含虚拟化文件的目录,资源管理器将在其工具栏中显示一个标记为“兼容性文件”的按钮,如图 3 所示。单击该按钮可导航至对应的 VirtualStore 子目录以显示虚拟化文件。

图 3 “兼容性文件”按钮指明了附近的虚拟化文件
图 3 “兼容性文件”按钮指明了附近的虚拟化文件 (单击该图像获得较大视图)

图 4 显示 UAC 文件虚拟化筛选器驱动程序 (%SystemRoot%\System32\Drivers\Luafv.sys) 如何实施文件系统虚拟化。因为它是文件系统筛选器驱动程序,所以它会看到所有文件系统操作,但是仅为来自旧进程的操作实施功能。您可以看到它为在系统全局 位置创建文件的旧进程更改了目标文件路径,但是没有为以标准用户权限运行 Windows Vista 应用程序的进程进行此更改。当它确实在用户具有完全访问权限的位置创建了文件时,旧进程便认为操作成功,但在 \Windows 目录上的默认权限会拒绝对为 Windows Vista 编写的应用程序的访问。

图 4 文件系统虚拟化
图 4 文件系统虚拟化

注册表虚拟化的实施与文件系统虚拟化略有不同。虚拟化的注册表项包括 HKEY_LOCAL_MACHINE\Software 分支的大部分,但有许多例外项,例如以下项:

HKLM\Software\Microsoft\Windows HKLM\Software\Microsoft\Windows NT HKLM\Software\Classes 

 

只有通常由旧应用程序修改,但不会带来兼容性或互操作性问题的项才能虚 拟化。Windows 将旧应用程序对虚拟化项的修改重定向到位于 HKEY_ CURRENT_USER\Software\Classes\VirtualStore 的用户注册表虚拟根目录。该项位于用户的 Classes 配置单元 %LocalAppData%\Microsoft\Windows\UsrClass.dat 中,与任何其他虚拟化文件数据一样,它并不随漫游用户配置文件漫游。

与 Windows 为文件系统维护一个固定虚拟化位置列表不同,注册表项的虚拟化状态作为一个标志 REG_ KEY_DONT_VIRTUALIZE 存储在该项自身。Reg.exe 实用工具可以显示该标志以及另外两个虚拟化相关标志:REG_KEY_ DONT_SILENT_FAIL 和 REG_KEY_ RECURSE_FLAG,如图 5 所示。当设置了 REG_KEY_DONT_SILENT_FAIL 并且该项未虚拟化(已设置 REG_KEY_DONT_VIRTUALIZE)时,除了应用程序请求的访问外,原本被拒绝对该项执行操作访问的旧应用程序还将被授予用户对该项所拥有 的任何访问权限。REG_KEY_RECURSE_FLAG 表明新的子项是否继承父项的虚拟化标志,而不仅仅是默认标志。

图 5 Reg 实用工具显示虚拟化标志
图 5 Reg 实用工具显示虚拟化标志 (单击该图像获得较大视图)

图 6 显示了配置管理器如何实施注册表虚拟化,该管理器管理操作系统内核 Ntoskrnl.exe 中的注册表。对于文件系统虚拟化,创建虚拟化项的子项的旧进程将被重定向到用户的注册表虚拟根,但默认权限会拒绝 Windows Vista 进程的访问。

除了文件系统和注册表虚拟化以外,某些应用程序还需要其他帮助才能在标 准用户权限下正确运行。例如,对于测试其正在运行的帐户是否是 Administrators 组成员的应用程序,如果是该组成员,则会正常运行,如果不是,则不能正常运行。因此,Windows Vista 定义了许多应用程序兼容性填充,以使这类应用程序无论如何都能够运行。最常应用于旧应用程序以使其在标准权限下操作的填充如图 7 所示。企业 IT 专业人员可以使用诸如应用程序兼容性工具包(ACT,可从 technet.microsoft .com/windowsvista/aa905066.aspx 获得),及其标准用户分析程序 (SUA) 实用工具,或 Aaron Margosis 的 LUA Buglight 等工具来确认其 LOB 应用程序的填充要求。他们使用 Compatibility Administrator(也是 ACT 的一部分)将填充分配给应用程序,然后将得到的兼容性数据库(.sdb 文件)通过组策略部署到桌面。请注意,如果需要,可以对使用全局安全策略设置的系统完全禁用虚拟化。

虚拟化的效果

在“任务管理器”中右键单击某个进程并从上下文菜单中选择“虚拟化”,即可更改进程的虚拟化状态。图 A 显示了当其虚拟化状态更改时命令提示符的行为。开始时虚拟化是禁用的,因为它有一个 Windows Vista 指令清单。因为它使用标准用户权限运行,所以无法在 \Windows 目录中创建文件,但是在使用任务管理器将其虚拟化后,它似乎能够成功创建该文件。当其虚拟化返回禁用状态时,它将找不到该文件,该文件实际位于用户的虚拟 存储中。

图 A 虚拟化状态更改
图 A 虚拟化状态更改 (单击该图像获得较大视图)


管理员批准模式

即使用户只运行与标准用户权限兼容的程序,某些操作仍要求管理权限。绝 大多数软件安装都要求使用管理权限,以便在系统全局位置创建目录或注册表项,或者安装服务或设备驱动程序。修改系统全局 Windows 设置和应用程序设置也要求使用管理权限,Windows Vista 家长控制功能便是如此。通过切换到专用管理帐户可以执行大多数这些操作,但是这样很不方便,导致多数用户仍然会使用管理帐户来执行其日常任务。

因此,Windows Vista 提供了一个增强的“运行身份”功能,以使标准用户能够方便地以管理权限启动进程。此功能要求为应用程序提供一种方式来标识系统可为之获得管理权限(代表该应用程序)的操作,我将对此进行简要说明。

此外,Windows Vista 还引入了一个管理员批准模式 (AAM),这样,作为系统管理员的用户便可以使用标准用户权限来运行,而不必在每次希望获得管理权限时输入用户名和密码。此功能在登录时为用户创建两个 身份:一个具有标准用户权限,另一个具有管理权限。由于 Windows Vista 系统上的每个用户要么是标准用户,要么多数情况下作为 AAM 中的标准用户来运行,因而开发人员必须假定所有 Windows 用户都是标准用户,这将导致有更多的程序使用不带有虚拟化或填充的标准用户权限来运行。

为进程授予管理权限称为提升。由标准用户帐户执行此过程时,称为“当面式”(OTS) 提升,因为它要求输入某个管理员组的成员帐户的凭据,这通常由另一个用户当着该标准用户的面完成。由 AAM 用户执行的提升称为“同意”提升,因为用户只需批准其管理权限的分配即可。

如果用户是图 8 中所列任意管理员类型组的成员,Windows Vista 就会将该用户视为管理员。所列的许多组都只用于加入域的系统,并且不直接赋予用户本地管理权限,但是允许他们修改域范围内的设置。如果用户是其中任何组的 成员,而不是实际的管理员组的成员,该用户将通过 OTS 提升而不是“同意”提升来获得其管理权限。

当属于所列的某个组的用户登录时,Windows Vista 将创建一个令牌,代表该用户的管理身份的标准用户版本。新令牌解除了分配给该用户的所有特权,只保留了图 9 中所列的那些特权,它们是默认标准用户特权。此外,任何管理员类型组在该新令牌中都带有 USE_FOR_DENY_ONLY 标志。图 10 显示了 Sysinternals Process Explorer(一种进程管理工具,可从 microsoft .com/technet/sysinternals 下载),其左侧显示了使用管理权限运行的进程的组成员关系和特权,右侧显示了不具备管理员权限的情况。(为防止意外错误使用,Windows 安全模型要求先启用带有禁用标志的特权,然后才能使用它。)

图 10 AAM 管理员和标准用户令牌
图 10 AAM 管理员和标准用户令牌 (单击该图像获得较大视图)

具有“仅拒绝”标志的组只能用于拒绝(而不能允许)用户对某个资源的访 问,这样就消除了当该组被整个删除时所产生的安全漏洞。例如,如果某个文件的访问控制列表 (ACL) 拒绝了 Administrators 组的所有访问,但为该用户所属的另一个组授予某些访问权限,那么如果令牌中没有管理员组,则会为用户授予访问权限,从而为该用户身份的标准用户版本赋予比 管理员身份更多的权限。

独立系统(通常是家用计算机)和加入域的系统对来自远程用户的 AAM 访问的处理不同,因为连接了域的计算机可以在其资源权限内使用域管理组。当用户访问独立计算机的文件共享时,Windows 将请求该远程用户的标准用户身份,但在加入域的系统上,Windows 将通过请求该用户的管理身份来支持其所有域组成员。


方便地获得管理权限

系统和应用程序可以通过多种方式标识对管理权限的需求。其中一个是显示 在资源管理器 UI 中的“以管理员身份运行”上下文菜单项和快捷方式选项。这些项目包含一个彩色盾牌图标,它应放在任何按钮或菜单项上,当选中它时会导致权限的提升。选择 “以管理员身份运行”菜单项将使资源管理器使用动词“runas”调用 ShellExecute API。

绝大多数安装程序都要求使用管理权限,因此,映像加载程序(用于触发可 执行文件的启动)包含了安装程序检测代码以发现可能的旧安装程序。它使用的某些启发方式很简单,只需检测该映像在其文件名或内部版本信息中是否具有设置 (setup)、安装 (install) 或更新 (update) 字样;较为复杂的启发方式则涉及扫描可执行文件中的字节序列,第三方安装包装实用工具大多为这种情况。

映像加载器还会调用应用程序兼容性 (appcompat) 库,以查看目标可执行文件是否要求使用管理员权限。该库将查询应用程序兼容性数据库,以查看该可执行文件是否关联了 RequireAdministrator 或 RunAsInvoker 兼容性标志。

可执行文件请求得到管理权限的最常用方式是在其应用程序指令清单文件中 包含一个 requestedElevationLevel 令牌。指令清单是 XML 文件,其中包含有关某个映像的补充信息。它们是在 Windows XP 中引入的,作为标识与并列 DLL 和 Microsoft .NET Framework 程序集的依赖关系的一种方式。指令清单中出现的 trustInfo 元素(可在下面的 Firewallsettings.exe 字符串转储摘录中看到)表明这是一个为 Windows Vista 编写的可执行文件,并且其中嵌套了 requestedElevationLevel 元素。该元素的 level 属性可具有以下三个值之一:asInvoker、highestAvailable 和 requireAdministrator。

<trustInfo xmlns=”urn:schema-microsoft-com:asm.v3”> <security> <requestedPrivileges> <requestedExecutionLevel Level=”requireAdministrator” uiAccess=”false”/> </requestedPrivileges> </security> </trustInfo> 

 

不需要管理权限的可执行文件(如 Notepad.exe)指定 asInvoker 值。某些可执行文件预期管理员始终希望具有最大访问权限,因此他们使用 highestAvailable 值。如果某用户运行具有该值的可执行文件,那么仅当他在 AAM 中运行或被视为管理员(根据早先定义的规测)且必须提升以获得其管理权限时,才会要求提升他的权限。例如,Regedit.exe、Mmc.exe 和 Eventvwr.exe 都是使用 highestAvailable 的应用程序。最后,requireAdministrator 始终会导致提升请求,任何没有管理权限就无法操作的可执行文件需要使用该值。

可访问性应用程序为 uiAccess 属性指定“true”,以便驱动所提升进程的窗口输入,并且它们还必须带有签名并位于多个安全位置(包括 %SystemRoot% 和 %ProgramFiles%)之一以获取该能力。

确定可执行文件所指定值的一种简单方法是使用 Sysinternals Sigcheck 实用工具查看其指令清单,如下所示:

sigcheck –m <executable> 

 

执行一个请求管理权限的映像将导致在服务主机进程 (%SystemRoot%\System32\Svchost .exe) 中运行的应用程序信息服务(也称为 AIS,它包含在 %SystemRoot%\System32\Appinfo.dll 中)启动 Consent.exe (%SystemRoot%\System32\Consent.exe)。Consent 将捕获屏幕的位图、向其应用一个淡入淡出效果、切换到只能由本地系统帐户访问的桌面、将该位图作为背景、并显示一个提升对话框,其中包含有关该可执行文件 的信息。在单独的桌面上显示可防止用户帐户中的任何恶意软件修改对话框的外观。

图 11 OTS 提升对话框
图 11 OTS 提升对话框 (单击该图像获得较大视图)

如果映像是由 Microsoft 数字签名的 Windows 组件,并且位于 Windows 系统目录中,则对话框顶部将显示一条蓝带,如图 11 顶部所示。灰带(对话框中间)表明映像由 Microsoft 以外的组织数字签名,橙色带(对话框底部)表明映像未经签名。提升对话框显示了映像的图标、描述以及数字签名映像的发布者,但对于未签名的映像只有一个通 用的图标、文件名和“未能识别的发布程序”。这样就使恶意软件更难以模仿合法软件的外观。对话框底部的“详细信息”按钮展开后将显示当可执行文件启动时要 传递给它的命令行。图 12 所示的“AAM 同意”对话框与此类似,但它不会提示提供管理员凭据,而是包含了“继续”和“取消”按钮。

图 12 AAM 提升对话框
图 12 AAM 提升对话框 (单击该图像获得较大视图)

如果用户拒绝提升,Windows 将向激发该启动过程的进程返回一个拒绝访问错误。当用户通过输入管理员凭据或单击“继续”同意提升时,AIS 将调用 CreateProcessAsUser 以使用适当的管理身份启动进程。虽然从技术上讲 AIS 是所提升进程的父项,但 AIS 使用了 CreateProcessAsUser API 中的新支持,后者将该进程的父进程 ID 设为最初启动它的进程的 ID(请参阅图 13)。这就是在显示进程树的工具(如 Process Explorer)中,已提升进程没有显示为 AIS Service Hosting 进程的子项的原因。

图 13 提升流程
图 13 提升流程

即使提升对话框显示在单独的安全桌面上,默认情况下,用户也无法验证他 们查看的是合法对话框,而不是由恶意软件提供的对话框。这并不是 AAM 的问题,因为恶意软件虽无法使用假的“同意”对话框获取管理权限,但它可以等待标准用户的 OTS 提升,截获它,并使用特洛伊木马对话框捕获管理员凭据。使用那些凭据,它们可以获得对管理员帐户的访问权限并感染它。

因此,强烈建议不要在企业环境中使用 OTS 提升。要禁用 OTS 提升(并减少咨询台呼叫),请运行本地安全策略编辑器 (Secpol.msc) 并将“用户帐户控制:标准用户的提升提示行为”配置为“自动拒绝提升请求”。

注重安全的家庭用户应当将 OTS 提升配置为要求使用一个恶意软件无法截获或模拟的安全注意序列 (SAS)。要配置 SAS,请运行组策略编辑器 (Gpedit.msc),导航到“计算机配置”|“管理模板”|“Windows 组件”|“凭据用户界面”,并启用“要求输入凭据的受信任路径”。完成上述步骤后,会要求您输入 Ctrl+Alt+Delete 以访问提升对话框。


隔离已提升的进程

Windows Vista 在已提升进程周围设置了一道屏障,以保护它们免受在同一桌面上使用标准用户权限运行的恶意软件的侵扰。如果没有这道屏障,恶意软件可能会通过窗口消息发送 合成的鼠标和窗口输入,从而驱动某个管理应用程序。虽然标准 Windows 安全模型可防止使用标准用户权限在进程中运行的恶意软件破坏作为不同用户运行的已提升进程,但它不会禁止作为某个管理用户的标准权限版本运行的恶意软件打 开该用户的已提升进程、向其中插入代码并启动其中的线程以执行插入的代码。

Windows Vista 为窗口消息提供的防护称为用户界面特权隔离 (UIPI)。它基于新的 Windows 完整性机制,Windows Vista 同样使用该机制作为已提升进程周围的屏障。在此新安全模型中,所有进程和对象都具有完整性级别,并且对象的完整性策略可以限制访问权限,否则,这些访问权 限将由 Windows 随机访问控制 (DAC) 安全模型授予某个进程。

完整性级别 (IL) 由安全标识符 (SID) 表示,后者还表示用户和组;而级别则编码在 SID 的相对标识符 (RID) 中。图 14 显示了四个主要 IL 的显示名称、SID 和 SID 的 RID 的十六进制版本。十六进制数字揭示了每个级别间的 0x1000 的间隔,以便提供由 UI 可访问性应用程序使用的中间级别并考虑未来增长需要。

图 15 列出了对象 IL 策略以及它们所限制的访问类型,这些访问类型与为对象定义的通用访问权限相对应。例如,No-Write-Up 将禁止低 IL 进程获取任何由 GENERIC_WRITE 访问权限表示的访问权限。大多数对象(包括文件和注册表项)的默认策略都是 No-Write-Up,这将禁止进程从具有比它更高的 IL 的对象获取写访问权限,即使该对象的随机访问控制列表 (DACL) 授予用户这种访问权限也是如此。仅有的具有不同策略的对象是进程对象和线程对象。它们的策略(No-Write-Up 加上 No-Read-Up)会禁止在低 IL 上运行的进程向具有较高 IL 的进程插入代码或从中读取数据(如密码)。

Windows 为每个进程分配一个 IL,该 IL 放在进程令牌中组 SID 的旁边,这些组是运行该进程的用户所属的组。图 16 列出了分配给不同 IL 的进程示例。进程通常继承其父项的 IL,但进程也可以在其他 IL 上启动进程,与 AIS 启动已提升进程时的操作相同。您可以通过指定 /all 选项使用内置的 Whoami 实用工具、Sysinternals Process Explorer 或 AccessChk 来查看进程完整性级别。Process Explorer 可以在附加的“完整性级别”列中显示进程 IL。

每个安全对象都有一个显式或隐式的 IL。进程、线程和令牌对象始终具有一个显式分配的 IL,它通常与对应进程令牌中存储的 IL 相同。多数对象都没有显式 IL,因此都默认为某个中等 IL。使用中等以外的 IL 创建的仅有对象是由在低 IL 上运行的进程创建的对象,它们因此而具有一个低 IL。您可以使用内置的 iCacls 工具 (%SystemRoot%\System32\iCacls.exe) 查看文件的 IL,并使用 Sysinternals AccessChk 实用工具查看文件、注册表项、服务和进程的 IL。图 17 显示需要通过保护模式 Internet Explorer 才能访问的目录的 IL 为“低”。

图 17 显示用户收藏夹目录 IL 的 AccessChk
图 17 显示用户收藏夹目录 IL 的 AccessChk (单击该图像获得较大视图)

如果对象具有显式 IL,则它存储在 Windows Vista 中新引入的一种访问控制项 (ACE) 类型中(即 Label ACE),该 ACE 位于对象安全描述符的系统访问控制列表 (SACL) 中(请参阅图 18)。 ACE 中的 SID 对应于对象的 IL,ACE 的标志为对象的完整性策略进行了编码。在 Windows Vista 之前,SACL 只存储审核 ACE,这需要“管理审核和安全日志”特权 (SeSecurityPrivilege),但读取 Label ACE 只需要“读取权限”(READ_CONTROL) 访问权限。如果进程要修改对象的 IL,它必须具有该对象的“更改所有者”(WRITE_OWNER) 访问权限以及一个与该对象相同或更高的 IL,并且该进程只能将 IL 设置为自己的 IL 或更低的 IL。新的“修改对象标签”(SeRelabelPrivilege) 特权使进程能够更改它可以访问的任何对象的 IL,甚至将 IL 提高到超过进程自己的 IL,但默认情况下,该特权未分配给任何帐户。

图 18 对象的 Label ACE
图 18 对象的 Label ACE

当进程尝试打开某个对象时,内核的 SeAccessCheck 功能中将先进行完整性检查,然后再进行标准的 Windows DACL 检查。在默认完整性策略下,仅当进程的 IL 等于或高于对象的 IL,且 DACL 也为该进程授予了它所需要的权限时,该进程才能打开此对象进行写访问。例如,低 IL 进程不能打开中等 IL 进程进行写访问,即使 DACL 为该进程授予了写访问权限。

在默认完整性策略下,进程可以打开任何对象(进程和线程对象除外)进行 读取访问,只要对象的 DACL 为它们授予了读取权限即可。这意味着,在低 IL 上运行的进程可以打开任何其运行所在的用户帐户可以访问的文件。保护模式 Internet Explorer 使用 IL 来帮助防止感染它的恶意软件修改用户帐户设置,但是它不能禁止恶意软件读取用户的文档。

上述情况不适用于进程和线程对象,因为它们的完整性策略还包括 No-Read-Up。这意味着,进程的 IL 必须等于或高于它要打开的进程或线程的 IL,且 DACL 必须授予它成功打开所需的访问权限。假设 DACL 允许授予所需的权限,图 19 显示了在中等和低 IL 上运行的进程针对其他进程和对象所拥有的访问权限。

图 19 对象和进程访问权限
图 19 对象和进程访问权限

Windows 消息传递子系统还支持完整性级别通过以下方式实施 UIPI:禁止进程向具有较高 IL 的进程所拥有的窗口发送除信息性窗口消息以外的任何消息。这将不允许标准用户进程向已提升进程的窗口进行输入,或不允许通过向其发送可触发内部缓冲区溢出 的格式不正确的消息来破坏已提升进程。进程可以通过调用 ChangeWindowMessageFilter API 选择允许其他消息通过这层防范。UIPI 还会防止窗口挂接影响较高 IL 进程的窗口,这样,例如标准用户进程便无法记录用户在管理应用程序中的键击情况。


提升和安全边界

UAC 提升是一种方便性,而不是安全边界,清楚这一点很重要。安全边界要求安全策略指明能够通过该边界的内容。用户帐户就是 Windows 中安全边界的一个示例,因为如果没有另一个用户的许可,某个用户就无法访问属于另一个用户的数据。

因为提升不是安全边界,所以无法保证使用标准用户权限在系统上运行的恶 意软件不会侵扰已提升进程以获取管理权限。例如,提升对话框只标识了即将提升的可执行文件;其中没有提供执行时将如何操作的任何信息。可执行文件将处理命 令行参数、加载 DLL、打开数据文件并与其他进程通信。可以想象,上述任何操作都可能允许恶意软件侵扰已提升进程,进而获取管理权限。

低 IL 沙盒中的游戏

保护模式 Internet Explorer 在低 IL 上运行,以便在可能感染其进程的恶意软件周围筑起一道围墙。这将防止恶意软件更改用户帐户设置并将自己安装在一个自动启动位置。您可以使用 Sysinternals PsExec 实用工具和 -l 开关,在低 IL 上启动任意进程以探究沙盒的秘密。图 B 显示了在低 IL 上运行的命令提示符如何无法在用户的临时目录(具有中等 IL)中创建文件,却能够在具有低 IL 的 Internet Explorer 临时目录中创建该文件。

图 B 命令提示符只能在相似的 IL 中创建文件
图 B 命令提示符只能在相似的 IL 中创建文件 (单击该图像获得较大视图)

 


已提升的 AAM 进程尤其易受侵扰,因为它们在与 AAM 用户的标准权限进程相同的用户帐户下运行,并共享用户的配置文件。许多应用程序读取在用户配置文件中注册的设置并加载在其中注册的扩展,这为恶意软件的提 升提供了机会。例如,常用控制对话框会加载在用户的注册表项(位于 HKEY_CURRENT_USER 下)中配置的外壳扩展,因此恶意软件可以将其自身作为一项扩展添加进去,以加载到使用那些对话框的任何已提升进程中。

即使是从标准用户帐户提升的进程也必定会因共享状态而受到侵扰。在某个 登录会话中运行的所有进程将共享 Windows 用来存储对象(如事件、mutex、信号和共享内存)的内部命名空间。如果恶意软件知道某个已提升进程将在进程启动时尝试打开并读取特定共享内存对象,它 可以创建该对象,而其内容将触发缓冲区溢出以便将代码插入到已提升进程中。这种攻击类型比较复杂,但其存在的可能性使得 OTS 提升无法成为一种安全边界。

我们的底线是引入提升以提供方便,从而鼓励要获得管理权限的用户在默认 情况下使用标准用户权限运行。希望安全边界有保障的用户可以用方便性换取这种保障,此时,可以为日常任务使用标准用户帐户,同时使用快速用户切换 (FUS) 切换到专用管理员帐户来执行管理操作。另一方面,希望用安全性换取方便性的用户可以在“控制面板”的“用户帐户”对话框中禁用系统上的 UAC,但是必须清楚,这同时也会禁用 Internet Explorer 的保护模式。


结束语

以标准用户身份运行有许多好处,其中包括有助于保护系统免受无意或有意 的损害,以及防止共享系统的用户的数据和完整性受到未经授权的访问。UAC 的各种变化和技术将导致 Windows 使用模型发生重要改变。在 Windows Vista 中,Windows 用户第一次能够使用标准用户权限执行大多数日常任务并运行大多数软件,现在,许多企业都能够部署标准用户帐户。