2. ACL数据结构:ACE、ACL与SID
聊ACL,绕不开它的三个核心零件:ACE、ACL和SID。我刚开始接触Windows权限时,总把ACE和ACL搞混——后来发现,搞懂它们的关系,权限控制就通了一半。
2.1 安全标识符(SID)——权限世界的身份证
SID,全称Security Identifier。说白了,它就是系统里每个安全主体的唯一编号。你想想看,系统怎么知道“张三”是谁?靠用户名?用户名可以改。靠密码?密码会变。SID才是真正不变的标识。
每个用户、每个组、甚至每台计算机,在创建时都会得到一个唯一的SID。这个值在系统内部是全局唯一的,不会重复。
SID的结构长什么样?
一个典型的SID长这样:
S-1-5-21-3623811015-3361044348-30300820-1013
我来拆开给你看:
| 部分 | 含义 | 示例值 |
|---|---|---|
| S | 固定前缀,表示这是一个SID | S |
| 1 | 修订版本号,目前固定为1 | 1 |
| 5 | 标识符颁发机构(Authority) | 5 = NT Authority |
| 21-...-1013 | 子颁发机构(Subauthorities) | 域标识符 + RID |
最后那串数字里的最后一个——1013,叫RID(Relative Identifier)。它是在域或本地范围内唯一标识用户或组的编号。
whoami /user 或 wmic useraccount get name,sid 快速查SID。有一次客户说“管理员账号删不掉”,我一查SID,发现根本不是内置管理员,而是个同名假账号。
常见的特殊SID
系统里有一些预定义的SID,我列几个你一定会遇到的:
| SID | 名称 | 说明 |
|---|---|---|
| S-1-0-0 | Null SID | 空标识,一般用不到 |
| S-1-1-0 | Everyone | 所有人,包括匿名用户 |
| S-1-5-18 | Local System | 本地系统账户,权限极高 |
| S-1-5-32-544 | Administrators | 本地管理员组 |
| S-1-5-32-545 | Users | 本地用户组 |
2.2 ACL条目(ACE)——权限的最小单元
ACE,Access Control Entry。它是ACL里的每一条规则。你可以把它理解成一张小卡片,上面写着:谁可以做什么。
一个ACE包含三个关键信息:
- SID:哪个用户或组
- 权限掩码:允许或拒绝哪些操作(读、写、执行等)
- 类型:允许型还是拒绝型
ACE的两种类型
| 类型 | 含义 | 优先级 |
|---|---|---|
| 允许型(Access Allowed) | 授予指定SID某些权限 | 低 |
| 拒绝型(Access Denied) | 明确禁止指定SID某些权限 | 高 |
这里有个关键点:拒绝型ACE永远排在允许型ACE前面。系统检查权限时,先看有没有拒绝规则,再看允许规则。一旦匹配到拒绝,直接返回“无权限”,不再继续检查。
核心原则: 拒绝优先于允许。这是ACL权限判断的铁律。
ACE的继承机制
在NTFS文件系统中,ACE可以被子文件夹和子文件继承。继承标志有几种:
- 容器继承(OI):子文件夹继承此ACE
- 对象继承(CI):子文件继承此ACE
- 只继承(IO):此ACE只作用于子对象,不作用于当前对象
- 不继承(NP):子对象不继承此ACE
举个例子:你给D盘根目录的“销售部”组设置了“读取”权限,并勾选了“应用到子文件夹和文件”。那么D盘下所有文件和文件夹都会继承这个ACE。这就是继承的实际效果。
2.3 访问控制列表(ACL)——ACE的集合
ACL,Access Control List。它就是一组ACE的列表。每个安全对象(文件、文件夹、注册表键、打印机等)都关联着一个ACL。
ACL分为两种:
| 类型 | 全称 | 作用 |
|---|---|---|
| DACL | 自由访问控制列表 | 控制谁可以做什么(读、写、执行等) |
| SACL | 系统访问控制列表 | 控制哪些操作需要被审计(记录日志) |
平时我们说的“改权限”,改的就是DACL。SACL一般用于安全审计场景,比如记录谁删除了重要文件。
ACL的内部结构
一个ACL在内存中的布局大致如下:
ACL Header (8字节)
- 修订版本
- 大小
- ACE数量
ACE #1 (拒绝型)
- SID: S-1-5-32-544 (Administrators)
- 权限: 完全控制
- 标志: 0x00
ACE #2 (允许型)
- SID: S-1-5-21-...-1013 (张三)
- 权限: 读取 + 写入
- 标志: 0x09 (OI|CI|IO)
ACE #3 (允许型)
- SID: S-1-1-0 (Everyone)
- 权限: 读取
- 标志: 0x00
注意顺序:拒绝型ACE在前,允许型ACE在后。这是Windows强制要求的排序规则。
SetSecurityInfo 时踩了这个坑——ACE顺序不对,权限设置失败。
2.4 三者的关系——一张图说清楚
下面这张图展示了SID、ACE、ACL和Security Object之间的关系:
从这张图可以看得很清楚:一个安全对象关联一个ACL,ACL里包含多个ACE,每个ACE绑定一个SID。这就是ACL权限控制的完整数据链路。
2.5 实战:用PowerShell查看ACL
光说不练假把式。我们直接上手看看真实系统的ACL长什么样:
# 查看文件或文件夹的ACL
Get-Acl -Path "C:\MyFolder" | Format-List
# 只看DACL中的ACE
(Get-Acl -Path "C:\MyFolder").Access | Format-Table IdentityReference, FileSystemRights, AccessControlType, IsInherited -AutoSize
输出示例:
IdentityReference FileSystemRights AccessControlType IsInherited
----------------- ---------------- ----------------- -----------
BUILTIN\Users ReadAndExecute Allow True
BUILTIN\Admin... FullControl Allow True
张三 Modify Allow False
看到没?每一行就是一个ACE。IdentityReference就是SID对应的用户名,FileSystemRights是权限,AccessControlType是允许还是拒绝。
Get-Acl | Format-List。先看ACL里有没有拒绝型ACE,再看允许型ACE的顺序。很多“明明有权限却访问不了”的问题,都是拒绝型ACE在作怪。
2.6 本章小结
来,我们捋一下:
- SID 是身份标识,每个用户/组唯一
- ACE 是权限规则,告诉系统谁可以做什么
- ACL 是ACE的集合,挂在每个安全对象上
- 拒绝型ACE优先级高于允许型ACE
- ACE的继承标志控制权限是否向下传播