• ACL 访问控制列表
  • ACE 访问控制条目
  • DACL 任务访问控制列表

访问控制列表 (ACL)

(ACL) 是适用于对象的安全保护列表。 (对象可以是文件、进程、事件或其他任何具有安全描述符.) ACL 是由一个一个访问控制项 (ACE) 组成的

访问控制条目 (ACE)

  1. 每一个 ACE 控制或监视指定对象的访问
  2. 每一个 ACE 都包含以下信息:
    • 安全标识符 SID ,用于标识 ACE 应用的对象
    • 一个访问掩码,用于指定 ACE 控制的访问权限
    • 指示 ACE 类型的标志位
    • 一组位标志,用于确定子容器或对象是否可以从附加 ACL 的主对象继承 ACE
  • 访问掩码: 一个 32 位值,用于指定 ACE 中允许或拒绝的权限,访问掩码还用于在打开对象时请求访问权限。

DACL 和 ACE

如果 Windows 对象没有 DACL 则系统允许所有人访问,如果对象具有 DACL 则只允许 ACE 允许的项访问,同样,如果 DACL 具有指定允许访问有限用户或组集的 ACE,则系统会隐式拒绝对非 ACE 中包含的所有受托人的访问权限。

AccessCheck 工作原理

现在我们已经知道了关于 ACL、ACE、DACL 那么当一个服务去访问对象时,系统是如何检查的?

当服务查看查看一个对象时,系统会将每个 ACE 中的 SID 与访问令牌中的信息 SID, 进行比对,知道发生以下事情:

  • 拒绝访问的 ACE 中存在对令牌中的 SID 的访问权限
  • 在 ACE 中存在对应的允许条目,则会授予所有条目的权限集合
  • 检查完所有 ACE ,没有找到对应的条目,则隐式拒绝访问

举例

在大部分情况下,我们可以使用允许访问的 ACE 来控制对对象的访问,无需显式拒绝对对线的访问, 一个例外是 ACE 允许访问组,举个例子:

现在假设有一个密码文件,我们允许 A 组成员编写查看,这时有一个用户 Andrew 是 A/B/C 组成员,我们不想让其查看到这个密码文件,但是 Andrew 又是 A 组成员,那么该如何拒绝呢?

我们可以在组允许访问 ACE 前加一个 Andrew 拒绝 ACE ,这样当 Andrew 查看该文件时,先读取到拒绝权限,直接返回拒绝,不在查看其他 ACE, 这就凸显出 ACE 顺序的重要性

ACL%26ACE - 图1

对于线程 A,系统读取 ACE 1 并立即拒绝访问,因为拒绝访问的 ACE 适用于线程访问令牌中的用户。 在这种情况下,系统不会检查 ACE 2 和 3。 对于线程 B,ACE 1 不适用,因此系统会转到 ACE 2,这允许写入访问,ACE 3 允许读取和执行访问权限。

ACE 顺序

我们知道当一个服务去查看一个对象时,会将服务访问令牌的 SID 和对象 DACL 中的 ACE 进行比对,比对的顺序是按照 DACL 中排序规定的,并且排序也具有一定的要求,当排序失误时,会导致一些错误的产生,所以对于 ACE 的顺序按照以下要求配置:

  1. 所有显式 ACE 都放置在任何继承的 ACE 之前。
  2. 在显式 ACE 组中,访问被拒绝的 ACE 放置在允许访问的 ACE 之前。
  3. 继承的 ACE 按继承顺序排列。 从子对象的父级继承的 ACE 先来,然后从祖父母继承的 ACE,依此类传对象树。
  4. 对于每个继承的 ACE 级别,访问被拒绝的 ACE 放置在允许访问的 ACE 之前。

扩展

1. 如果 ACE 顺序配置不当会如何?

ACL%26ACE - 图2

我们知道这里的 Andrew 之所以不能访问是因为第一个条目是拒绝,但是如果我们将条目顺序换为: 213 会怎么样,这里 ACE 2 是授予 A 组访问权限,那么 Andrew 会直接获取权限,ACE 1 条目则失效