安全观察管理 ACL 的工具

Jesper M. Johansson

在 Windows 中,访问控制列表 (ACL) 能让您很好地控制用户的能力和使用类似文件和文件夹等资源的过程。管理 ACL 可能是更复杂的任务之一,它与保护您用户系统的安全性相关。幸运的是,有很多有用的实用工具

可以帮助自动化和简化关于权限和 ACL 的任务。

大多数读者都熟悉历史悠久的 cacls.exe 工具,它自面市以来就安装在每个版本的 Windows NT® 中。如果在 Windows Vista™ 中运行 cacls.exe,会看到下列消息:

Microsoft Windows [Version 6.0.5744]
Copyright (c) 2006 Microsoft Corporation. All rights reserved.

C:\Windows\system32>cacls

 NOTE: Cacls is now deprecated, please use Icacls.

除了对 Windows Vista 中 ACL 的更新之外(我已在《TechNet 杂志》2007 年六月期中进行了说明;请参阅 technetmagazine.com/issues/ 2007/06),Microsoft 还更新了一些可用来管理 ACL 的工具。有趣的是,在这些更新中最重要的是命令行工具。

Icacls.exe 是 Windows Vista 中新出现的(在 Windows Server® 2003 Service Pack 2 中的下层也是新出现的)。它将逐渐替代 cacls.exe,正如您可能知道的一样,它从未被完全更新过,无法支持更多由 Windows® 2000 引入的详细权限,从而使这个更新晚了大约七年之久。

令人惊讶的是,不管 cacls.exe 是否被弃用,它实际上还是包含了部分新功能。首先,它能识别交接点和符号链接,并且知道如何遍历它们。其次,它可以打印和设置 ACL,从而可以使用安全性描述定义语言 (SDDL) 字符串。

然而,尽管 cacls.exe 有更新,您都会真的需要 icacls.exe 中提供的功能。

保存和恢复 ACL

过去 10 年来一直有一个愿望(至少是我的愿望),就是希望能够保存 ACL,以便可以在后来恢复它。事实证明,它是您可以对 ACL 执行的最复杂的操作之一。除了在某些特殊情况下以外,ACL 一般不可能回到一开始未遭破坏的原始状态。不过,该功能可能非常有用。

在介绍如何保存或恢复 ACL 之前,让我们先探讨一下它为什么这么难。假设您有一个包含本地大学学生用户数据的层次结构。您在 2 月 1 日保存了 ACL。4 月 17 日,您发现 ACL 遭到了破坏,然后去从保存的副本进行恢复。这个操作有哪些复杂的地方?

首先,新季度是从 4 月 2 日开始。您的学生大约有 15% 已毕业;因此,他们的目录不再保留。这样,您在无效的备份文件中会有 ACL。您还有一批新学生,也占 15%,在这个新季度入学。他们现在有主目录,但是在备份文件中没有 ACL。他们的 ACL 应该是什么?当然您有 70% 的学生仍在那里,但是他们已创建了新文件和文件夹,并删除了其他文件和文件夹。您可以忽略删除的文件和文件夹,但是您如何配置他们创建的新文件夹呢?如果学生决定在 3 月 4 日将文件夹与他的朋友分享,那该怎么办呢?您会在恢复 ACL 时中断他们的共享吗?

保存和恢复 ACL 并不是许多人希望您相信的那么简单的一个操作。您在执行此操作时需要小心行事。很可能,甚至极有可能您会将一些未定义的行为作为结果。恢复 ACL 确实是最后一个手段;备份它的时间越长,恢复它时发生中断的可能性就越大。

不过如果您愿意尝试这个功能,可使用 /save 开关运行 icacls.exe:

icacls <target> /save acls.bin /t

这会将 ACL 保存到名为 acls.bin 的文件。在该文件中,具有 ACL 的每个对象会各占一行,后面接着的一行指定 SDDL 中的 ACL。通过使用 /t 开关,命令会对您指定对象及其下面的所有对象和容器执行操作。

保存功能是工具包中很受欢迎的一个新增功能,但是它仍有一些瑕疵。例如,它仅保存自由访问控制列表 (DACL),而不是系统访问控制列表 (SACL)。实际上,如果有 SACL,它会保存代表这个 SACL 的虚拟值,但是不会实际保存 SACL 的任何部分。

此外,保存 ACL 的方法会引发一个有意思的问题。当您在最喜欢的文本编辑器中打开保存的 ACL 之前,请记住:

不要编辑您已保存的 ACL!

如果您在文本编辑器中打开了包含您保存的 ACL 的文件,您会发现它看起来像是 Unicode (UTF-16) 格式的文本文件。实际上,这就是它的具体格式。这也许会导致您考虑编辑它,并将其从本文编辑器中保存。千万别那么做!

如果您在文本编辑器中打开包含保存的 ACL 的文件,并进行了保存,您将无法从该文件恢复 ACL。事实证明,它实际上并不是 Unicode 文本文件。这种文件必须以 2 位字节的 0xfffe 开头。如果您使用文本编辑器(如记事本)保存文件,事实上它会将标记放入文件的第一个 2 字节中。但是此 icacls.exe 工具期望 ACL 数据会在文件中字节为 0 的地方开始。结果,工具将无法分析文件中的 ACL,因为它期望开始两个字节是指定操作对象的字符串的一部分。您的备份文件将不可用。

Microsoft 意识到了这个问题,但由于是在 Windows Vista 测试周期较晚的时候才报告,因此这个瑕疵在发布之前未被修复。目前,我们不知道它什么时候,甚至是否会被修复。因此现在最好的建议是不编辑已保存的 ACL。如果您需要这样做,请将文件保存为 .bin 文件,并使用十六进制编辑器,如您最喜欢的开发环境。

使用 /save 开关保存 ACL 后,就可以使用带 /restore 开关的 icacls.exe 来恢复它。形式最简单的恢复命令使用下面的语法:

icacls <directory> /restore acls.bin

恢复过程不会对文件进行任何操作。如需了解这一点,请看一下图 1 中显示的命令顺序。这里我通过指出文件中的 icacls.exe 创建了一个保存文件。然后我通过简单地用 /restore 替代 /save 来尝试恢复它。由于恢复命令仅对目录进行操作,所以无法进行上述操作。支持修改的文件已在 acls.bin 文件中指定。为了恢复 ACL,我会在目录中而不是在文件中指出它。这就是我在最后一个命令执行的操作,在这里我将“.”指定为需要操作的对象。

Figure 1 保存和恢复 ACL

C:\Users\Jesper>icacls test.txt /save acls.bin
processed file: test.txt
Successfully processed 1 files; Failed processing 0 files

C:\Users\Jesper>icacls test.txt /restore acls.bin
test.txt\test.txt: The system cannot find the path specified
Successfully processed 0 files; Failed processing 1 files

C:\Users\Jesper>icacls . /restore acls.bin
processed file: .\test.txt
Successfully processed 1 files; Failed processing 0 files

另请注意,恢复命令必须以提升的权限运行!只有当您有权读取 ACL 时,才能以低级别管理员甚至标准用户的身份运行命令提示符中的保存命令。然而要恢复 ACL,您需要有一个完整又纯粹的管理令牌。

替代 SID

icacls.exe 中另一个很有用的功能是可以用一个用户的权限替换另一个用户的权限。这通过使用 /substitute 开关在恢复期间完成。替代开关的文档中声称需要一个 SID,但是后来有说明实际上也可以是一个常规用户名。这样,图 2 中显示的顺序就能够工作了。

Figure 2 恢复期间替代 SID

C:\Users\Jesper>icacls test.txt
test.txt VistaRC2-Test\foo:(R,W)
    VistaRC2-Test\Jesper:(I)(F)
    NT AUTHORITY\SYSTEM:(I)(F)
    BUILTIN\Administrators:(I)(F)

Successfully processed 1 files; Failed processing 0 files

C:\Users\Jesper>icacls test.txt /save acls.bin
processed file: test.txt
Successfully processed 1 files; Failed processing 0 files

C:\Users\Jesper>icacls. /substitute foo bar /restore acls.bin
processed file: .\test.txt
Successfully processed 1 files; Failed processing 0 files

C:\Users\Jesper>icacls test.txt
test.txt VistaRC2-Test\bar:(R,W)
    VistaRC2-Test\Jesper:(I)(F)
    NT AUTHORITY\SYSTEM:(I)(F)
    BUILTIN\Administrators:(I)(F)

Successfully processed 1 files; Failed processing 0 files

正如您看到的那样,我以之前就有的同一个 ACL 结束,但是用来指定 foo 权限的 ACE 现在用来指定 bar 的权限。

更改所有者

多年以来,这个 chown 工具已成为 UNIX 系统上的装订器。Windows 最初没有更改对象所有者的内置方法。后来在资源工具包中出现了 SetOwner 工具。再后来,Windows NT 4.0 中出现了 takeown.exe 工具,但是这个实用工具仅允许您获取所有权,不允许将它授予其他用户,除非您有他们的密码。现在 icacls.exe 提供一种内置功能,让您可以为您有权设置其所有者的对象设置所有者:

C:\>icacls c:\test /setowner foo
processed file: c:\test
Successfully processed 1 files; Failed processing 0 files

遗憾的是,icacls.exe 不能为您显示对象的所有者。实际上没有办法从命令行看出对象的所有者是谁。而且,如果您保存对象的 ACL,就不会保存对象的所有者。

icacls.exe 还有一个 bug,即不能调用 SeTakeOwnershipPrivilege 来更改所有者。如果您有权根据 ACL 更改对象的所有者,那 icacls.exe 就会按照指定方式运行。然而,如果您是管理员,但无权根据对象的 ACL 更改该所有者,那么就会因为那个 bug 而无法使用 icacls.exe 执行此操作。在这种情况下,您需要使用 takeown.exe 工具,它可以调用 SeTakeOwnershipPrivilege,但是仅可以更改您帐户或管理员群组的所有者,而不是任意帐户的所有者:

C:\>takeown /f c:\test

SUCCESS: The file (or folder): “c:\test” now owned by user “JJ-VistaRTMTst\Jesper”.

当然,还应该注意 subinacl 工具,它可以从 Microsoft 下载中心下载,还有 setowner 开关。在很多情况下,Subinacl 的工作方式实际上比 icacls 更直观,但使用起来却也复杂得多。

查找特定用户的文件

Icacls 还有另一个有用的功能:可以找到有特定用户权限的文件。例如:

C:\windows\system32>icacls “c:\program files” /findsid jesper /t

SID Found: c:\program files\Passgen\
passgen.exe.
Successfully processed 1808 files; Failed processing 0 files

如果您想尝试找出特定用户可能有权执行的操作,这个功能将非常有用。

重置和更改 ACL

如果 ACL 已遭破坏或损坏,icacls.exe 有办法将其重置为从父项继承。这在 2006 年秋季爆发的零天安全性问题期间非常有用。用来缓解 Windows 组件中的这个问题的一种方法就是拒绝“每个人”访问对象的权限。这部分非常简单,但是使用 Windows XP 和 Windows Server 2003 中的内置工具来删除访问控制项 (ACE) 几乎是不可能的。不过在 Windows Vista 中,您只需要运行下面的命令:

C:\windows\system32>icacls “c:\program files\passgen\passgen.exe” /reset

processed file: c:\program files\passgen\passgen.exe
Successfully processed 1 files; Failed processing 0 files

当然,Icacls.exe 可以执行所有的标准授权/拒绝/删除操作。列表中真正新增的唯一项目是删除。使用这个开关,您可以删除所有允许 ACE 和所有拒绝 ACE,或者来自特定对象或层次结构的指定用户的允许 ACE 和拒绝 ACE。图 3 显示了一些不同的授权、删除和拒绝操作的示例。

Figure 3 授权、拒绝和删除操作

C:\>icacls c:\test /grant foo:(F)
processed file: c:\test

Successfully processed 1 files; Failed processing 0 files

C:\>icacls c:\test
c:\test JJ-VistaRTMTst\foo:(F)
    BUILTIN\Administrators:(I)(F)
    BUILTIN\Administrators:(I)(OI)(CI)(IO)(F)

Successfully processed 1 files; Failed processing 0 files

C:\>icacls c:\test /remove:g foo
processed file: c:\test
Successfully processed 1 files; Failed processing 0 files

C:\>icacls c:\test
c:\test BUILTIN\Administrators:(I)(F)
    BUILTIN\Administrators:(I)(OI)(CI)(IO)(F)

Successfully processed 1 files; Failed processing 0 files

C:\>icacls c:\test /deny foo:(F)
processed file: c:\test
Successfully processed 1 files; Failed processing 0 files

C:\>icacls c:\test
c:\test JJ-VistaRTMTst\foo:(N)
    BUILTIN\Administrators:(I)(F)
    BUILTIN\Administrators:(I)(OI)(CI)(IO)(F)

Successfully processed 1 files; Failed processing 0 files

C:\>icacls c:\test /remove:d foo
processed file: c:\test
Successfully processed 1 files; Failed processing 0 files

C:\>icacls c:\test
c:\test BUILTIN\Administrators:(I)(F)
    BUILTIN\Administrators:(I)(OI)(CI)(IO)(F)

Successfully processed 1 files; Failed processing 0 files

如果您想将某一对象的访问权开放给特定组或用户,仅删除拒绝 ACE 的功能可能很有用。

设置完整性级别

Icacls.exe 还有显示和设置完整性级别的功能。Windows Vista 支持在对象上放置完整性标签。Icacls.exe 是可以用来执行该操作的命令行工具:

C:\>icacls c:\test /setintegritylevel high

processed file: c:\test
Successfully processed 1 files; Failed processing 0 files

C:\>icacls c:\test
c:\test BUILTIN\Administrators:(I)(F)
    BUILTIN\Administrators:(I)(OI)(CI)(IO)(F)
    Mandatory Label\High Mandatory Level:(NW)

Successfully processed 1 files; Failed processing 0 files

注意如果对象有一个显示设置,icacls.exe 仅显示完整性标签。大多数的文件都不会这样,因此您也很难看到这样的情况。

最后,icacls.exe 可以验证对象是否具有规范 ACL。如前面所述,大家都知道第三方工具会在 ACL 中以错误的顺序放置 ACE。Icacls.exe 可以验证和修复那些类型的问题,如下所示:

C:\>icacls c:\test /verify
processed file: c:\test

Successfully processed 1 files; Failed processing 0 files

ACL UI

ACL UI 或 ACL 用户界面已从 Windows XP 中的 ACL UI 进行了细微的修改。图 4 和图 5 分别显示了 Windows XP 和 Windows Vista 的 ACL UI 对话框。

图 4 Windows XP 中的 ACL UI 对话框

图 4** Windows XP 中的 ACL UI 对话框 **

图 5 Windows Vista 中的 ACL UI 对话框

图 5** Windows Vista 中的 ACL UI 对话框 **

正如您看到的那样,它们有一些不同。首先,对话框最终会清楚地显示您操作的对象,如果您同时对好几个对象进行操作,此对话框将非常有用。其次,底部还有一些帮助的超链接。但是,最值得注意的变化是删除了“添加”和“删除”按钮,替代它们的是大力支持 Windows Vista 中用户访问控制 (UAC) 的“编辑”按钮。正如您在该按钮上的盾牌旁边看到的那样,启动该对话框的用户无权编辑 ACL,因此在她可以编辑权限之前需要提升。注意,如果您在 C: 驱动器的根目录创建了文件夹并立即检查它的属性,它就可能不是默认值。作为文件夹的所有者,您将有编辑 ACL 的隐式权限,盾牌会消失。表示 COM Moniker 的盾牌是用来为一部分运行的进程启动提升提示的机制。如果单击“编辑”按钮,会看到一个熟悉的提升对话框,如果单击提升对话框中的“继续”,就会看到一个和您在 Windows XP 单击“添加”按钮后所看到的一样的对话框。ACL UI 在很多地方都遵循这个双对话框概念;您在提升之前都会看到对话框,提升后,就会看到 Windows 的先前版本中熟悉的老对话框。

如果先单击“高级”按钮,然后是“审核”选项卡,始终会有一个提升按钮,如图 6 所示。不可以在没有提升的情况下修改审核,即使您拥有对象的完全控制权限,或者您是所有者。那是因为,修改对象 SACL 的能力由 SE_SECURITY_NAME 特权掌握,在 GUI 工具中称为“管理审核和安全日志”。默认情况下,仅管理员具有该权限。但是,在管理员审批模式下(启用 UAC 时),会删除管理员的特权,即使您是管理员也需要提升。

图 6 修改 Windows Vista 中的审核设置始终需要提升

图 6** 修改 Windows Vista 中的审核设置始终需要提升 **

最后要注意的是当您修改 ACL 时的提升要求:所有这些语句对于未禁用的 UAC 都是临时的。如果您禁用 UAC,所有的行为会转换为您在 Windows XP 进行的行为,除了对话框看起来不一样以外。但是,如果自从您的令牌具有 Administrators SID 以来您一直都是以管理员的身份登录,就不会要求提升。

其他工具

Icacls.exe 是一项很有用的工具,它在 cacls.exe 基础上进行了很多改进,但仍存在一些缺点。也许最值得注意的是它不能管理对象的访问权,而不是文件和目录的访问权。Windows Vista 相对于 Windows XP 而言,只对其他对象的 ACL 进行了细微的更改,但是需要管理服务、注册表项或 Active Directory® 对象的 ACL 的情况仍有发生。

如果您是命令行发烧友,就需要 subinacl.exe 来执行此操作。Subinacl.exe 是一种支持工具,也可在下载中下载。

尽管 subinacl.exe 比较容易使用,我还是必须给您一些警告。实际上,它有时候非常迟钝。但是,subinad.exe 是管理访问控制的强大工具。每个超级管理员都需要这个工具。

注册表 ACL

注册表 ACL 与文件系统 ACL 一样,曾发生过变化。尽管它变化的范围对比文件系统的变化要小得多。与以前版本的 Windows 最明显的不同在于,由于 Power Users 的排斥,几乎所有的 Power User ACE 都消失了。Power Users 并不比其他用户强大。尽管我们知道 ACL 真的是有些复杂,但是实际上不是所有的 Power Users 的 ACE 都消失了。只是不幸的是有一些丢失了。

当您查看注册表中的 ACL 时,在很多地方都会看到名为 RESTRICTED 的 SID 的 ACE。这对于 Windows Vista 并不新鲜,但它是一个很有趣又很难理解的 SID。RESTRICTED SID 表示提供受限令牌的任何进程。受限令牌可通过使用 CreateRestrictedToken API 的特殊功能来创建。这类令牌有一个或多个限制 SID——用于单独访问检查的 SID。假如我们有一个使用受限令牌运行的进程。如果该进程试图使用 RESTRICTED SID 的 ACE 访问对象,Windows 就会真正执行两项访问检查。第一项是普通访问检查。第二项的工作方式几乎与第一项一样,但是仅针对令牌中的限制 SID。两项访问检查都必须通过。

目前有好几个使用 RESTRICTED SID 的 ACL,特别是在注册表中。这个 ACL 的屏幕截图如图 7 所示。

图 7 几个地方的注册表 ACL 都包含 RESTRICTED 的 ACE

图 7** 几个地方的注册表 ACL 都包含 RESTRICTED 的 ACE **

此时,很少会有进程使用受限令牌功能,特别是涉及限制 SID 时。使用受限令牌功能的进程的示例是安装了 Windows 防火墙、基本筛选引擎和诊断策略服务的服务进程。它还使用限制写入的令牌。根据我的发现,Windows Vista 目前仅有九个服务使用 RESTRICTED 和限制写入的令牌。

正如最新先前版本的 Windows 一样,关于注册表权限的最佳实践是小心行事。除了在特殊和目的性较强的情况下之外,请不要修改注册表中的权限。考虑到复杂的继承模式以及对注册表执行的敏感操作,如果您不小心修改了注册表中的 ACL,就很可能会遇到无法接受的致命故障。

总结

和大多数的 Windows 版本一样,Windows Vista 中的访问控制做了一些细微的更改。但是,不像某些其他最新的版本,实际上还是有一些较小的更改,它们会添加到相当重要的行为更改中。特别是 UAC 要求的几个更改,例如完整性标签和对 ACL UI 的修改。此外,我们还对已记录的历史记录中的 ACL 进行了首次大清理。

在很多方法中,Windows 上的默认 ACL 实际上比 Windows Vista 中的要简单,因为之前有很多功能都没有。但是和先前的版本一样,您真的应该仔细研究访问控制,直到彻底了解它。特别是对于新版本的操作系统。希望通过使用本文介绍的工具,您可以轻松地了解 ACL。

Jesper M. Johansson 是解决软件安全问题的首席安全工程师,以及《TechNet 杂志》的特约编辑。他拥有 MIS 博士学历,具有 20 多年的计算机安全方面的经验。本专栏改编自 Roger Grimes 和 Jesper Johansson 的新书“Windows Vista Security: Securing Vista Against Malicious Attacks”(Windows Vista 安全性:保护 Vista 免遭恶意攻击)(Wiley, 2007)。

© 2008 Microsoft Corporation 与 CMP Media, LLC.保留所有权利;不得对全文或部分内容进行复制.