- 最低权限用户帐户
- 确定真正的 LUA 错误
- 修复 LUA 错误的技术
出现的另一个问题与系统时间有关。Windows XP 不允许 LUA 用户更改系统时间。这并不是 LUA 错误,因为更改系统时间在审核与 Kerberos 协议方面有安全隐患。不过,称 Windows XP 不允许 LUA 用户更改时区这一事实是 LUA 错误却是有根据的。双击任务栏通知区域中的时钟时显示错误消息而不是“日期和时间”小程序的只读视图这一事实也是如此。(请注意,Windows Vista? 极其侧重于提供更加无缝的 LUA 体验,其中包括对“日期和时间”小程序的改进。)
到目前为止,大多数 LUA 错误都归因于注册表和文件系统访问权限。例如,一个程序可能尝试将其设置保存在 %ProgramFiles% 下的安装文件夹中,也可能会尝试使用“完全访问”权限打开 HKLM 下的某个项,即便实际上使用“读取”访问权限便可。其他类型的 LUA 错误包括尝试启动或停止服务、加载设备驱动程序、直接访问硬件资源、创建或管理文件共享,甚至是显式地检查当前用户是否为 Administrators 组的成员。
始终会有一个或多个低级别操作(API 调用),在作为管理员时可以成功执行,但作为 LUA 执行时却会失败。自己可以通过一些工具(如 SysInternals 开发的 Regmon 和 Filemon)来查看其中的一些错误。所查看到的每一个都真的是 LUA 错误吗?这取决于应用程序响应失败的方式。我所见过的响应归类为以下三组:
应用程序只调用操作,不检查结果,但其能否继续正常工作并不取决于操作成功。不是 LUA 错误。
妥善降级:
应用程序调用操作,检查它是否成功,并以适当方式处理故障。不是 LUA 错误。
应用程序调用操作,并假定操作成功,只有操作成功,它才能继续正常工作。这种情况的一个变型是,应用程序检查操作是否成功,但未以适当方式处理故障,如在显示错误消息后死锁。
更改安全性设置之前,请验证所修复的是真正的 LUA 错误,而不只是假想的 LUA 错误,从而确保不存在更好的能够在不增加风险的情况下更正该问题的方法。
举个例子,有一个您或您的用户需要运行的标准应用程序。该应用程序的设计用途并不是在计算机上执行任何系统管理任务,但由于某个未知的原因,只有通过具有管理员级别访问权限的帐户运行,它才能正常工作。您需要为您的用户授予对该应用程序的访问权限,但又不希望他们以管理员身份运行。您该怎么办呢?
最常见的解决方法是干脆将用户添加到 Administrators 组。有时此操作由服务台技术人员来完成,以确定这样做是否可以修复问题。之后该技术人员便忘记了从 Admins 组中删除该用户,这必然导致他在几周内又接到一个服务台电话,用户在电话中询问“我的计算机为什么运行得这么慢,而且为什么只要我一登录,就会弹出一堆广告呢?”让我们将这种解决方法称作无效方法好了,就不再加以考虑了。
其他两个常见(但不够理想)的解决方法是,只作为管理员运行那一个程序,或在将对该程序的安装文件夹、HKEY_LOCAL_MACHINE 下该程序的所有注册表项以及 HKEY_CLASSES_ROOT 下的所有注册表项的“完全控制”权限授予“每个人”后作为普通用户运行该程序。
对了,在做这件事时,应记得为用户授予“调试”、“取得所有权”以及“作为操作系统的一部分”权限(我当然是在开玩笑,这样做的风险极高,应予避免)。
好了,那么您该怎么办呢?在本文的其余部分,我将介绍一个系统性的方法,既能够解决 LUA 错误,同时又能将风险降至最低。我将按从最可取到最不可取的顺序来介绍这些方法,并列举每个方法的优缺点。顺便说一下,尽管本文中的指导主要面向 Windows XP,这些方法实际上同样适用于 Windows Vista。
这是最佳方法。如果应用程序要求具有管理员权限并无合法理由(无论是业务还是技术上的理由),那么无法通过普通用户帐户运行应用程序就是一种严重的错误,会对系统的安全性、稳定性和可管理性造成危害。请认真考虑让开发人员直接在代码中修复该问题。
如果开发小组答复您的请求时这样说“这是一个关键任务应用程序,因此必须以管理员身份运行”或“必须以管理员身份运行该应用程序,因为它会在 HKEY_LOCAL_MACHINE 中写入信息”,就应该这样回答“你胡说八道”,并坚持让他们修复错误。
开发小组在应用程序代码中直接修复错误后,就不必再执行任何修补程序、调整程序或解决方法了。此外,开发人员还可以从经验中学习,避免产生新的 LUA 错误。(请注意,LUA 错误的首要成因就是开发人员在编写代码时以管理员身份运行!我将在“放宽访问控制列表”部分对此做详细论述。)
时间和金钱两方面的开销都会令人望而却步,如果资源有限,需要修复的应用程序又很多,就更是如此。可能需要重新设计应用程序的结构,而且在此过程中可能会引入新的错误。
使用 Application Compatibility Toolkit 中提供的“LUA 模式”修补程序真正诱人的原因是,它使用方便。还不需要提升权限。
在 Windows XP 中,“LUA 模式”修补程序往往无效。(Windows Vista 中的“文件和注册表虚拟化”经过了完全重新编写,其兼容性比 Windows XP 中的 ACT“LUA 模式”高得多。)
工具不奏效时底层操作所增添的复杂性会使故障排除变得更加复杂。
在 Windows 2000 之前,HKCR 只是对 HKLM\Software\Classes(只有管理员才可以向其中写入数据)的一个符号链接。这表示对 HKCR\.txt 执行的操作实际上发生在 HKLM\Software\Classes\.txt 中。Windows 2000 引入了以用户为单位的注册数据,因此现在 HKCR 已成为 HKLM\Software\Classes 和 HKCU\Software\Classes 的合并视图(用户可以向其中写入数据)。如果后者中存在项,它将享有优先权。因此,如果 HKCU\Software\Classes\.txt 中已存在 HKCR\.txt,现在对该项的操作将在 HKCU\Software\Classes\.txt 中进行;如果不存在,将和以前一样,操作将在 HKLM\Software\Classes\.txt 中进行。
问题在于,有许多应用程序会在运行时向 HKCR 写入数据,以增强其文件关联、COM 注册数据等。如果写入失败,即使要写入的数据已经存在,也会产生错误。每次应用程序运行时,都会写入相同的数据。如果相同的注册数据存储在 HKCU\Software\Classes 中,写入操作将会成功,而且不会更改程序的行为。
要修复此问题,首先必须确定应用程序试图写入到的 HKCR 下的项。将这些项导出到一个或多个 .reg 文件中(在“注册表编辑器”中,选择“文件”|“导出”,然后选择“选定的分支”)。然后使用文本编辑器,用 [HKEY_CURRENT_USER\Software\Classes\ 替换 [HKEY_CLASSES_ROOT\ 的所有实例并保存更改。完成后,将编辑过的 .reg 文件导入到需要运行该程序的用户的注册表中。
此方法可修复应用程序在 HKCR 中执行本应在安装期间完成的操作的问题。该方法好于放宽对 HKCR 下系统范围资源访问控制的方法。恶意软件覆盖 HKCU 下的项将不会影响操作系统组件或计算机的其他用户。
直到最近才出现能够将 HKCR 写入识别为 LUA 错误来源并隔离所涉及项的工具。使用 LUA Buglight 执行此任务要容易得多。
此方法可避免放宽对文件系统内系统范围资源的访问控制。同样,恶意软件覆盖 HKCU 下的项将不会影响操作系统组件或计算机的其他用户。
IniFileMapping 条目仅指定文件名,因此将会影响配置文件 API 对任何路径中具有该名称的任何文件的所有访问。这可能会对具有专用的同名 ini 文件的其他应用程序产生副作用。
许多游戏依赖 Macrovision 开发的 secdrv 设备驱动程序(也称为 SafeDisc)。随 Windows XP 一起提供的 SafeDisc 驱动程序是一种需要时启动的驱动程序;不允许用户停止和启用它,这会导致程序尝试访问该驱动程序时出现错误。有一个更新(可从 Microsoft 及从 Macrovision 站点获得)可以将该驱动程序配置为在系统启动时加载,这样用户启动它时就不需要拥有权限。此更改使非管理员用户能够正常地运行某些游戏。
(请注意,撰写本文时 Microsoft 下载页面针对该更新有一句说明,称该软件“will not alter or patch any component on your system; it will only change the startup state of the system component.(将不会改动或修补系统上的任何组件;它将只更改系统组件的启动状态。)”。事实并非如此 - 它会安装更新的驱动程序。)
此更新易于实现,而且不需要在访问控制列表 (ACL) 中进行与系统范围资源有关的更改。
除了该方法主要用于更正与游戏(而不是生产力应用程序)有关的问题之外,实际上没有任何缺点。
LUA 错误最常见的主要成因是开发人员(往往也是测试人员)通常以管理员身份运行。开发人员可能并非有意要求最终用户以管理员身份运行,但依赖管理员访问权限的东西可能会潜入代码(例如,写入到 C: 驱动器根文件夹中的文件、写入 %ProgramFiles% 下的应用程序安装文件夹中的文件或写入 %windir% 中的文件)。开发人员和测试人员使用时应用程序还能正常工作,但当您以普通用户身份运行应用程序时,它就崩溃了。
一种方法是更改对象的访问控制列表 (ACL),为用户授予程序所需的访问权限。通常,需要调整的对象位于注册表或文件系统(如果使用 NTFS)中。采用此方法时需要进行认真考虑,并应注意一些重要事项。
首先,在已尝试了所有更可取的方法并确认这些方法都不能修复所要处理的 LUA 错误时,才应选择此方法。如果采用此方法,一定要非常小心。
安全配置指南支持
”。)此外,应尽一切可能避免更改程序代码的 ACL。这是为了防止恶意软件感染或替换应用程序文件。
理想情况下,资源只应由一位用户进行访问。如果资源被多个非管理员用户访问,则一位用户导致另一位用户的帐户遭受危害的风险会增加。
最后,只要应用程序能够工作,应只为可能的最少数量用户授予访问可能的最少数量资源所需的最少量附加访问权限。在任何情况下都不需要为“每个人”授予对文件系统或注册表一大部分的完全控制权限。
最理想的做法是只为计算机的主要用户授予附加访问权限,但如果系统数量庞大,这样做在管理上可能会有困难(例如,在一个系统上授予 MARY 权限,在另一个系统上授予 STEVE 权限,依此类推)。如果可以定义一组需要使用该程序的用户,应将这些用户添加到一个组,然后为该组授予访问权限。
也可以授予对内置 INTERACTIVE 仿真组的访问权限。这样做将只为当时以交互方式登录的用户授予附加访问权限,而不会授予附加的对资源的远程访问权限。请注意,在终端服务器或“快速用户切换”应用场景中,计算机上可能同时有多位用户的令牌中有 INTERACTIVE。
此方法会为您的时间投资带来巨大回报。我和我的同事见过的大部分 LUA 错误都与文件和注册表权限有关。调整访问控制列表可能比任何其他方法修复的 LUA 错误都要多。
此方法的可取性较低,因为出于某种原因对 ACL 进行了这样的设置。更改 ACL 使得受限用户能够更改共享资源(出于善意或恶意),并会使一位用户(或该用户无意间运行的恶意软件)可以更容易地影响其他用户。如果管理员受到影响,就会危害整个系统。
一些应用程序解决 LUA 错误的方法是,在启动时显式地检查您是否为管理员组成员,如果您不是,将显示一条错误消息,坚称您必须是管理员,才能使用该程序。这可能是由于开发人员的懒惰、不称职或傲慢(或三者兼而有之),但无论您使用任何其他解决方法,这些应用程序都不会让步。如果已经确认所有其他方法都已失败,就只能考虑以提升的组或权限运行那个有问题的应用程序。
请不要以管理员身份运行应用程序,而是尝试以提高的权限(但仍低于完全管理权限)运行它。可以 Power Users 成员的身份或特定权限(如 SeLoadDriverPrivilege)运行应用程序。但要知道,只需多费一点工夫,就可利用这些其他组和权限中的许多组和权限接管整个系统。
博客文章。)
最后,可以使用 RunAsAdmin。这是 Valery Pryamikov 开发的一个值得关注而且有用的开源实用程序。RunAsAdmin 采用的方法有点类似于 Windows Vista 的“用户帐户控制”功能 (UAC),就地提升当前用户的权限而不要求使用密码。
Winternals(SysInternals 的商业机构)提供了 Protection Manager,该工具使用轻型客户端-服务器应用程序和白名单技术来封锁所有不受信任的应用程序。可通过 Protection Manager 将应用程序的进程令牌和权限提升到管理员进程令牌和权限的级别或降低到用户进程令牌和权限的级别(当最终用户分别是非管理员或管理员时)。Protection Manager 不允许已提升权限的应用程序的子进程以提升的权限运行,除非也将该子进程显式地配置为已提升权限的应用程序。已降低权限进程的所有子进程的权限将自动降低。可按管理员通过数字签名、散列、NTFS 文件所有权或路径进行的指定对应用程序执行允许、封锁、提升权限或降低权限操作。
还可使用其他工具,这些工具执行类似 RunAs 的操作时会将管理员帐户凭据加密(有时只是进行模糊处理)。尽管此方法提高了标准,可阻止一些用户获取管理员凭据,但那些密码仍然需要在用户的安全上下文中解密,因此可能会暴露给拥有适当工具的攻击者。
有一个我听过的常见问题是,RunAs.exe /savecred 选项是否可用作快捷方式,以使用户能够使用保存的密码(不需要再次输入密码)以管理员身份运行某个应用程序。但这会导致无法预料的问题,而且也有许多问题是应该知晓的。凭据并不是绑定到任何单个快捷方式;凭据保存后,就可以使用它们来启动任何应用程序。尽管密码使用用户特有密钥进行了安全的加密,但仍然要在用户的安全上下文中进行解密而被短时间公开。而且,在 Windows XP Home Edition 上无法使用 /savecred 选项。
使用此方法可以避免始终以管理员身份运行所有内容。遗憾的是,这差不多是此方法的唯一优点。
以提高的权限运行应用程序比我已介绍过的任何其他方法的风险都高得多。如果以管理员身份运行应用程序,将很难保护系统不受恶意用户或恶意应用程序的攻击。以下是一个简单的示例。如果以管理员身份运行“记事本”,然后选择“文件”|“打开”,将会显示一个类似资源管理器的小窗口。您仍然位于“记事本”中,这意味着您拥有对整个文件系统的完全管理员级别访问权限,甚至可以从该处以管理员身份启动程序。此项简单技术会被恶意用户或将击键或窗口消息送入已提高权限程序的恶意软件利用。
“最低权限用户帐户”可以作为安全策略中的一个便利选择,但它可能会引发一些值得关注的难题。这些错误解决方法的效力和安全性有很大差异。虽然确定错误的确切成因,然后使用最佳解决方案进行修复有困难,但这样做很重要。如果使用其中一个可取性较低的方法,则应了解如何尽最大可能保护系统。
LUA Buglight 是一个专门用于帮助开发人员和 IT 专业人士确定 Windows XP 上运行的应用程序中 LUA 错误具体成因的工具。确定具体成因后,就可以通过修复应用程序的源代码或进行配置更改来更轻松地解决错误,从而使应用程序能够正常地为非管理员用户工作。
LUA Buglight 方法的核心是,应用程序调用修补过的 API 时,修补代码会先调用底层 API。如果该 API 因访问被拒绝(在某些情况下是由于不拥有权限)而失败,修补代码会取得 this-user-as-admin 令牌,模拟该令牌,然后再次调用底层 API。第二次调用的结果便是返回到应用程序的内容。如果以管理员身份的调用成功,有关该调用的信息将作为潜在的 LUA 错误写入日志文件。最终结果是应用程序不会由于 LUA 错误而失败,因为在需要时它可以使用管理员权限,但将会列出每一个需要使用管理员权限的情况。有关 LUA Buglight 即将推出的测试版的最新信息,请参阅 blogs.msdn.com/aaron_margosis。