- ACL 访问控制列表
- ACE 访问控制条目
- DACL 任务访问控制列表
访问控制列表 (ACL)
(ACL) 是适用于对象的安全保护列表。 (对象可以是文件、进程、事件或其他任何具有安全描述符.) ACL 是由一个一个访问控制项 (ACE) 组成的
访问控制条目 (ACE)
每一个 ACE 控制或监视指定对象的访问
- 每一个 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 顺序的重要性
对于线程 A,系统读取 ACE 1 并立即拒绝访问,因为拒绝访问的 ACE 适用于线程访问令牌中的用户。 在这种情况下,系统不会检查 ACE 2 和 3。 对于线程 B,ACE 1 不适用,因此系统会转到 ACE 2,这允许写入访问,ACE 3 允许读取和执行访问权限。
ACE 顺序
我们知道当一个服务去查看一个对象时,会将服务访问令牌的 SID 和对象 DACL 中的 ACE 进行比对,比对的顺序是按照 DACL 中排序规定的,并且排序也具有一定的要求,当排序失误时,会导致一些错误的产生,所以对于 ACE 的顺序按照以下要求配置:
- 所有显式 ACE 都放置在任何继承的 ACE 之前。
- 在显式 ACE 组中,访问被拒绝的 ACE 放置在允许访问的 ACE 之前。
- 继承的 ACE 按继承顺序排列。 从子对象的父级继承的 ACE 先来,然后从祖父母继承的 ACE,依此类传对象树。
- 对于每个继承的 ACE 级别,访问被拒绝的 ACE 放置在允许访问的 ACE 之前。
扩展
1. 如果 ACE 顺序配置不当会如何?
我们知道这里的 Andrew 之所以不能访问是因为第一个条目是拒绝,但是如果我们将条目顺序换为: 213 会怎么样,这里 ACE 2 是授予 A 组访问权限,那么 Andrew 会直接获取权限,ACE 1 条目则失效