icacls.exe 是 NTFS 安全描述符的命令行管理工具,封装 Win32 API:GetNamedSecurityInfo / SetNamedSecurityInfo,读取、修改对象安全描述符;只支持 NTFS 文件系统,NTFS DACL/SACL 访问控制列表命令行工具,在 PowerShell 中, 下面是 icacls 命令和 PowerShell 对应命令的对比:
icacls.exe 拆解解构
适用:Windows Vista / Win10 / Win11 / Server2008‑2025;NTFS DACL/SACL 访问控制列表命令行工具,替代老旧
cacls.exe分析框架:底层原理|依赖文件|依赖关系|配套链|逻辑链路|边界
一、底层原理
icacls.exe 是 NTFS 安全描述符的命令行管理工具。
- NTFS 文件 / 文件夹每个对象携带安全描述符 Security Descriptor,包含:所有者 (Owner)、组 (Group)、DACL (自主访问控制列表,谁允许 / 拒绝访问)、SACL (系统访问控制列表,审计 ACE)。
- icacls 封装 Win32 API:
GetNamedSecurityInfo/SetNamedSecurityInfo,读取、修改对象安全描述符;只支持 NTFS 文件系统;FAT32/exFAT 无安全描述,icacls 对其无效。
核心能力:
- 查询文件 / 目录 DACL、SACL、所有者;
- 设置权限、继承标志;
- 备份 / 恢复 ACL;
- 重置子对象继承权限;
- 设置审计 SACL;
注意:icacls不修改文件内容,只操作元数据安全描述符;老工具
cacls.exe已被废弃,对现代继承、SACL 支持不全。
权限标志缩写: F完全访问,M修改,RX读取执行,R只读,W写入; 继承标志:(OI)对象继承、(CI)容器继承、(IO)仅继承,(NP)不传播继承。
二、依赖文件
| 文件 | 作用 |
|---|---|
icacls.exe |
主可执行程序,命令行入口,参数解析,调用 Win32 安全 API |
advapi32.dll |
Windows 高级安全 API;GetNamedSecurityInfo/SetNamedSecurityInfo 实现主体 |
kernel32.dll |
文件对象打开、路径解析 |
sspicli.dll |
SID、账户名称 <-> 安全标识符互相转换(账户名转 SID、SID 解析显示用户名) |
ntfs.sys |
内核层 NTFS 驱动,最终把安全描述持久化存储到磁盘元数据;API 只是提交请求,真正落盘由 ntfs.sys 完成 |
备份 ACL 导出文件:
.acl文本文件,icacls /save 输出;/restore 读取该文件恢复权限。 该 acl 是 icacls 自定义文本格式,不是标准二进制安全描述符,只能由 icacls 解析。
三、依赖关系
硬性依赖
- 文件系统:必须 NTFS;FAT32、exFAT、网络 SMB 共享 (远端 FAT) 无法保存安全描述,设置会静默失败。
- 权限前提:
- 查询 DACL:对象的读取安全信息 READ_CONTROL权限;普通用户一般可以读取。
- 修改 DACL:需要
WRITE_DAC权限。 - 修改所有者:需要
WRITE_OWNER;取得所有权需要管理员权限,开启 SeRestorePrivilege、SeSecurityPrivilege 特权。 - 修改 SACL 审计规则:必须管理员,启用
SeSecurityPrivilege特权。
- SID 解析依赖本地 SAM 或者域 DC:域账号 SID 需要域控可解析,离线环境只能显示 SID 字符串,无法翻译为账户名。
核心参数速览
| 参数 | 功能 | ||
|---|---|---|---|
icacls file |
查询 DACL 权限 | ||
/grant user:perm |
授予权限 | ||
/deny user:perm |
拒绝权限 | ||
| `/inheritance:e | d | r` | 继承:e 启用继承;d 禁用继承并复制 ACE;r 移除所有继承 ACE |
/setowner user |
设置对象所有者 | ||
/setacl |
直接替换完整 ACL | ||
/save aclfile /t |
递归保存整个目录树 ACL 配置到 acl 文件 | ||
/restore aclfile /t |
从备份文件恢复 ACL | ||
/reset /t |
重置:从父项重新继承权限,清除自定义 ACE | ||
/t |
递归处理所有子文件夹、子文件 | ||
/c |
遇到错误继续执行,不中断批量操作 | ||
/q |
静默,不输出成功信息 |
依赖调用链条
icacls.exe 解析命令行参数
↓
advapi32.dll → GetNamedSecurityInfo / SetNamedSecurityInfo Win32安全API
↓
内核层 → ntfs.sys 将安全描述符写入NTFS文件元数据
↓
返回结果;icacls格式化输出账户名+权限+继承标志
四、配套链
完整权限操作时序链
- 读取权限:
icacls D:\data→ API 读取安全描述 → SID 翻译为用户名 →控制台打印 DACL。 - 批量备份权限流水线
icacls D:\data\* /save D:\backup\data.acl /t /c
- 批量恢复权限流水线
icacls D:\data /restore D:\backup\data.acl /t /c
配套相关工具 / API
cacls.exe:旧版废弃工具;缺少 SACL、完整继承支持,不建议使用。- PowerShell
Get‑Acl / Set‑Acl:PowerShell 包装,底层同样调用advapi32安全 API,输出对象化安全描述符,适合脚本编程。 - 资源管理器安全选项卡:图形界面,底层 API 与 icacls 完全同源。
- 相关特权:SeSecurityPrivilege(操作 SACL 审计)、SeRestorePrivilege(强制设置权限、所有者)。
常用示例
# 查看目录权限
icacls D:\MyData
# 授予域用户修改权限,开启继承
icacls D:\MyData /grant "CONTOSO\user01:(M)" /t /c
# 禁用继承,复制已继承ACE为显式ACE
icacls D:\MyData /inheritance:d
# 重置权限,全部从父目录继承
icacls D:\MyData /reset /t /c
# 备份整个目录树ACL
icacls D:\MyData /save D:\acl_backup.acl /t /c
# 恢复ACL(注意:restore参数前面路径是目标根目录,不是acl文件路径!)
icacls D:\MyData /restore D:\acl_backup.acl /t /c
⚠️极易踩坑:
/restore第一个参数是目标文件夹路径,acl 文件名写在第二个参数;顺序颠倒直接异常。
五、逻辑链路
- icacls.exe 接收命令行参数,完成语法校验;非法权限标识、账号名直接报错退出。
- 打开目标文件 / 目录对象,申请对应访问权限:
READ_CONTROL读;WRITE_DAC / WRITE_OWNER写。 - 读模式(查询)
- 调用
GetNamedSecurityInfo获取对象安全描述符; - 将 SID 通过
sspicli.dll翻译为可读账户名称; - 解析 DACL ACE、继承标志;格式化输出控制台。
- 调用
- 写模式(grant /deny/setowner /reset)
- 修改内存中的安全描述符结构体;处理继承标志、ACE 合并逻辑;
- 调用
SetNamedSecurityInfo把修改提交给系统; - 内核 ntfs.sys 将安全描述持久写入 NTFS 元数据;
- /save 备份:递归遍历目录树,逐个读取每个对象 SD,以 icacls 自定义文本格式写入
.acl文件。 - /restore 恢复:读取 acl 备份文本,解析每个对象对应的 SD,遍历目标路径,逐个对象调用 SetNamedSecurityInfo 回写安全描述符。
- 返回 ERRORLEVEL 退出码。
关键点:icacls 本身不实现权限校验逻辑,只是调用系统 API;真正的权限判定在内核
ntfs.sys。
六、边界约束(高频坑点)
1 文件系统边界
- 仅 NTFS 支持安全描述;FAT32/exFAT、RAM 盘:可以执行 icacls 命令,但设置的权限不会持久保存,无实际效果。
- SMB 网络共享远端文件:操作的是远端服务器 NTFS 安全描述,受 SMB 共享权限 + NTFS 权限双重叠加约束;icacls 只能修改 NTFS DACL,不能修改 SMB 共享权限(共享权限用
net share/ PowerShellNew‑SmbShare)。
2 权限与特权边界
- 修改 SACL 审计(AUDIT),必须管理员,且需要启用
SeSecurityPrivilege;普通管理员默认该特权是关闭状态,icacls 执行会报错。 - 设置所有者
/setowner,需要 WRITE_OWNER 权限;强行夺取所有权需要管理员特权。 - 普通用户只能读取 DACL;无法修改所有者、SACL。
- UAC 开启情况下:必须以管理员身份运行 CMD/PowerShell,否则部分修改操作静默失败。
3 继承逻辑边界
/inheritance:e:启用继承(默认状态,子对象从父继承 ACE)/inheritance:d:禁用继承,但把继承来的 ACE 复制成为显式 ACE(最常用)/inheritance:r:禁用继承,并且删除全部继承 ACE,只保留本对象显式 ACE/reset:删除本对象自定义显式 ACE,完全恢复为从父继承状态。
坑:
/deny拒绝 ACE 优先级高于 grant 允许;拒绝 ACE 一旦存在优先拦截访问,排错时要重点检查拒绝项。
4 /save/restore 备份恢复边界
.acl是 icacls 自定义文本格式,不能直接拷贝到不同服务器直接恢复:域 SID 在跨域环境失效;本地账号 SID 在不同机器完全不一样。- restore 的时候路径结构必须和备份时目录层级保持一致;acl 文件内部记录相对路径,目录结构错位会恢复到错误对象。
/save只备份安全描述符(ACL、所有者),不备份文件内容、时间戳。
5 参数边界
/t递归:处理指定目录以及全部子目录、子文件;不加 /t 只处理目标对象本身。/c:遇到单个文件访问错误继续往下跑批量,不加 /c 遇到第一个错误直接终止整个批量任务;大规模目录批量操作强烈建议带上/c。- 账户名带空格必须英文双引号包裹;域账号格式
DOMAIN\account。
6 返回码
| Errorlevel | 含义 |
|---|---|
| 0 | 全部操作成功 |
| 1 | 语法参数错误 |
| 2 | 文件路径找不到 |
| 5 | 拒绝访问,权限不足 |
7 其他重要边界
- icacls 不会自动刷新资源管理器缓存;权限修改完成立刻生效,但图形界面可能需要 F5 刷新才显示最新 ACL。
- 卷根目录特殊继承行为:NTFS 卷根目录(D:\)有系统内置特殊 ACE,不要随意
/reset,容易破坏系统权限。 - SID 解析失败(域控离线):输出 SID 字符串如
S‑1‑5‑21‑xxxx,而不是账户名称,功能本身正常,只是无法翻译成显示名。 - icacls不能修改共享权限,很多人混淆「NTFS 权限」和「SMB 共享权限」,两者是两套独立控制。
排错提示: 批量权限修改异常,优先带上
/c完整跑完,再看输出报错; 怀疑权限错乱,使用icacls 路径 /t > acl_report.txt导出完整报告分析。
NTFS DACL / SACL 完整解构
定位:NTFS 文件系统上存储的安全描述符(Security Descriptor, SD),DACL 控制「谁能访问这个对象」,SACL 控制「哪些访问行为要被审计」。
核心关系:
Token(访问者身份) + SD(DACL/SACL对象规则)→ 送入内核 SRMSeAccessCheck,判定访问是否允许;和前面 Windows Token、AccessChk 形成完整权限判定链路。注意:SD 是安全模型概念,NTFS 只是把 SD 持久化存储在文件 MFT 元数据里;SRM 安全引用监视器才是权限裁决主体,NTFS 只负责存储、加载 SD。
一、底层原理
1. 安全描述符 SD 整体结构
SECURITY_DESCRIPTOR
├─ Owner SID:对象所有者SID
├─ Group SID:对象主组SID(NTFS传统保留,现代Windows很少用)
├─ DACL (Discretionary Access Control List) 自主访问控制列表
│ └─ ACE 访问控制条目集合(Allow / Deny ACE)
└─ SACL (System Access Control List) 系统访问控制列表
└─ Audit ACE 审计条目,触发安全事件日志
DACL(自主访问控制列表)
- 由对象所有者自主维护,决定哪些用户 / 组拥有哪些访问权限
- 条目叫 ACE(Access Control Entry),分两类:
ACCESS_ALLOWED_ACE:允许 SID 拥有指定掩码权限ACCESS_DENIED_ACE:拒绝 SID 拥有指定掩码权限
裁决顺序:Deny ACE 优先于 Allow ACE;列表从上往下匹配,一旦命中就终止。 空 DACL:无任何限制,所有人完全访问;NULL DACL(空指针):系统默认安全规则,和空 DACL 不一样。
SACL(系统访问控制列表)
- 系统层面的审计规则,不是访问控制;用来记录访问行为到安全事件日志(EventLog Security)
- ACE 类型:
SYSTEM_AUDIT_ACE - 触发条件:成功访问 / 失败访问;当 Token 尝试访问对象,匹配 SACL 的 ACE,就写入安全审计日志
- 读取 / 修改 SACL 需要特权:
SeSecurityPrivilege(极高权限,默认只有系统账号持有)
2. NTFS 存储载体:MFT(主文件表)
NTFS 每个文件 / 目录在 MFT 里占一条 MFT 记录。 MFT 属性 $SECURITY_DESCRIPTOR 保存 SD。 为了节省磁盘空间,NTFS 做安全描述符缓存池(Security Descriptor Cache / $SECURITY 元文件):
- 多个文件如果 SD 完全相同,只在
$SECURITY存一份 SD,MFT 记录只存索引引用 - 大量文件继承相同权限时,大幅节约磁盘空间
继承(Inheritance)机制:目录新建子文件 / 子目录,默认继承父目录 DACL/SACL 的 ACE;ACE 带继承标志(
CONTAINER_INHERIT/OBJECT_INHERIT)控制是否向下传递。 继承不是实时同步:是创建对象那一刻复制 ACE;后续父目录 DACL 修改,不会自动更新已经存在的子对象(除非手动传播)。
3. 权限裁决完整逻辑(和 Token 联动)
- 进程发起文件 IO(ReadFile/CreateFile),携带线程有效 Token
- I/O 管理器转发到 NTFS 驱动,取出目标文件 MFT 内的 SD(DACL+SACL)
- 内核 SRM 调用
SeAccessCheck(Token, SD, 申请访问掩码)- 遍历 DACL 的 ACE,匹配 Token 内 UserSID+GroupSID
- 先匹配 Deny,再匹配 Allow
- 同时检查 SACL:如果本次访问命中审计 ACE,生成安全审计事件
- 返回
GrantedAccess允许权限掩码;无匹配 ACE,默认拒绝访问 - NTFS 根据裁决结果,允许 / 拒绝本次文件 IO
AccessChk 工具本质就是:读取对象 SD,传入指定账号 Token,调用
AccessCheck,输出有效权限。
二、依赖文件 & 依赖链
DACL/SACL 是安全模型,不是独立文件;分为两大部分:安全子系统(SRM) + NTFS 文件系统驱动。
一级依赖
- ntoskrnl.exe
- SRM 安全引用监视器,
SeAccessCheck、SeQuerySecurityDescriptorInfo、SeSetSecurityDescriptorInfo内核安全函数 - 安全描述符解析、ACE 校验、审计事件生成
- SRM 安全引用监视器,
- ntfs.sys(NTFS 文件系统驱动)
- 读取 / 写入 MFT 里
$SECURITY_DESCRIPTOR属性;维护$SECURITY全局 SD 缓存池 - 处理 SD 继承逻辑;文件打开时取出 SD,交给 SRM 做访问检查
- 读取 / 写入 MFT 里
- advapi32.dll(Win32 安全 API)
GetNamedSecurityInfo/SetNamedSecurityInfo:获取 / 设置文件对象 SD(DACL/SACL)GetSecurityDescriptorDacl/GetSecurityDescriptorSacl:解析 SD 内部 DACL/SACLConvertStringSecurityDescriptorToSecurityDescriptor:SDDL 字符串转二进制 SD
- ntdll.dll
- NTAPI 桩:
NtQuerySecurityObject、NtSetSecurityObject,用户态到内核 syscall 入口
- NTAPI 桩:
- lsass.exe
- SID 解析,LookupAccountSid,把 SID 翻译成用户名(权限查看工具依赖)
二级依赖链(用户态读取文件 DACL)
用户程序/AccessChk
↓ advapi32.dll GetNamedSecurityInfo
↓ ntdll.dll NtQuerySecurityObject
↓ syscall → ntoskrnl.exe SRM
↓ ntfs.sys
↓ 读取MFT $SECURITY_DESCRIPTOR 属性
内核配套组件
clfs.sys:安全日志存储,SACL 审计事件写入安全日志sam.sys:本地账号 SID 数据库,SID 解析eventlog:安全事件日志服务,接收 SACL 审计事件
三、完整调用链
场景 1:读取 NTFS 文件 DACL(AccessChk / Explorer 安全选项卡)
1. 调用 GetNamedSecurityInfoW,指定文件路径,请求DACL/SACL/Owner信息
2. advapi32 封装调用 NtQuerySecurityObject
3. 系统调用进入ntoskrnl,SRM转发请求到ntfs.sys
4. ntfs.sys读取目标文件MFT记录,取出$SECURITY_DESCRIPTOR
5. ntfs从$SECURITY缓存池取出完整SD
6. SRM校验调用者是否拥有READ_CONTROL权限(读取SD需要这个权限)
7. SD数据返回用户态;advapi32解析SD,分离DACL、SACL、Owner
8. 遍历DACL的ACE,LookupAccountSid把SID翻译成账号名称
9. 返回给工具展示(AccessChk输出权限,资源管理器安全标签页)
场景 2:修改文件 DACL(资源管理器权限编辑)
1. 用户编辑安全权限,生成新DACL
2. SetNamedSecurityInfoW,传入新SD
3. NtSetSecurityObject syscall进入内核
4. SRM校验调用者是否拥有WRITE_DAC权限;修改SACL需要SeSecurityPrivilege
5. ntfs.sys接收新SD,写入MFT的$SECURITY_DESCRIPTOR,更新$SECURITY缓存
6. 如果设置继承标志,可选择将DACL传播到子目录/子文件
场景 3:文件访问触发权限检查(CreateFile 打开文件)
1. 应用调用CreateFile,请求读/写权限
2. I/O管理器调用ntfs.sys定位文件MFT记录,取出SD
3. 获取当前线程有效Token
4. SRM SeAccessCheck(Token, SD, DesiredAccess)
5. 同时检查SACL,匹配则生成审计事件,写入安全日志
6. 返回允许掩码;拒绝则返回STATUS_ACCESS_DENIED
核心 API 清单
Win32 advapi32
- GetNamedSecurityInfo / SetNamedSecurityInfo:获取 / 设置命名对象安全描述符(文件、注册表、内核对象通用)
- GetSecurityDescriptorDacl / GetSecurityDescriptorSacl:提取 DACL/SACL
- GetAce:遍历 ACE 条目
- ConvertStringSecurityDescriptorToSecurityDescriptor:SDDL 字符串解析
NTAPI ntdll
- NtQuerySecurityObject
- NtSetSecurityObject
内核 SRM
- SeAccessCheck
- SeQuerySecurityDescriptorInfo
四、配套链(工具与生态)
Sysinternals 配套
- AccessChk:读取 NTFS / 内核对象 SD,配合 Token 计算有效权限,DACL/SACL 审计主力工具
- AccessEnum:批量扫描目录树 DACL,发现权限漏洞、过度宽松 ACE
- WinObj:浏览内核对象 SD(内核对象同样拥有 SD,DACL/SACL,原理和 NTFS 文件 SD 一致,但存储不在 NTFS MFT)
Windows 原生工具
icacls:命令行查看 / 修改 NTFS DACL(不能直接操作 SACL)cacls:旧版工具,功能有限secpol.msc:审计策略,控制 SACL 审计事件是否生效(SACL 只是规则,审计策略全局开关)- 资源管理器 → 文件属性 → 安全选项卡:图形化编辑 DACL,高级选项查看 SACL
- PowerShell
Get-Acl / Set-Acl:读取 / 设置 SD,支持 SDDL
标准
- SDDL:Security Descriptor Definition Language,安全描述符文本表示形式
- Windows 安全模型:SD/DACL/SACL 这套模型统一用于 NTFS、注册表、内核对象、服务、打印机,不仅仅是 NTFS 文件
五、边界、限制、失效场景
✅ 能力边界
- DACL:自主访问控制,精细控制用户 / 组对文件的读 / 写 / 删除 / 修改权限;支持继承
- SACL:审计访问行为,记录成功 / 失败访问到安全日志;需要 SeSecurityPrivilege
- 安全模型是统一的:NTFS 文件、注册表项、内核对象(WinObj 看到的对象)都使用同一套 SD+Token+SeAccessCheck 裁决逻辑
❌ 硬限制边界
- 继承是创建时复制,不是动态联动 父目录 DACL 修改,不会自动更新已经存在的子文件;只有新建对象才继承。需要手动勾选 “替换子容器和对象的权限” 进行传播。
- SACL 不生效的前提:本地安全策略里审计策略未开启 就算 SACL 写了审计 ACE,如果全局审计策略没有启用对应审计类别,不会生成日志。SACL 只是规则,审计策略是总开关。
- 读取 SD 需要
READ_CONTROL权限;修改 DACL 需要WRITE_DAC;修改 SACL 必须启用SeSecurityPrivilege,普通管理员默认禁用该特权。 - NTFS 的
$SECURITY缓存池:删除大量唯一 SD 的文件,缓存不会立刻清理,会占用少量磁盘空间。 - 权限叠加:不是简单合并 Allow,Deny ACE 优先级最高。例如:组 Allow 读写,但单独用户 Deny,最终拒绝访问。
- 所有者权限:Owner 可以修改 DACL,哪怕没有 WRITE_DAC;这是 Windows 安全模型特殊规则。
- 复制 / 移动文件时 DACL 继承规则差异:
- 同分区移动:保留原 SD
- 同分区复制:继承目标目录 DACL
- 跨分区复制 / 移动:继承目标目录 DACL
失效场景
- 权限传播中断:子对象勾选 “禁用继承”,不再接收父目录 ACE
- 损坏 MFT:MFT 记录损坏,$SECURITY_DESCRIPTOR 丢失,SD 读取失败
- 备份还原场景:备份工具带备份 SD,还原时可恢复 SD;普通复制会丢失 SD,继承目标目录权限
- 压缩 / 加密 EFS:EFS 加密属性独立于 DACL;DACL 控制能否打开文件,EFS 控制能否解密文件,二者互不替代
- 共享权限:共享权限和 NTFS DACL 是两层权限,取交集。SMB 共享权限和 NTFS 权限叠加,最终权限取两者最严格集合,非常容易踩坑。
六、横向联动(整套安全体系串联)
表格
| 组件 | 角色 |
|---|---|
| Token | 访问者身份(SID、组、特权、完整性级别) |
| SD(DACL/SACL) | 对象安全规则:允许 / 拒绝、审计 |
| SRM SeAccessCheck | 裁决器:Token + SD → 有效访问权限 |
| NTFS ntfs.sys | MFT 存储 SD,加载 SD 交给 SRM |
| AccessChk | 读取 SD,注入 Token,调用 AccessCheck 输出有效权限 |
| WinObj | 读取内核对象 SD(内核对象无 MFT,在内核对象头存储 SD) |
一句话串联:WinObj 看内核对象 SD,AccessChk 拿 Token+SD 算权限;NTFS 把文件 SD 保存在 MFT;SRM 做最终权限裁决。
七、安全边界
- 红队常用:修改 DACL 添加后门 ACE;修改 SACL 开启审计;夺取文件 Owner 权限。
- EDR 会监控
SetNamedSecurityInfo、NtSetSecurityObject这类修改 DACL/SACL 的 API 调用。 - 注意:DACL 控制访问,不能防御底层磁盘读取;绕过文件系统直接读取磁盘扇区,可直接读取文件原始数据,不受 NTFS DACL 限制(这就是为什么 ATA Secure Erase/NVMe Sanitize 介质擦除是独立于文件权限的数据销毁方案)。
NTFS 审计 ACE(System Audit ACE)完整解构
定位:SACL 中的核心条目 SYSTEM_AUDIT_ACE,属于 Windows 安全描述符 SD 的 SACL(系统访问控制列表)组件。 区分:
- DACL 的 ACE:控制访问(允许 / 拒绝)
- SACL 的 Audit ACE:不控制访问,只在发生匹配访问动作时生成安全审计日志 整套链路:
访问动作 → 线程Token → SRM检查SACL的Audit ACE → 命中则生成审计事件 → 写入安全日志注意:Audit ACE 不是 NTFS 独有,注册表、内核对象、服务等所有带 SD 的对象都可以配置审计 ACE,NTFS 只是将 SD 持久保存在 MFT。
一、底层原理
1. SYSTEM_AUDIT_ACE 结构体定义
SYSTEM_AUDIT_ACE
├─ Header:ACE类型=SYSTEM_AUDIT_ACE,ACE大小,继承标志
├─ Mask:需要审计的访问权限掩码(FILE_READ_DATA、FILE_WRITE_DATA、DELETE等)
├─ AceFlags:
│ ├─ SUCCESSFUL_ACCESS_ACE_FLAG:成功访问触发审计
│ ├─ FAILED_ACCESS_ACE_FLAG:失败访问触发审计
│ ├─ 继承标志:CONTAINER_INHERIT / OBJECT_INHERIT / NO_PROPAGATE_INHERIT / INHERIT_ONLY
└─ SID:目标主体SID(用户/组SID,匹配访问Token中的SID)
- 继承标志含义:
OBJECT_INHERIT:文件继承这条审计 ACECONTAINER_INHERIT:子目录继承这条审计 ACENO_PROPAGATE_INHERIT:继承下去的 ACE 不再继续向下传递INHERIT_ONLY:仅用于继承,当前对象本身不生效
裁决逻辑(SACL 审计匹配,和 DACL 分开执行):
- 用户发起文件 IO,携带线程有效 Token
- SRM 拿到 SACL,遍历里面每一条 Audit ACE
- 判断:Token 的 SID(用户 / 组 SID)匹配 ACE 的 SID,并且本次请求的 DesiredAccess 与 ACE.Mask 有交集
- 再看 AceFlags:本次访问是成功还是失败,对应 SUCCESSFUL / FAILED 标记
- 全部条件满足 → 生成安全审计事件(Event ID 4663 对象访问)
✅ 关键点:SACL 审计检查独立于 DACL 权限判定
- 即使 DACL 拒绝访问(返回 AccessDenied),只要 Audit ACE 匹配 + 标记 FAILED,依然会记录失败访问审计日志
- DACL 允许访问,若 ACE 标记 SUCCESSFUL,就记录成功访问
2. NTFS 存储位置
Audit ACE 存放在 SD 的 SACL 段,SD 保存在文件 MFT 记录的$SECURITY_DESCRIPTOR属性; 多个文件 SD 完全相同会复用$SECURITY元文件的全局 SD 缓存池,Audit ACE 跟着 SD 一起缓存。
继承机制:新建子文件 / 目录时,复制父 SACL 里带继承标记的 Audit ACE;父 SACL 后续修改不会自动更新已有子对象,需要手动传播。
3. 全局审计策略开关(极易踩坑)
Audit ACE 只是审计规则,必须配合本地安全策略→审计策略(Audit Policy),开启「对象访问」审计子类别,否则就算 SACL 写满 Audit ACE,不会产生任何日志。
- 现代 Windows(Vista+)使用高级审计策略(Advanced Audit Policy),细粒度控制,优先于旧的基础审计策略。
- 对应子类别:
Audit Object Access→Audit File System(NTFS 文件对象审计)。
4. 审计事件内容
NTFS 文件审计生成 Event ID 4663(尝试访问对象),日志包含:
- 主体 SID / 账号(访问者 Token 身份)
- 对象路径、对象类型(File)
- 请求的访问掩码
- 访问结果(成功 / 失败)
- 进程 ID、进程名称
二、依赖文件 & 依赖链
Audit ACE 是安全描述符内的数据结构,不是独立驱动 / 文件;执行分为:用户态 API 操作 SACL/AuditACE、内核 SRM 审计判定、日志写入三层。
一级依赖
- ntoskrnl.exe
- SRM 安全引用监视器:
SeAccessCheck同时完成 DACL 权限判定 + SACL 审计匹配 SeAuditObjectAccess:审计事件生成核心内核函数,匹配 Audit ACE 后调用此函数生成审计记录SeQuerySecurityDescriptorInfo/SeSetSecurityDescriptorInfo:读取 / 修改 SD(含 SACL、Audit ACE)
- SRM 安全引用监视器:
- ntfs.sys
- 读取 MFT 中
$SECURITY_DESCRIPTOR,取出 SACL 交给 SRM;修改 SACL 时将 SD 写回 MFT - 处理 Audit ACE 继承传播逻辑
- 读取 MFT 中
- advapi32.dll
- Win32 安全 API:
GetNamedSecurityInfo/SetNamedSecurityInfo,读写 SD 的 SACL GetSecurityDescriptorSacl、GetAce、AddAce、DeleteAce:解析、新增、删除 Audit ACE
- Win32 安全 API:
- ntdll.dll
- NTAPI 桩函数:
NtQuerySecurityObject、NtSetSecurityObject,用户态到内核 syscall 入口
- NTAPI 桩函数:
- lsass.exe
- 高级审计策略加载;SID 解析(LookupAccountSid,SID 转用户名)
- clfs.sys + eventlog service
- CLFS(通用日志文件系统):存储安全事件日志;审计事件最终写入
Security.evtx
- CLFS(通用日志文件系统):存储安全事件日志;审计事件最终写入
修改 SACL/Audit ACE 的硬性特权:
SeSecurityPrivilege,默认管理员账户默认禁用,必须手动启用才能读写 SACL。仅 READ_CONTROL 只能读 DACL,不能读取 SACL。
二级依赖链
用户态:读取 SACL 并遍历 Audit ACE
工具(AccessChk / PowerShell Get-Acl / icacls)
↓ advapi32.dll GetNamedSecurityInfo
↓ GetSecurityDescriptorSacl 获取SACL
↓ GetAce 循环遍历每一条Audit ACE
↓ ntdll NtQuerySecurityObject
↓ syscall → ntoskrnl SRM
↓ ntfs.sys 读取MFT $SECURITY_DESCRIPTOR
用户态:新增 / 删除 Audit ACE(修改 SACL)
程序/资源管理器高级安全设置
↓ advapi32 AddAce / SetNamedSecurityInfo
↓ NtSetSecurityObject
↓ syscall进入ntoskrnl
↓ SRM校验权限:必须SeSecurityPrivilege + WRITE_OWNER / WRITE_DAC相关权限
↓ ntfs.sys 将新SD写入MFT,更新$SECURITY缓存
访问文件触发 Audit ACE 审计(核心运行链路)
应用 CreateFile / ReadFile / DeleteFile
↓ I/O管理器 → ntfs.sys,读取目标文件SD(SACL+DACL)
↓ 获取当前线程有效Token
↓ ntoskrnl SRM SeAccessCheck
├─ 分支1:DACL判定允许/拒绝访问
└─ 分支2:遍历SACL里所有Audit ACE
↓ 匹配SID+访问掩码+成功/失败标记
↓ SeAuditObjectAccess 生成审计事件
↓ 发送事件到EventLog,clfs.sys写入Security.evtx
三、核心 API 清单
Win32 advapi32
GetSecurityDescriptorSacl:从 SD 提取 SACLSetSecurityDescriptorSacl:向 SD 写入 SACLGetAce:遍历 SACL 中的 ACE,判断类型是否为SYSTEM_AUDIT_ACEAddAce:添加 Audit ACE 到 SACLDeleteAce:删除 SACL 内 Audit ACEInitializeAcl:初始化 SACL 缓冲区ConvertStringSecurityDescriptorToSecurityDescriptor:SDDL 文本转为 SD(SACL 部分用 S:(...) 描述审计 ACE)
NTAPI ntdll
NtQuerySecurityObjectNtSetSecurityObject
内核 SRM
SeAccessCheckSeAuditObjectAccess
四、配套链(工具、生态、标准)
Sysinternals 工具
- AccessChk:可读取对象 SD,展示 SACL 内 Audit ACE,审计权限 + 审计规则
- AccessEnum:批量遍历目录树,导出 DACL/SACL 审计 ACE 配置
- WinObj:查看内核对象 SACL 审计 ACE(内核对象无 MFT,SD 保存在对象头)
Windows 原生工具
- 资源管理器 → 文件属性 → 安全 → 高级 → 审计:图形界面添加 / 删除 Audit ACE
- PowerShell
Get-Acl / Set-Acl:读取、修改 SACL 与 Audit ACE,支持 SDDL icacls:仅支持 DACL,不能读取 / 修改 SACL 审计 ACE(重要区分)auditpol.exe:命令行管理高级审计策略(开启文件系统审计总开关,Audit ACE 生效的前提)- secpol.msc:本地安全策略,图形配置审计策略
SDDL 语法(审计 ACE 文本表达)
SACL 段以S:开头,Audit ACE 示例:
S:(AU;SA;WDRC;;;S-1-5-32-544)
AU= SYSTEM_AUDIT_ACESA= SUCCESSFUL_ACCESS(成功访问审计;FA = 失败访问,SF = 成功 + 失败)WDRC:权限掩码(Write、Delete、ReadControl 等)- 末尾 SID:要审计的主体 SID
五、边界、限制、失效场景
✅ 能力边界
- Audit ACE 只做审计日志记录,不阻断访问;访问控制完全交给 DACL。
- 支持继承,可批量给目录树配置文件 / 子目录审计规则。
- 可以区分审计成功访问、失败访问,按需组合。
- 模型通用:NTFS 文件、注册表、进程、内核对象都使用同一种 SYSTEM_AUDIT_ACE。
❌ 硬限制边界
- 两层开关:Audit ACE + 全局高级审计策略,缺一不可 只配置 SACL 的 Audit ACE,但
auditpol未开启Audit File System,不会生成任何日志。 - 读写 SACL 必须
SeSecurityPrivilege特权,普通管理员默认禁用;即使管理员,没有启用该特权,读取 SACL 直接报错。 - 继承仅在新建子对象那一刻复制 ACE;父目录 SACL 修改,存量子文件不会自动更新审计 ACE,需要勾选 “替换子容器和对象的审计条目” 强制传播。
INHERIT_ONLY标记的 Audit ACE:只向下继承,当前对象本身不触发审计,容易配置失误。- 审计日志存在性能开销:大量目录配置 Audit ACE,高频文件读写会产生海量 Security.evtx 事件,占用 IO、磁盘,甚至导致日志快速填满覆盖旧记录。
- 审计只在Windows 文件系统层生效;直接磁盘扇区读取(绕过 NTFS 文件系统)不会触发 Audit ACE 审计,不会生成 4663 日志。
失效场景
- 高级审计策略被关闭:
auditpol /get /subcategory:"File System"显示未启用。 - 权限不足:未启用
SeSecurityPrivilege,无法设置 / 读取 SACL。 - 子对象启用「禁用继承」,不再继承父目录 Audit ACE。
- SD 损坏:MFT 记录损坏,SACL 丢失,审计 ACE 读取失败。
- 日志已满且设置为覆盖:旧审计事件被自动清除,取证丢失记录。
- 备份还原:普通文件复制不会携带 SACL;只有备份 API(如 robocopy /COPY:S)才能完整还原 SD(含 SACL 审计 ACE)。
六、联动串联(整套安全体系)
表格
| 组件 | 角色 |
|---|---|
| Token | 访问者身份 SID / 组 SID,SRM 用来匹配 Audit ACE 的 SID |
| DACL ACE | 允许 / 拒绝访问,控制能不能打开文件 |
| Audit ACE(SACL) | 定义哪些 SID + 哪些访问动作需要记录审计日志 |
| SRM SeAccessCheck | 同时做权限判定 + Audit ACE 匹配 |
| SeAuditObjectAccess | 命中审计 ACE 后生成安全事件 |
| ntfs.sys | MFT 存储 SD,加载 SACL/Audit ACE |
| auditpol | 全局审计总开关,控制审计事件是否落地写入日志 |
完整一句话:Audit ACE 定义 “审计谁、审计什么操作、成功还是失败记日志”;auditpol 是总闸;SRM 在每次对象访问时拿着访问者 Token 去匹配 Audit ACE,命中就写安全事件。
七、安全边界
- 蓝队场景:配置 Audit ACE 监控敏感目录的删除 / 修改行为,捕获 4663 事件;
- 红队场景:清除 / 篡改 SACL 审计 ACE,删除审计规则,规避行为取证;这类操作会被 EDR 监控(
SetNamedSecurityInfo、NtSetSecurityObject); - 审计日志本身也可以被 SACL 保护,限制普通用户修改 / 清空 Security.evtx。
Windows NTFS 权限模型深度解构
分析框架:底层原理|依赖文件|依赖关系|逻辑链路|配套链|边界|自动化 重点:安全描述符组织架构、嵌套层级、继承链路、生效判断栈
一、底层原理
NTFS 权限不是简单 “文件挂一组权限”,是分层嵌套 + 继承 + 特权覆盖 + 安全参考监视器 (SRM) 判决的复合访问控制模型。 内核组件:SRM(安全参考监视器),位于内核,所有本地文件访问全部经过 SRM 校验;ntfs.sys 负责把安全描述符 SD 持久化存储到卷元文件$Secure,MFT 每条记录存储 SD 索引,不重复存储完整 SD(SD 去重节约磁盘)。
安全描述符 SD 顶层结构(第 0 层,根对象)
SecurityDescriptor SD
├─ Owner SID 对象所有者
├─ Group SID 主组(Windows极少使用)
├─ DACL 自主访问控制列表 用户/组允许/拒绝访问(业务权限主体)
└─ SACL 系统审计ACL 访问审计规则,不控制权限,只写日志
注意:Owner 本身携带隐式特权:
WRITE_DAC、WRITE_OWNER;哪怕 DACL 全部拒绝,所有者依然可以修改权限,这个是独立于 DACL 的特权,不属于 ACE 条目。
二、DACL 内部组织架构(第 1 层)
DACL 是 ACE(Access Control Entry)条目的有序数组。 每条 ACE 结构:
ACE
├─ ACE类型:允许ACE / 拒绝ACE / 审计ACE(SACL内) / 完整性ACE(MIC)
├─ ACE标志位(继承控制标志)
│ ├─ CI ContainerInherit 容器继承(文件夹向下继承)
│ ├─ OI ObjectInherit 对象继承(文件向下继承)
│ ├─ IO InheritOnly 仅继承:本对象不生效,只传给子对象
│ ├─ NP NoPropagateInherit 不传播继承:只传给直接子一级,不再深层嵌套
│ └─ INHERITED_ACE 标记:此ACE来自父继承,不是本对象显式ACE
├─ Trustee SID:用户/组SID
└─ AccessMask 32位位掩码:细粒度权限位(RD WD AD X DE DC RC WDAC WO …)
ACE 强制排序规则(SRM 判决依赖顺序,不能乱)
- 显式拒绝 ACE
- 显式允许 ACE
- 继承拒绝 ACE
- 继承允许 ACE
拒绝优先原则:只要命中一条拒绝 ACE,直接拒绝访问,不再向后匹配。
三、完整嵌套层级模型(从卷根向下嵌套)
NTFS 权限是目录树嵌套继承模型,层级从卷根开始向下递归;每一个文件 / 文件夹都是独立安全对象。
| 层级 | 对象 | 说明 |
|---|---|---|
| L0 | NTFS 卷本身(\) | 卷根安全描述符;所有顶层目录继承源头 |
| L1 | 一级文件夹 D:\DirA |
显式 SD / 继承卷根 SD |
| L2 | 二级子文件夹 D:\DirA\Sub1 |
继承 L1,也可设置独立显式 SD(断开继承) |
| L3 | 三级子文件夹 / 文件 D:\DirA\Sub1\file.txt |
继承父 L2,可设置独立显式 SD |
| … | 无限向下嵌套 | 理论无硬编码最大层级;受 NTFS 路径长度、MFT 资源限制 |
⚠️ 逻辑层级 vs 物理 MFT:
- 逻辑嵌套层级可以无限深;
- 每个 MFT 记录对应 1 个安全对象;每个对象可以:①继承父 SD;②使用显式 SD(禁用继承)。
继承两种模式
- 启用继承(默认):子对象从直接父对象复制继承 ACE(标记
INHERITED_ACE);父改权限,子自动刷新继承 ACE。 - 禁用继承:
- 模式 A:复制继承 ACE 转为本对象显式 ACE(对应
icacls /inheritance:d) - 模式 B:完全删除所有继承 ACE,对象只保留手动新增显式 ACE(
icacls /inheritance:r)
- 模式 A:复制继承 ACE 转为本对象显式 ACE(对应
关键点:继承只来自直接父目录,不是卷根直接全局下发;每一层可以切断继承,生成独立 SD。
完整访问判决栈(SRM 判决多层判断顺序,非常重要)
当进程访问一个 NTFS 文件,SRM 按顺序逐层判断:
- 进程特权校验:是否
SeSecurityPrivilege、SeTakeOwnershipPrivilege等特权;特权可以绕过部分 ACL。 - 判断:当前进程 Token 用户 SID 是否等于对象 Owner SID → 授予 Owner 固有特权(修改权限)
- 加载该对象 DACL 全部 ACE(显式 + 继承 ACE 已经合并在本对象 DACL 内,不是实时向上递归查询父目录!!)
- 按 ACE 顺序逐条匹配进程 Token 内所有 SID(用户 + 全部所属组 SID)
- 命中拒绝 ACE → 直接拒绝访问,判决结束
- 命中允许 ACE → 累加 AccessMask 权限位
- 遍历全部 ACE 完成;有匹配允许位则放行;无任何允许命中则隐式拒绝。
✅重点误区纠正: ❌错误:访问文件的时候系统一层层向上查询父文件夹权限。 ✅正确:禁用 / 启用继承时,子对象就已经把继承 ACE 复制到自身 DACL;访问时只读取当前对象自己 DACL,不向上遍历父目录。父目录权限变更后,会向下传播更新子对象继承 ACE 缓存。
四、完整模型层级总表(由外到内,从系统到 ACE 位掩码)
0层:Windows安全子系统 SRM 安全参考监视器(内核,全局判决层)
↓
1层:NTFS卷 $Secure 安全描述符存储池(SD全局去重存储)
↓
2层:MFT文件记录:每个文件/文件夹引用一条SD(卷根L0,目录L1,子目录L2,文件L3…无限逻辑嵌套)
├─ SD.Owner / SD.Group
├─ SD.DACL → 第3层
│ ├─ ACE[0] 显式拒绝
│ ├─ ACE[1] 显式允许
│ ├─ ACE[2] 继承拒绝
│ └─ ACE[3] 继承允许 → 第4层
│ ├─ ACE标志位(OI/CI/IO/NP/INHERITED_ACE)
│ ├─ Trustee SID
│ └─ AccessMask 32bit位掩码(第5层,最小权限单元)
└─ SD.SACL(审计)
- 逻辑目录嵌套层级:理论无上限,受 Windows 最大路径长度限制;
- 权限模型内部数据嵌套一共 6 层:SRM → 卷 SD 存储池 → SD 安全描述符 → DACL 数组 → ACE 条目 → AccessMask 位掩码。
AccessMask 32 位掩码(最小权限单元,第 5 层)
32bit 每一位代表一项原子权限: RD(读数据)、WD(写数据)、AD(追加)、X(执行遍历)、DC(删除子项)、DE(删除)、RC(读取控制)、WDAC(写入DACL)、WO(写入Owner)等。 简易缩写F M RX R W D是多个 bit 的组合别名。
五、依赖文件
| 组件 | 作用 |
|---|---|
| ntfs.sys | 内核驱动;MFT 读写;$Secure 卷存储;SD 加载 |
| advapi32.dll | 用户态 API:GetNamedSecurityInfo / SetNamedSecurityInfo |
| lsass.exe | SID、用户组 Token 解析;登录 Token 生成 |
| srms.sys | 安全参考监视器内核模块,访问判决核心 |
六、逻辑链路(修改权限完整时序)
- icacls / GUI / PowerShell 调用
SetNamedSecurityInfo - advapi32.dll 传递 SD 结构到内核
- ntfs.sys 写入 / 复用 $Secure 池内 SD;更新 MFT 记录 SD 索引
- 如果开启继承:向所有子对象下发通知,刷新子对象内部继承 ACE 缓存
- 后续访问文件:SRM 读取当前对象自身 DACL 做判决,不再访问父目录
坑:大量目录递归修改权限,会触发大规模子对象继承 ACE 刷新,IO 极高。
七、边界约束
- 继承是 “向下复制缓存”,不是实时向上查询。切断继承之后,父目录权限变更不再影响该对象。
- Owner 特权独立 DACL 存在;即使 DACL 全部拒绝,Owner 可以修改权限,但不代表可以直接读写文件数据。
- 继承标志
NP(NoPropagateInherit):本对象 ACE 只直接子一级生效,不再向更深层级嵌套传递。 - ReFS 复用完全一样 SD 权限模型;FAT32 无 SD 结构,ACL 完全无效。
- 符号链接:可以设置自身 SD;访问时默认解析到目标对象,使用目标对象 SD 判决。
- 孤立 SID:SID 在本地 / 域不存在,但 ACE 条目仍然保留在 DACL 中,会造成权限异常。
八、配套链 & 自动化流水线
运维工具对应模型操作
- takeown.exe:只修改 SD.Owner(第 2 层 SD 字段),不动 DACL/ACE。
- icacls.exe:读写 DACL、ACE 标志位、AccessMask;控制继承传播。
- PowerShell
Get‑Acl:完整读取 SD 全部字段,包括 SACL;输出 SDDL 字符串(SD 完整文本序列化)。 - icacls
/verify:校验 DACL 内 ACE 排序是否符合 SRM 规范。
PowerShell 查看完整层级结构示例
#读取完整SD对象
$acl = Get‑Acl "D:\test" -Audit
#输出SDDL文本,可以看到完整Owner/DACL/SACL全部层级编码
$acl.Sddl
#枚举每一条ACE
$acl.Access | Format‑Table
SDDL 简短示例(直观看到模型序列化)
O:S‑1‑5‑32‑544G:S‑1‑5‑32‑544D:(A;OICI;FA;;;SY)(A;OICI;FA;;;BA)
O=Owner SID
G=Group SID
D=DACL部分;每条(A=允许;OICI标志;FA完全访问;;SID)
SD(Security Descriptor,安全描述符) + SRM(Security Reference Monitor,安全引用监视器)完整解构
核心一句话总结: SD = 对象的静态安全规则容器(DACL/SACL/Owner/Group);SRM = Windows 内核安全裁决引擎。 SRM 不关心对象是 NTFS 文件、注册表项、内核对象还是服务;SRM 只做一件事:输入【访问者 Token + 对象 SD + 请求访问掩码】,输出是否允许访问,同时匹配 SACL 生成审计事件。 NTFS、注册表驱动、对象管理器只是载体:负责把 SD 加载进内存传给 SRM,SRM 才是权限判定的唯一主体。
一、底层原理
1. SD 安全描述符(SECURITY_DESCRIPTOR)
SD 是自包含的二进制安全规则结构体,不绑定任何特定文件系统,是 Windows 安全模型的通用数据结构。
SECURITY_DESCRIPTOR
├─ Revision:版本号
├─ Control:控制标志位
│ ├─ SE_DACL_PRESENT:存在DACL
│ ├─ SE_DACL_DEFAULTED:DACL从父继承而来
│ ├─ SE_SACL_PRESENT:存在SACL
│ ├─ SE_OWNER_DEFAULTED:Owner继承自父对象
│ └─ …
├─ Owner SID:对象所有者SID(Owner可以修改DACL,是特殊权限)
├─ Group SID:对象主组SID(遗留,现代Windows极少使用)
├─ DACL(自主访问控制列表):Allow/Deny ACE,控制访问权限
└─ SACL(系统访问控制列表):Audit ACE,匹配访问行为生成审计日志
- SD 可以序列化为 SDDL 字符串,方便存储、传输、脚本操作。
- SD本身没有逻辑,只是一堆规则的静态数据;SD 不会自己做权限判断,必须交给 SRM。
- 不同对象的 SD 持久化位置不同:
- NTFS 文件:MFT 记录
$SECURITY_DESCRIPTOR属性,复用$SECURITY元文件全局 SD 缓存 - 注册表项:存放在注册表 hive 内部元数据
- 内核对象(事件、互斥体、WinObj 里的对象):SD 保存在内核对象头,不持久化,重启丢失
- NTFS 文件:MFT 记录
2. SRM 安全引用监视器(内核组件)
SRM 是ntoskrnl.exe内部的安全子系统,Windows 强制访问控制的裁决核心,属于内核基础组件。 SRM 两大核心职责:
- 访问权限裁决:
SeAccessCheck入参:- 访问主体 Token(进程 / 线程访问令牌:UserSID、GroupSID、Privileges、完整性级别 MIC)
- 对象 SD(DACL/SACL/Owner)
- DesiredAccess:调用方想要申请的访问掩码(FILE_READ_DATA、DELETE、WRITE_DAC 等)
- ObjectType:对象类型(文件 / 注册表 / 内核对象) 输出:
GrantedAccess(被允许的权限掩码) + 状态(允许 / 拒绝STATUS_ACCESS_DENIED)
裁决逻辑: ① 遍历 DACL,Deny ACE 优先匹配;一旦命中 Deny,直接拒绝; ② 没有 Deny,继续匹配 Allow ACE; ③ 无任何 ACE 匹配,默认拒绝访问。
- 审计匹配:同步遍历 SACL 在
SeAccessCheck内部,并行遍历 SACL 内的SYSTEM_AUDIT_ACE; 若 Token 的 SID 匹配 ACE,访问掩码交集存在,并且成功 / 失败标记匹配本次访问结果 → 调用SeAuditObjectAccess生成安全审计事件。
SRM 是集中式安全裁决器:所有受保护对象访问,都必须经过 SRM 校验,这是 Windows 安全模型的核心设计。 驱动(ntfs.sys/registry 驱动 / 对象管理器)不能私自判断权限,必须调用 SRM。
3. 完整裁决模型(Token + SD + SRM)
访问请求(CreateFile / RegOpenKey / OpenEvent)
↓
对象驱动(ntfs.sys / cm.sys / Ob对象管理器)取出对象SD
↓
获取当前线程有效Token(线程模拟令牌优先,没有则使用进程主Token)
↓
调用 SRM SeAccessCheck(Token, SD, DesiredAccess)
├─ 分支1:DACL判定 → 允许/拒绝访问
└─ 分支2:SACL Audit ACE匹配 → 命中则生成审计事件
↓
SRM返回GrantedAccess;驱动根据结果放行或拒绝IO
4. SD 生命周期
- 创建对象(新建文件 / 注册表项):从父对象继承 SD(继承 ACE 规则);
- 对象驱动把 SD 存入对应的持久化存储(NTFS MFT / 注册表 hive);
- 访问对象时,驱动加载 SD 到内存,传入 SRM;
- 用户调用
SetNamedSecurityInfo修改 SD → 驱动更新持久存储; - 对象删除:NTFS 释放 MFT 记录;内核临时对象直接销毁内存中的 SD。
重点:继承只是对象创建瞬间复制 SD 的 ACE;父 SD 后续修改不会自动同步到子对象。
二、依赖文件 & 依赖关系
SD 是数据结构,SRM 是 ntoskrnl 内部内核模块,不存在单独的 srm.sys。
一级依赖
- ntoskrnl.exe(SRM 核心)
- SRM 内核函数:
SeAccessCheck、SeAuditObjectAccess、SeQuerySecurityDescriptorInfo、SeSetSecurityDescriptorInfo、SeCreateSecurityDescriptor - SID 解析、ACE 校验、审计事件生成、MIC 完整性级别校验
- 对象管理器
Ob:内核对象创建时处理 SD
- SRM 内核函数:
- 对象管理器 Ob(ntoskrnl 内) 内核对象(事件、互斥体、目录对象,WinObj 浏览的对象)SD 存储在对象头部,打开对象时把 SD 交给 SRM。
- ntfs.sys NTFS 文件载体:读取 MFT 的
$SECURITY_DESCRIPTOR、全局 SD 缓存池$SECURITY元文件;加载 SD 提交 SRM;写回 SD。 - cm.sys(配置管理器,注册表驱动) 注册表项 SD 持久化在 hive,打开注册表项时加载 SD 交给 SRM。
- advapi32.dll Win32 安全 API 封装:
GetNamedSecurityInfo/SetNamedSecurityInfo,读写 SD;SDDL 转换、ACE 增删。 - ntdll.dll NTAPI 桩:
NtQuerySecurityObject/NtSetSecurityObject,用户态→内核 syscall 入口。 - lsass.exe 提供 SID→账号名解析;加载系统审计策略;登录会话管理、Token 生成。
- clfs.sys + EventLog SRM 的
SeAuditObjectAccess生成审计事件,通过 CLFS 写入 Security.evtx 安全日志。
二级依赖链
1)用户态读取对象 SD(AccessChk / PowerShell Get-Acl)
AccessChk.exe
↓ advapi32.dll GetNamedSecurityInfoW
↓ ntdll.dll NtQuerySecurityObject
↓ syscall → ntoskrnl SRM
↓ 对象驱动(ntfs.sys/cm.sys/Ob对象管理器)读取对象SD
↓ SD二进制数据原路返回用户态
advapi32解析SD,拆分Owner、DACL、SACL,遍历ACE
LookupAccountSid(lsass)SID转账号名称
2)修改对象 SD(资源管理器安全页面、SetNamedSecurityInfo)
应用程序
↓ advapi32 SetNamedSecurityInfoW
↓ NtSetSecurityObject syscall
↓ ntoskrnl SRM
→ SRM校验调用者权限:READ_CONTROL / WRITE_DAC / WRITE_OWNER;修改SACL需要SeSecurityPrivilege
↓ 对象驱动(ntfs.sys/cm.sys)将新SD写入持久存储
3)对象访问,SRM 权限裁决(最核心调用链)
应用 CreateFile / RegOpenKey / OpenEvent
↓ I/O管理器 / 对象管理器 Ob
↓ 对象驱动(ntfs.sys/cm.sys)加载对象SD
↓ 获取当前线程有效Token
↓ 调用 ntoskrnl SRM SeAccessCheck(Token, SD, DesiredAccess)
├─ DACL ACE遍历,判定访问允许/拒绝
└─ SACL Audit ACE遍历,匹配成功/失败 → SeAuditObjectAccess生成审计事件
↓ SRM返回GrantedAccess
↓ 对象驱动:允许IO 或 返回STATUS_ACCESS_DENIED
↓ 审计事件送入EventLog,clfs.sys写入Security.evtx
三、核心 API 清单
Win32 advapi32
GetNamedSecurityInfo/SetNamedSecurityInfo:获取 / 设置命名对象 SD(文件、注册表、内核对象通用)GetSecurityDescriptorOwner/Group/Dacl/Sacl:从 SD 提取各部分AddAce / DeleteAce / GetAce:操作 DACL/SACL 内 ACEConvertStringSecurityDescriptorToSecurityDescriptor:SDDL 转二进制 SD
NTAPI ntdll
NtQuerySecurityObjectNtSetSecurityObject
SRM 内核 API(ntoskrnl)
SeAccessCheck:核心裁决函数SeAuditObjectAccess:生成审计事件SeQuerySecurityDescriptorInfoSeSetSecurityDescriptorInfoSeValidSecurityDescriptor:校验 SD 二进制合法性
四、配套链(工具、生态、标准)
Sysinternals 工具
- AccessChk:读取 SD,传入指定 Token,调用 AccessCheck,输出 SRM 裁决后的有效权限;直接模拟 SRM 的裁决逻辑
- WinObj:浏览内核对象(\BaseNamedObjects 等),读取内核对象 SD(内核对象 SD 不保存在 NTFS)
- AccessEnum:批量遍历目录树,批量导出 NTFS 对象 SD(DACL/SACL)
Windows 原生工具
- 资源管理器安全高级属性:图形化编辑 SD(Owner/DACL/SACL)
- PowerShell
Get-Acl / Set-Acl:读写 SD,SDDL 操作 auditpol.exe:管理高级审计策略,控制 SACL 审计事件是否落地(SRM 生成审计事件前会检查全局审计策略)whoami /all:查看当前进程 Token(SRM 裁决的输入)
标准
- Windows 安全模型文档:SD、DACL/SACL、ACE 定义
- SDDL(Security Descriptor Definition Language)文本序列化规范
五、边界、限制、失效场景
✅ 能力边界
- SRM 是统一裁决器:NTFS、注册表、内核对象、服务、打印机全部复用同一套 SD+Token+SRM 模型。
- SD 与存储介质解耦:SD 只是规则,持久化载体由对象驱动决定。
- SRM 同时处理自主访问控制 DACL + 审计 SACL + MIC 强制完整性级别。
- Owner 拥有特殊权限:对象所有者可以修改 DACL,哪怕没有 WRITE_DAC 权限。
❌ 硬限制边界
- SRM 仅拦截操作系统层对象访问 直接读取磁盘原始扇区(绕过 ntfs.sys 文件系统驱动),不会触发 SRM,SD/DACL 完全失效。这也是 ATA Secure Erase / NVMe Sanitize 介质擦除不受 NTFS 权限约束的根本原因。
- SD 只是快照:修改 SD 后,已经缓存到内存的 SD,部分场景需要重新加载;继承仅在新建对象时复制。
- SRM 不会阻止内核驱动绕过安全检查:内核驱动如果不调用
SeAccessCheck,可以直接操作对象(需要内核权限)。 - SACL 审计需要双重开关:SD 内 AuditACE + 系统高级审计策略;SRM 即使匹配 AuditACE,如果审计策略关闭,不会写入日志。
- 权限读取 SD 的权限:
- READ_CONTROL:读取 DACL、Owner
- 读取 SACL 必须 SeSecurityPrivilege 特权(默认管理员禁用)
- 完整性级别 MIC(Vista+):SRM 在 SeAccessCheck 中额外校验 MIC;低完整性进程不能写入高完整性对象,独立于 DACL。
失效场景
- SD 损坏:二进制 SD 结构非法,SRM 校验
SeValidSecurityDescriptor失败,返回错误。 - 对象驱动不支持安全描述符:少数老旧第三方驱动不集成 SRM 调用,无 SD 权限控制。
- 内核级恶意驱动:绕过 SRM 直接操作对象,不触发权限校验、不触发审计。
- 备份还原:普通文件复制不会携带 SD;只有备份 API(BackupRead/BackupWrite、robocopy /COPY:S)才完整导出 SD。
- 令牌损坏:Token 结构异常,SRM 无法匹配 SID,访问判定失败。
六、整套安全体系串联(前面所有组件汇总)
表格
| 组件 | 角色 |
|---|---|
| Token | 访问者身份载体(SID、组、特权、MIC 完整性级别),SRM 的输入 |
| SD | 对象静态安全规则:Owner、DACL、SACL |
| DACL ACE | Allow/Deny,控制访问放行 / 拒绝 |
| SACL Audit ACE | 定义哪些访问行为触发审计日志 |
| SRM(SeAccessCheck) | 裁决引擎:Token + SD → 允许 / 拒绝 + 审计事件 |
| ntfs.sys | SD 持久化载体(MFT),加载 SD 提交 SRM |
| AccessChk | 用户态工具,模拟 SRM 的 AccessCheck,计算有效权限 |
| WinObj | 浏览内核对象 SD(内核对象 SD 保存在内核对象头,不落地磁盘) |
一句话串联: 所有对象访问,驱动取出 SD、拿到访问者 Token,交给 SRM 裁决;SRM 看 DACL 决定能不能访问,看 SACL 决定要不要记审计日志;NTFS 只负责把文件的 SD 存在 MFT 元数据里。
七、安全边界
- 蓝队:保护关键对象 SD,配置 SACL 审计 ACE,SRM 在访问时生成 4663 审计事件;
- 红队:篡改 SD(添加后门 ACE、删除 SACL 审计 ACE)、夺取对象 Owner;这类操作会触发
SetNamedSecurityInfo,被 EDR 监控; - SRM 在内核态执行,用户态程序无法绕过 SRM,除非拿到内核权限。
Windows NTFS 访问控制全套原生工具栈(Win10/Win11‑2026 最新)
分析框架:底层原理|依赖文件|依赖关系|逻辑链路|配套链|边界|自动化 工具全集:
icacls.exe、takeown.exe、cacls.exe(废弃)、资源管理器安全 GUI、PowerShellGet‑Acl/Set‑Acl;底层统一基于 Windows 安全参考监视器 SRM + NTFS 安全描述符 SD。
一、底层原理
1. NTFS 安全描述符 SD(存储于卷元文件$Secure,去重存储)Microsoft ...
四元组结构:
Owner:所有者 SID;所有者固有特权:无视 DACL 拒绝,具备修改 SD 权限Group:主组(Windows 极少使用)DACL自主访问控制列表:控制谁读 / 写 / 执行;icacls /save仅保存 DACLSACL系统审计 ACL:记录访问审计事件;icacls 不读写 SACL
2. 安全子系统内核模型
- SRM 安全参考监视器:内核态,所有 ACL 校验、特权校验统一入口;
- 特权:
SeTakeOwnershipPrivilege(夺取所有权)、SeRestorePrivilege(设置所有者),必须管理员提升 Token 才会启用;UAC 过滤管理员 Token 默认不携带完整特权博客园。 - ACE 强制排序(GUI/icacls/PowerShell 全部遵循):
- 显式拒绝 ACE
- 显式允许 ACE
- 继承拒绝 ACE
- 继承允许 ACE
- MIC 强制完整性控制:低完整性进程不能写入高完整性对象;由 icacls
/setintegritylevel管理。 - SDDL 字符串:安全描述符文本序列化格式(O:/G:/D:/S:),PowerShell 原生支持,可完整保存 Owner/DACL/SACL。
3. 各工具定位
| 工具 | 定位 |
|---|---|
| icacls.exe | 现代命令行,DACL、继承、MIC 完整性、DACL 备份还原;不能强制夺取 Owner |
| takeown.exe | 仅修改 SD.Owner;解锁权限锁死对象;只改所有者,DACL 不变 |
| cacls.exe | 废弃遗留;不支持 MIC、精细继承、备份还原;仅兼容旧脚本Microsoft ... |
| 资源管理器安全 UI | 图形外壳;aclui.dll 封装,底层复用 advapi32 API;适合单点调试,不适合批量 |
| PowerShell Get‑Acl / Set‑Acl | .NET 包装原生 Win32 安全 API;唯一原生可完整读写 Owner+DACL+SACL+MIC 的系统组件,弥补 icacls 备份短板 |
二、依赖文件
| 组件 | 程序路径 | 核心依赖 |
|---|---|---|
| icacls.exe | C:\Windows\System32\icacls.exe |
advapi32.dll、aclui.dll、lsass.exe、ntfs.sys |
| takeown.exe | C:\Windows\System32\takeown.exe |
advapi32.dll、lsass.exe、ntfs.sys |
| cacls.exe | C:\Windows\System32\cacls.exe |
advapi32.dll、lsass.exe、ntfs.sys |
| 资源管理器安全 UI | explorer.exe + aclui.dll 对话框 | explorer.exe、aclui.dll、advapi32.dll、lsass.exe、ntfs.sys |
| PowerShell ACL Cmdlet | System.Security.AccessControl(.NET) | advapi32.dll、lsass.exe、ntfs.sys |
公共依赖释义
advapi32.dll:Win32 安全 APIGetNamedSecurityInfo/SetNamedSecurityInfo,读写对象安全描述符 SD。lsass.exe:SID ↔ 用户 / 组名双向翻译;本地 SAM、域账号解析;域离线输出原始 SID 字符串。ntfs.sys:内核驱动,操作卷$Secure元数据,MFT 安全描述符持久化、内核访问校验。aclui.dll:权限掩码、继承标记解析、GUI 对话框渲染;takeown 不加载该 DLL。
三、依赖关系(调用链路)
takeown.exe
takeown.exe 参数解析 /f /r /c
↓
启用特权 SeTakeOwnershipPrivilege + SeRestorePrivilege
↓
advapi32.dll::SetNamedSecurityInfo 修改SD.Owner字段
↓
lsass.exe 获取当前进程用户SID
↓
系统调用 → ntfs.sys写入卷$Secure元数据更新安全描述符
icacls.exe
icacls.exe 参数解析 /grant /deny /save /restore /inheritance /setintegritylevel
↓
advapi32.dll Get/SetNamedSecurityInfo,读写DACL、MIC完整性标签
↓
lsass.exe SID名称转换
↓
ntfs.sys 更新$Secure元数据
↓
控制台输出 / 写入自定义aclfile备份文本(仅DACL)
资源管理器安全 UI
explorer.exe 右键属性‑安全‑高级
↓
aclui.dll渲染权限编辑对话框
↓
aclui.dll内部调用advapi32.dll安全API
↓
lsass SID翻译
↓
ntfs.sys读写SD
PowerShell Get‑Acl / Set‑Acl
PowerShell Cmdlet → .NET System.Security.AccessControl
↓
封装advapi32.dll Win32安全API,支持SDDL完整序列化
↓
lsass SID解析
↓
ntfs.sys读写完整SD(Owner+DACL+SACL+MIC)
运行前置约束
- 必须 NTFS/ReFS;FAT32/exFAT/UDFS 无安全描述符,全部 ACL 操作报错无效Microsoft ...。
- UAC:修改 Owner、批量 ACL 修改必须提升管理员权限;普通过滤管理员 Token 缺少特权,takeown 夺取所有权失败。
- Windows 资源保护 WFP 受保护对象:即使 takeown 接管,修改后 WFP 会自动还原原始权限;系统目录谨慎递归操作。
- 符号链接:
- takeown:无
/L参数,永远跟随目标对象,不能修改链接本身所有者; - icacls:
/L操作符号链接自身; - GUI:默认跟随链接目标。
- takeown:无
四、逻辑链路
标准锁死目录修复时序(生产标准流水线)
1. takeown /f "D:\LockedDir" /r /c
→ 将所有子对象Owner修改为当前管理员SID;DACL完全不变
2. icacls "D:\LockedDir" /reset /t /c
→ 清除显式DACL,恢复父目录继承ACL
3. icacls "D:\LockedDir" /grant Administrators:(F) SYSTEM:(F) /t /c
→ 重新授予业务权限
> 重要:takeown仅改Owner,**夺取所有权不等于获得访问权限,必须后续重设DACL**
备份还原两套链路对比
- icacls
/save→/restore- ✅优点:速度快,原生递归;
- ❌缺陷:只备份 DACL;Owner、SACL 审计、MIC 完整性标签全部丢失,还原不会恢复。
- PowerShell
Export‑CliXml/Import‑CliXml- ✅完整保存 Owner、DACL、SACL、MIC 完整性标签;支持 SDDL 字符串导出;
- ❌大目录批量速度低于 icacls。
继承参数一一映射(GUI ↔ icacls)
| GUI 高级安全设置 | icacls 参数 |
|---|---|
| 禁用继承 → 将继承的权限复制到此对象 | icacls /inheritance:d |
| 禁用继承 → 删除继承的权限 | icacls /inheritance:r |
| 启用继承 | icacls /inheritance:e |
| 重置为父项继承权限 | icacls /reset |
关键能力对照表
| 能力 | icacls.exe | takeown.exe | cacls.exe | 资源管理器 GUI | PowerShell ACL |
|---|---|---|---|---|---|
| 修改对象 Owner | ❌不能强制夺取 | ✅仅修改 Owner | ❌ | ✅ | ✅完整读写 |
| DACL 授权 / 拒绝 ACE | ✅完整 | ❌不处理 DACL | ✅基础 | ✅完整 | ✅完整 |
| OI/CI/NP 精细继承标记 | ✅完整 | ❌ | ❌有限 | ✅完整 | ✅完整 |
| MIC 完整性标签管理 | ✅支持 | ❌ | ❌不识别 | ✅支持 | ✅支持 |
| DACL 备份还原 | ✅(/save /restore) | ❌ | ❌ | ❌ | ✅完整 SD 备份 |
| SACL 审计读写 | ❌不支持 | ❌ | ❌ | ✅图形界面 | ✅原生支持 |
| 符号链接操作 | ✅(/L) | ❌无参数 | ❌ | ❌ | ✅支持 |
五、配套链
系统原生配套
whoami /all:查看当前进程全部特权,校验SeTakeOwnershipPrivilege是否启用。- 安全事件日志:开启 SACL 审计策略后,安全日志记录所有者变更、ACL 修改事件。
- SDDL 字符串:跨机器迁移权限、模板化部署。
运维工作流
- 权限锁死修复流水线:
takeown → icacls /reset → icacls /grant - 批量权限迁移:快速 DACL 备份用
icacls /save;重要生产迁移优先 PowerShell 完整 SD 备份。 - 脚本规范:新脚本禁止使用废弃
cacls.exe,优先 icacls;需要 SACL/Owner 完整备份使用 PowerShell。 - 排错辅助:
icacls /verify扫描不规范乱序 ACL。
六、边界约束(风险坑点汇总)
| 分类 | 边界风险 |
|---|---|
| takeown 边界 | 仅修改 Owner,DACL 保持原样;UAC 未提升管理员,特权缺失直接失败;无符号链接 / L 参数;接管 WFP 系统文件会被 Windows 资源保护自动回滚。 |
| icacls 边界 | /save只保存 DACL,丢失 Owner/SACL/MIC;不能强制夺取所有者;/grant:r仅替换该 SID 显式允许 ACE,不碰拒绝、继承 ACE;/inheritance:d与/inheritance:r极易混淆造成权限丢失。 |
| cacls 边界 | 已废弃;不支持 MIC、高级继承、备份还原;输出文本与 icacls 备份文件互不兼容,禁止新自动化脚本使用。 |
| GUI 边界 | 适合单点调试;海量文件批量修改性能极差;底层行为等价命令行。 |
| PowerShell ACL 边界 | 完整 SD 备份性能弱于 icacls;SDDL 字符串写错直接造成对象完全锁死。 |
| 文件系统边界 | FAT32/exFAT 无安全描述符,全部 ACL 操作无效。 |
| 特权边界 | 修改 Owner、批量 ACL 必须提升管理员;普通用户返回拒绝访问。 |
| 符号链接边界 | takeown 无法修改链接本身所有者;icacls 必须显式/L才操作链接自身。 |
卡脖子痛点
- takeown 执行完成直接访问文件仍然报错,忘记后续 icacls 重设 DACL;
- 将 icacls
/save当作完整安全描述符备份,迁移后丢失所有者、审计 SACL;- 直接递归修改 Windows 系统目录,触发 WFP 回滚,系统组件异常。
七、自动化流水线
批处理模板(锁死目录修复 + DACL 备份)
@echo off
set "TARGET=D:\LockedFolder"
::1.夺取所有者
takeown /f "%TARGET%" /r /c
::2.重置ACL恢复继承
icacls "%TARGET%" /reset /t /c
::3.分配权限
icacls "%TARGET%" /grant Administrators:(F) SYSTEM:(F) /t /c
::4.备份DACL(仅DACL)
icacls "%TARGET%" /save acl_dacl_backup.txt /T /C /Q
PowerShell 完整安全描述备份(弥补 icacls 短板,包含 Owner+DACL+SACL+MIC)
$path = "D:\LockedFolder"
#完整SD备份
Get‑Acl -Path $path -Audit | Export‑CliXml "Full_SD_Backup.xml"
#完整恢复
Import‑CliXml "Full_SD_Backup.xml" | Set‑Acl -Path $path
#导出SDDL字符串模板
$sd = Get‑Acl $path -Audit
$sd.Sddl | Out‑File "sd_template.txt"
PowerShell 批量巡检校验 ACL 规范性
$scanPath = "D:\Data"
& icacls $scanPath /verify /T /C | Out‑File "acl_verify_report.txt"
icacls.exe 深度解构
分析框架:底层原理|依赖文件|依赖关系|逻辑链路|配套链|边界|自动化 定位:Windows NTFS DACL 命令行管理工具,替代已废弃
cacls.exe;负责文件 / 文件夹自主访问控制列表、继承、所有者、强制完整性标签管理;仅作用于 NTFS 文件系统。
一、底层原理
- NTFS 安全描述符 SD (Security Descriptor) 每个文件 / 文件夹在 MFT 主文件表记录内保存安全描述符 SD,结构四元组:
Owner对象所有者 SIDGroup主组 SIDDACL自主访问控制列表(icacls/save只备份这一部分)SACL系统访问控制列表(审计 ACL,icacls 不读写)
⚠️ icacls
/save//restore不保存 / 恢复 Owner、SACL、完整性标签,仅处理 DACL。
- ACE 访问控制项排序规则(Windows 强制校验) icacls 写入 ACL 会自动规范化重排 ACE 顺序,优先级从上到下:
- 显式拒绝 ACE
- 显式允许 ACE
- 继承拒绝 ACE
- 继承允许 ACE 使用
/verify可检测乱序、损坏、格式不规范 ACL。 - 两套权限掩码体系
- 简易缩写:
F完全控制、M修改、RX读取执行、R只读、W写入、D删除;是底层多个位掩码的组合别名。 - 细粒度底层掩码:
DE、RC、WDAC、WO、RD、WD、AD、X、DC,对应 Win32 原生 32 位访问掩码比特。
-
继承标志位(OI/CI/IO/NP/I)
标记 含义 (OI)ObjectInherit 对象继承:子文件继承 ACE (CI)ContainerInherit 容器继承:子文件夹继承 ACE (IO)InheritOnly 仅继承:本对象不生效,仅传给子对象 (NP)NoPropagateInherit:仅下一级,不再深层递归 (I)Inherited:该 ACE 来自父对象继承,非本对象显式 ACE - MIC 强制完整性控制
/setintegritylevel添加强制完整性标签 ACE:L低、M中、H高;低完整性进程不能写入高完整性对象。 - SID 解析机制 支持友好账号名;原始 SID 必须加前缀
*,例*S‑1‑1‑0;本地账号由 LSASS 解析,域 SID 依赖域控。
二、依赖文件
| 文件 | 路径 | 核心职责 |
|---|---|---|
| icacls.exe | C:\Windows\System32\icacls.exe |
主程序,解析命令行参数、业务逻辑、输出控制台 / 备份文件 |
| advapi32.dll | C:\Windows\System32\advapi32.dll |
Win32 安全 API:GetNamedSecurityInfo / SetNamedSecurityInfo;SID 名称转换 API |
| aclui.dll | C:\Windows\System32\aclui.dll |
权限字符串、继承标记 (OI/CI) 解析,与资源管理器安全 UI 共用同一套解析逻辑 |
| ntfs.sys | C:\Windows\System32\drivers\ntfs.sys |
NTFS 内核驱动;读写 MFT 内部安全描述符 SD;内核层访问权限校验 |
| lsass.exe | 系统进程 | SID <--> 用户 / 组名双向翻译;本地安全账号数据库读取;域 SID 需要 RPC 交互域控制器 |
icacls
/save输出的 aclfile:自定义文本格式,不是注册表、不是二进制 SD,只能被 icacls /restore 解析。
三、依赖关系
完整调用链路
icacls.exe 解析命令行参数
↓
advapi32.dll 安全API
↓
├─SID解析 → RPC调用 lsass.exe(本地/域账号解析)
└─GetNamedSecurityInfo / SetNamedSecurityInfo → 系统调用进入内核
↓
ntfs.sys 读写磁盘MFT记录中的安全描述符SD
↓
控制台输出 / 写入aclfile备份文本
运行前置约束
- 文件系统:必须 NTFS;FAT32/exFAT 没有 MFT 安全描述符,ACL 全部操作报错。
- 运行账号权限
- 读取 ACL:对象需要
READ_CONTROL - 修改 DACL(/grant/deny /remove):需要
WRITE_DAC - 修改所有者
/setowner:需要WRITE_OWNER;icacls 不会强制夺取所有权,权限不足直接失败,必须搭配 takeown.exe。
- 读取 ACL:对象需要
- 符号链接:默认跟随链接指向的目标;
/L参数才操作符号链接本身。 - 域环境:离线断网时,域 SID 无法翻译,输出原始 SID 字符串。
四、逻辑链路(子命令执行时序)
1. icacls name /save aclfile [/T /C /L /Q]
/T开启递归,遍历目录树所有对象;- 调用
GetNamedSecurityInfo读取 SD,只提取 DACL,丢弃 Owner/SACL/ 完整性标签; - 将对象路径、ACE 条目、继承标记写入自定义文本 aclfile。
2. icacls directory /restore aclfile [/substitute SidOld SidNew] [/C /L /Q]
- 读取解析 aclfile 文本;
- 如有
/substitute执行 SID 替换; - 调用
SetNamedSecurityInfo,仅把 DACL 写回 NTFS 对象;不触碰所有者、SACL、完整性标签。
/T在 restore 下无效,备份文件内已记录全部子项路径。
3. /setowner user
- 用户 / 组名解析为 SID;
- 修改 SD 内部 Owner 字段;
边界:无强制夺取权限;权限不足直接报错,需要前置 takeown。
4. /grant[:r] Sid:perm
- 不带
:r:叠加模式,新增 ACE,原有显式允许 ACE 保留; - 带
:r:替换模式,清除该 SID 全部显式允许 ACE,只保留本次授予权限,不修改拒绝、继承 ACE; - 构造 ACE 加入 DACL,icacls 自动规范化重排 ACE 顺序。
5. /deny Sid:perm
新增显式拒绝 ACE;拒绝优先级最高;同时清除该 SID 同权限的允许 ACE。
6. /remove[:g|:d] Sid
- 无后缀:删除该 SID 全部 ACE(允许 + 拒绝)
:g:仅删除允许 ACE:d:仅删除拒绝 ACE
7. /inheritance:e|d|r
e:启用继承,恢复继承父目录 DACL;d:禁用继承,把继承 ACE 复制为本对象显式 ACE(GUI:禁用继承→复制权限)r:禁用继承,彻底删除全部继承 ACE(GUI:禁用继承→删除继承权限)
8. /reset
清除本对象所有显式 DACL;完全使用父目录继承下来的 ACL。
9. /findsid /verify
/findsid Sid:递归扫描,找出 DACL 中显式包含该 SID 的文件;/verify:扫描 ACL 是否乱序、ACE 计数异常,识别损坏不规范 ACL。
10. /setintegritylevel
向 SD 添加 MIC 强制完整性 ACE,控制低完整性进程访问权限。
通用参数逻辑
/T:递归本目录及子文件子文件夹执行操作;/C:遇到访问拒绝、错误不终止整体任务,输出错误继续执行;/L:操作符号链接本身,而不是链接指向目标;/Q:静默模式,屏蔽成功输出,仅输出错误信息。
五、配套链
系统原生配套工具
- takeown.exe:夺取对象所有者;处理权限锁死目录标准流程:
takeown → icacls;icacls 无法强制夺取所有权。 - cacls.exe:旧版废弃工具;不支持完整性标签、精细继承控制、备份还原。
- 资源管理器安全 UI:文件夹属性→安全→高级安全设置;底层复用
advapi32.dll+aclui.dll同一套 API。
脚本配套组件
- PowerShell
Get‑Acl / Set‑Acl:.NET 封装同一套 Win32 安全 API;可以完整备份Owner+DACL+SACL 完整性标签,弥补 icacls/save缺失项。 - 备份还原组合工作流
- icacls
/save:快速批量备份 DACL; - PowerShell Export‑CliXml:完整全量安全描述符 SD 备份。
- icacls
标准运维流水线(修复权限锁死目录)
takeown /f "D:\target_dir" /r /c
icacls "D:\target_dir" /reset /t /c
icacls "D:\target_dir" /grant Administrators:(F) SYSTEM:(F) /t /c
六、边界约束(坑点汇总)
| 边界分类 | 风险说明 |
|---|---|
| 备份还原边界 | /save只保存 DACL;所有者、SACL 审计、完整性标签不会备份,restore 不会恢复,运维高频踩坑。 |
| 所有者边界 | /setowner不能强制夺取所有权;权限不足直接失败,必须前置 takeown.exe。 |
| 继承参数混淆 | /inheritance:d复制继承 ACE;/inheritance:r直接删除继承 ACE,两个参数行为差异巨大。 |
| SID 格式坑 | 数字 SID 必须前缀*,如*S‑1‑1‑0,缺少 * 会解析失败。 |
| 符号链接边界 | 默认跟随链接目标;修改链接本身权限必须加/L。 |
| ACE 自动重排 | 手动构造乱序 DACL,icacls 写入时自动规范化排序;/verify用于检测异常 ACL。 |
| 共享权限隔离 | icacls 只操作NTFS 本地 ACL,完全不处理 SMB 共享权限;网络访问有效权限 = NTFS ACL ∩ 共享权限。 |
| 拒绝 ACE 副作用 | /deny添加显式拒绝,优先级最高;大量拒绝 ACE 会造成排错困难,尽量少用。 |
:r替换范围 |
/grant:r只替换该 SID显式允许 ACE,不碰拒绝 ACE、继承 ACE。 |
| 文件系统限制 | FAT32/exFAT 没有安全描述符,ACL 全部命令报错。 |
卡脖子痛点:
- 误以为
/save完整备份全部安全属性,丢失所有者、审计 SACL;- 锁死对象直接调用 icacls 改所有者,忘记 takeown 全部操作失败;
d与r继承参数混淆,造成权限意外丢失。
七、自动化流水线(批处理 + PowerShell)
批处理模板
::备份DACL
icacls "D:\MyData" /save acl_backup.txt /T /C /Q
::还原DACL
icacls "D:\" /restore acl_backup.txt /C /Q
::授予管理员完全控制(替换原有显式权限)
icacls "D:\MyData" /grant:r Administrators:(F) SYSTEM:(F) /T /C
::禁用继承,复制继承ACE为显式权限
icacls "D:\MyData" /inheritance:d
::删除Everyone全部ACE
icacls "D:\MyData" /remove Everyone /T /C
::设置中等完整性级别
icacls "D:\MyData" /setintegritylevel M /T
PowerShell 脚本
$path = "D:\MyData"
#导出icacls权限报告
& icacls $path /T /C | Out‑File "acl_report.txt"
#校验ACL规范性
& icacls $path /verify /T /C
#修复锁死目录
takeown /f $path /r /c
icacls $path /reset /t /c
icacls $path /grant Administrators:(F) SYSTEM:(F) /t /c
完整安全描述备份(弥补 icacls 缺陷,包含 Owner/DACL/SACL)
#完整SD备份
Get‑Acl $path -Audit | Export‑CliXml "Full_SecurityDescriptor.xml"
#完整SD恢复
Import‑CliXml "Full_SecurityDescriptor.xml" | Set‑Acl $path
icacls.exe + takeown.exe + cacls.exe + 资源管理器安全 UI 完整解构
分析框架:底层原理|依赖文件|依赖关系|逻辑链路|配套链|边界|自动化 定位:Windows NTFS 访问控制全套原生工具栈。
icacls.exe:现代命令行 DACL / 继承 / 完整性标签管理takeown.exe:仅修改安全描述符 Owner 所有者 SID,用于解锁权限锁死对象cacls.exe:遗留兼容工具,功能残缺已废弃- 资源管理器安全 UI:图形交互外壳,底层和命令行共用同一套安全 API
一、底层原理
NTFS 安全描述符 SD 基础模型
SD 四元组:Owner(所有者SID) | Group | DACL自主访问控制列表 | SACL审计ACL
- Owner 特权规则:无论 DACL 如何拒绝,对象所有者天然拥有
WRITE_OWNER权限,可以重设 ACL;这是takeown能够解锁文件的理论基础。 takeown.exe只改写 Owner 字段,不改动 DACL、SACL、完整性标签。夺取所有权之后,再交由icacls.exe修改 DACL 权限。icacls.exe:操作 DACL、继承、MIC 完整性标签;没有能力强制修改 Owner,没有 SE_RESTORE 特权时直接报错。cacls.exe:仅能读写基础 DACL;不识别 MIC 完整性标签、高级继承标志OI/CI/NP,无备份还原能力。- 资源管理器安全 UI:
aclui.dll做界面封装,不实现权限内核逻辑;读写 SD 全部转发advapi32.dll;GUI “禁用继承” 两个选项与 icacls 参数一一对应:- 复制继承权限 →
icacls /inheritance:d - 删除继承权限 →
icacls /inheritance:r
- 复制继承权限 →
- ACE 规范化排序(四阶顺序,命令行与 GUI 统一)
- 显式拒绝 ACE
- 显式允许 ACE
- 继承拒绝 ACE
- 继承允许 ACE
二、依赖文件
| 组件 | 程序路径 | 核心依赖 |
|---|---|---|
| icacls.exe | %SystemRoot%\System32\icacls.exe |
advapi32.dll、ntfs.sys、lsass.exe、aclui.dll(字符串解析) |
| takeown.exe | %SystemRoot%\System32\takeown.exe |
advapi32.dll、ntfs.sys、lsass.exe |
| cacls.exe | %SystemRoot%\System32\cacls.exe |
advapi32.dll、ntfs.sys、lsass.exe |
| 资源管理器安全 UI | explorer.exe + aclui.dll 对话框 | explorer.exe、aclui.dll、advapi32.dll、ntfs.sys、lsass.exe |
公共依赖说明
advapi32.dll:提供 Win32 安全 APIGetNamedSecurityInfo/SetNamedSecurityInfo,读写 NTFS 对象安全描述符 SD。lsass.exe:SID ↔ 用户 / 组名双向解析;本地 SAM 账号、域账号翻译。ntfs.sys:内核驱动,MFT 记录持久化 SD,内核态访问权限校验。aclui.dll:权限掩码、继承标记解析与图形对话框渲染;takeown不加载此模块。
三、依赖关系
调用链路
takeown.exe
takeown.exe 解析命令行参数 /f /r /c
↓
advapi32.dll::SetNamedSecurityInfo 仅修改SD.Owner字段
↓
lsass.exe 解析当前进程Token得到当前用户SID
↓
系统调用进入内核 → ntfs.sys 将Owner SID写入MFT
icacls.exe
icacls.exe 参数解析(/grant /deny /save /restore /inheritance…)
↓
advapi32.dll Get/SetNamedSecurityInfo 读写SD(DACL、MIC完整性标签)
↓
lsass.exe SID名称转换
↓
ntfs.sys MFT读写安全描述符
cacls.exe
cacls.exe 参数解析
↓
advapi32.dll 仅读写DACL,忽略MIC标签,继承支持有限
↓
lsass SID解析
↓
ntfs.sys MFT读写
资源管理器安全 UI
explorer.exe 右键→属性→安全→高级
↓
加载aclui.dll渲染权限编辑对话框
↓
aclui.dll内部调用advapi32.dll安全API
↓
lsass SID翻译
↓
ntfs.sys 读写MFT安全描述符SD
前置运行条件
- 文件系统必须为NTFS;FAT32/exFAT 不存在安全描述符,全部 ACL 相关操作报错无效。
takeown.exe需要管理员提升权限,需要开启特权SE_RESTORE_NAME;普通过滤管理员 Token 无法夺取所有者。- icacls 修改 DACL 需要对象
WRITE_DAC权限;修改 Owner 需要WRITE_OWNER;无特权时不能强制夺取所有者。 - 域环境离线场景:域 SID 无法解析,界面与命令行直接输出原始 SID 字符串。
- 符号链接:
- takeown:无
/L参数,总是跟随符号链接目标,不能修改链接本身所有者; - icacls:提供
/L,可操作符号链接自身; - 资源管理器:默认跟随符号链接目标。
- takeown:无
四、逻辑链路
标准解锁时序(权限锁死目录完整流水线)
1. takeown /f "D:\LockedDir" /r /c
→ 修改全部子对象Owner为当前管理员SID,DACL保持原样
2. icacls "D:\LockedDir" /reset /t /c
→ 清除显式DACL,恢复父目录继承ACL
3. icacls "D:\LockedDir" /grant Administrators:(F) SYSTEM:(F) /t /c
→ 重新授予业务需要的访问权限
各工具能力对比
| 能力 | icacls.exe | takeown.exe | cacls.exe | 资源管理器安全 UI |
|---|---|---|---|---|
| 修改 Owner 所有者 | ❌不能强制夺取 | ✅仅修改 Owner | ❌不支持 | ✅支持 |
| DACL 读写、授权拒绝 | ✅完整支持 | ❌不处理 DACL | ✅基础支持 | ✅完整支持 |
| 继承精细控制 OI/CI/NP | ✅完整 | ❌ | ❌有限 | ✅完整 |
| 完整性 MIC 标签 | ✅支持 | ❌ | ❌不识别 | ✅支持 |
| DACL 备份 /restore 还原 | ✅支持 | ❌ | ❌ | ❌ |
| 符号链接操作 (/L) | ✅支持 | ❌无参数 | ❌ | ❌ |
关键行为边界
takeown执行完成不等于拥有访问权限,必须后续 icacls 修改 DACL 才可以正常读写文件。- icacls
/save只备份 DACL;Owner、SACL、MIC 标签不保存。 - cacls 输出文本格式与 icacls 备份文件互不兼容,不可混用还原。
五、配套链
系统原生配套
- PowerShell
Get‑Acl / Set‑Acl:.NET 封装同一套 Win32 安全 API;可完整备份 SD 全部字段(Owner+DACL+SACL+MIC),弥补 icacls 备份缺陷。 - 事件日志:安全日志可以记录对象所有者变更、ACL 修改审计(需要开启 SACL 审计策略)。
运维配套工作流
- 锁死目录修复流水线:
takeown → icacls /reset → icacls /grant - 批量权限迁移:icacls
/save备份 DACL;目标机器/restore恢复;重要场景搭配 PowerShell 做完整 SD 备份。 - 脚本兼容:新脚本禁止使用 cacls.exe,统一使用 icacls.exe。
六、边界约束(风险坑点)
| 分类 | 边界风险 |
|---|---|
| takeown 边界 | 只改 Owner,DACL 不变;UAC 未提升管理员,夺取所有者直接失败;无符号链接 / L 参数。 |
| icacls 边界 | /save不保存 Owner/SACL/ 完整性标签;不能强制夺取所有者;/grant:r仅替换显式允许 ACE;/inheritance:d与/inheritance:r极易混淆。 |
| cacls 边界 | 已废弃;不支持 MIC、高级继承、备份还原;不要在新自动化脚本中使用。 |
| GUI 边界 | 图形界面操作本质等价命令行;大量文件批量修改 GUI 性能极差,适合单点调试,批量优先命令行。 |
| 文件系统边界 | FAT32/exFAT 无安全描述符,全部 ACL 操作无效。 |
| 特权边界 | 修改 Owner、批量 ACL 修改,都需要提升管理员权限;普通用户会出现拒绝访问。 |
| 符号链接 | takeown 无法修改链接本身所有者,只能修改目标;icacls 需要显式/L。 |
卡脖子痛点:
- 执行 takeown 之后直接访问文件仍然报错,忘记后续 icacls 重设 DACL;
- 使用 icacls 尝试直接修改锁死对象所有者,操作失败;
- 把 icacls
/save当做完整安全描述符备份,迁移后丢失所有者、审计标签。
七、自动化流水线
批处理完整解锁模板
@echo off
set "TARGET=D:\LockedFolder"
::1.夺取所有者
takeown /f "%TARGET%" /r /c
::2.重置ACL,恢复继承
icacls "%TARGET%" /reset /t /c
::3.授予管理员、系统完全控制
icacls "%TARGET%" /grant Administrators:(F) SYSTEM:(F) /t /c
::4.备份DACL
icacls "%TARGET%" /save acl_backup.txt /T /C /Q
PowerShell 完整 SD 备份(弥补 icacls 备份缺陷)
$path = "D:\LockedFolder"
#完整安全描述备份,包含Owner、DACL、SACL、完整性标签
Get‑Acl -Path $path -Audit | Export‑CliXml Full_SD_Backup.xml
#完整恢复
Import‑CliXml Full_SD_Backup.xml | Set‑Acl -Path $path
PowerShell 批量巡检
$scanPath = "D:\Data"
& icacls $scanPath /verify /T /C | Out‑File acl_verify_report.txt




Windows NTFS 文件 / 文件夹安全 ACL 权限(截图界面完整解构)
分析框架:底层原理|依赖文件|依赖关系|逻辑链路|配套链|边界|自动化 截图序列:①文件夹属性‑安全选项卡 →②高级安全设置 →③权限项目编辑窗口;对象路径:
C:\Users\Administrator\Desktop\优化条目,NTFS 访问控制列表 ACL 图形编辑器。
一、底层原理
- NTFS 元数据层面:每个文件 / 文件夹都存在一个安全描述符 SD (Security Descriptor),存储于 MFT 主文件表记录内部;安全描述符包含:所有者 SID、组 SID、DACL 自主访问控制列表、SACL 系统访问控制列表(审计)。
- DACL(自主访问控制列表):就是截图中一条条权限条目,每条 ACE 访问控制项包含:主体 SID (用户 / 组)、类型 (允许 / 拒绝)、访问掩码 (权限位)、继承标志、应用于范围。
- 截图②可见:
继承于:C:\Users\Administrator\,权限从父文件夹继承而来;应用于:此文件夹、子文件夹和文件控制继承传播。
- 截图②可见:
- 权限计算逻辑
- 拒绝 ACE 优先级 > 允许 ACE;只要存在拒绝,优先拦截访问。
- 先评估本对象 ACE,再评估继承下来 ACE;用户有效权限 = 用户 SID + 用户所属全部组 SID 合并后的权限集合。
- 所有者 (Owner) 特权:截图②所有者是
Administrators,对象所有者可以无视 DACL,修改权限,这是 Windows 权限体系非常关键的后门机制。
- 继承机制:新建对象默认继承父目录 DACL;点击【禁用继承】可以切断继承,二选一:复制继承权限 / 删除继承权限。
- 访问掩码:截图③基本权限是高层封装;底层是32 位 bit 位掩码,完全控制、修改、读取执行都是多个底层 bit 的组合;点击「显示高级权限」可以看到原始细粒度 bit 权限。
注意:共享权限和 NTFS ACL 是两套独立权限;最终有效权限取两者交集,截图是 NTFS 本地 ACL,不是共享权限。
二、依赖文件
| 文件 / 组件 | 路径 | 作用 |
|---|---|---|
ntfs.sys |
%SystemRoot%\System32\drivers\ntfs.sys |
NTFS 内核驱动,读写 MFT 里面安全描述符 SD;内核完成访问权限校验 |
aclui.dll |
%SystemRoot%\System32\aclui.dll |
截图全部安全 UI 对话框实现:属性安全页、高级安全设置、编辑权限项目全部由这个 DLL 渲染 |
advapi32.dll |
%SystemRoot%\System32\advapi32.dll |
Win32 安全 API:GetNamedSecurityInfo / SetNamedSecurityInfo 获取、设置对象安全描述符 SD |
lsass.exe |
系统进程 | SID 解析、用户名‑SID 互相转换、用户组成员 SID 展开,UI 把 SID 翻译为人可读账号名称 |
| MFT($MFT) | NTFS 卷元数据,无直接文件路径 | 每个文件记录里面存储 Security Descriptor 安全描述符 |
注册表无直接存储:NTFS 安全描述符保存在磁盘 MFT,不在注册表。
三、依赖关系
完整调用链路(打开截图安全属性窗口)
资源管理器explorer.exe 右键文件夹 → 属性 → 安全选项卡
↓
explorer 加载 aclui.dll (ACL图形UI组件,截图全部窗口由它绘制)
↓
aclui.dll 调用 advapi32.dll API GetNamedSecurityInfoW
↓
内核转发到 ntfs.sys,读取磁盘MFT内该文件夹的安全描述符SD(DACL/所有者/SACL)
↓
aclui.dll RPC调用 lsass.exe:把SID翻译为用户名/组名,填充界面列表
↓
用户编辑权限、点应用 → SetNamedSecurityInfoW → ntfs.sys 将新SD写回MFT记录
外部依赖
- 文件系统必须是 NTFS;FAT32/exFAT 无安全描述符,安全选项卡会直接灰掉不可用。
- lsass.exe 正常运行:SID‑用户名解析依赖 lsass;lsass 异常界面会显示 SID 字符串而不是中文账号名。
- 权限依赖:修改 ACL / 所有者,需要对象 WRITE_DAC 权限;修改所有者需要 WRITE_OWNER 权限;普通读取安全页只需要 READ_CONTROL。
- 继承依赖:父文件夹存在有效的 DACL;新建对象默认继承父 ACE。
- 域环境:域 SID 需要域控制器解析账号名称;断网会显示 SID。
四、逻辑链路(时序,对应三张截图操作)
- 第一幅截图【属性‑安全】: explorer 加载 aclui.dll,读取 MFT 安全描述,解析 DACL,展示组或用户名列表,展示简化后的基础权限勾选框;点击【编辑】进入权限修改;点击【高级 (V)】跳转第二张截图高级安全设置。
- 第二幅截图【高级安全设置】
- 展示所有者、审核 SACL、完整 ACE 权限条目;每一条 ACE 显示:主体、类型、访问权限、继承来源、应用于范围。
- 【禁用继承】:切断来自父文件夹的权限继承;
- 选中 ACE,点击【编辑】,跳转第三张截图权限项目窗口。
- 第三幅截图【权限项目】
- 主体:用户 / 组 SID;类型:允许 / 拒绝;应用于:控制继承传播范围(此文件夹 / 子文件夹 / 文件)。
- 基本权限是高层封装;点击【显示高级权限】展开底层细粒度 bit 掩码。
- 勾选 / 取消权限 → 确定,构造新 ACE,写回对象 DACL。
- 点击全部窗口「应用」:调用
SetNamedSecurityInfo将新安全描述符 SD 写入 NTFS MFT。
关键边界逻辑
- 继承于字段:代表这条 ACE 不是本对象显式设置,复制自父目录;禁用继承后该字段消失。
- 应用于:控制 ACE 向下传播到子文件夹、子文件;是 NTFS 继承体系核心。
- 所有者权限:哪怕 DACL 全部拒绝,对象所有者依然可以修改权限;这是 Windows 设计,用于防止彻底锁死对象。
五、配套链
- 图形配套
cacls.exe:旧版命令行 ACL 工具,已逐步废弃。icacls.exe:现代 Windows ACL 命令行工具,查询、设置、备份、恢复 NTFS 权限。
- 编程接口
- Win32 API:
GetNamedSecurityInfo/SetNamedSecurityInfo - PowerShell:
Get‑Acl/Set‑Acl,封装上面 Win32 API,脚本自动化操作 ACL。
- 运维配套
- icacls 支持导出权限备份:
icacls 路径 /save acl_backup.txt,可恢复权限。 - 取得所有权:需要先修改所有者,才能修改被锁死对象 ACL。
六、边界约束 & 坑点
| 边界分类 | 详细说明 |
|---|---|
| 文件系统边界 | FAT32/exFAT 无 SD 安全描述符,安全选项卡灰色;仅 NTFS 支持完整 ACL。 |
| 继承坑点 | 子对象 “不继承”;复制 / 移动文件夹权限行为不同:同卷移动保留原 ACL;跨卷复制继承目标父文件夹 ACL。 |
| 拒绝 ACE 优先级 | 拒绝条目优先级高于允许;GUI 顺序不影响计算结果,很多人误以为列表从上到下判断,实际不是顺序匹配。 |
| 所有者边界 | 对象所有者可以绕过 DACL 拒绝,修改权限;即使 DACL 全部拒绝访问,所有者依然可以编辑安全。 |
| 应用于边界 | 「仅将这些权限应用到此容器中的对象和 / 或容器」= 只给子对象,本对象不生效,容易配置错。 |
| 共享 + NTFS 交集 | 网络访问时,有效权限 = NTFS ACL 和 共享权限两者取最小交集;很多故障只改 NTFS 忽略共享权限。 |
| SID 失效坑点 | 账号删除后,ACE 残留孤立 SID;UI 显示 SID 一串数字,无用户名。 |
| 加密 EFS 边界:EFS 加密文件,ACL 控制访问,但解密还需要用户 EFS 证书私钥,ACL 不能控制解密行为。 |
卡脖子痛点
- 文件夹移动复制,继承行为不符合预期,权限错乱;
- 只看 DACL,忽略所有者特权,以为设置拒绝就完全锁死;
- 混淆「共享权限」和「NTFS 本地 ACL」,网络访问权限故障。
七、自动化流水线(PowerShell + icacls)
1、读取文件夹 NTFS 安全描述 ACL(替代 GUI 查看)
$path = "C:\Users\Administrator\Desktop\优化条目"
Get-Acl -Path $path | Format-List
# 查看详细ACE条目
(Get-Acl $path).Access
2、icacls 查询权限(命令行)
icacls "C:\Users\Administrator\Desktop\优化条目"
3、备份整个目录树 ACL 权限
icacls "C:\Users\Administrator\Desktop\优化条目" /save acl_backup.txt /t
4、恢复 ACL 备份
icacls "C:\Users\Administrator\Desktop\" /restore acl_backup.txt
5、PowerShell 添加一条允许 ACE(读取和执行,对应截图③勾选状态)
$path = "C:\Users\Administrator\Desktop\优化条目"
$acl = Get‑Acl $path
$identity = "Everyone"
# 权限:读取和执行,列出文件夹内容,读取
$rights = "ReadAndExecute, ListDirectory, Read"
$accessRule = New‑Object System.Security.AccessControl.FileSystemAccessRule($identity,$rights,"ContainerInherit,ObjectInherit","None","Allow")
$acl.AddAccessRule($accessRule)
Set‑Acl -Path $path -AclObject $acl
6、禁用继承,复制已继承权限到本对象
$acl = Get‑Acl $path
# 参数 $true = 将继承ACE复制为本对象显式ACE;$false = 删除继承权限
$acl.SetAccessRuleProtection($true,$true)
Set‑Acl -Path $path -AclObject $acl
说明:
SetAccessRuleProtection($isProtected,$preserveInheritance)等价 GUI【禁用继承】的两个选项。

ICACLS命令 高级的文件和文件夹权限管理工具,支持更多功能
——————————————————————————————————————————————————————————————
ICACLS name /save aclfile [/T] [/C] [/L] [/Q]
将匹配名称的文件和文件夹的 DACL 存储到 aclfile 中以便将来与 /restore 一起使用。请注意,未保存 SACL、所有者或完整性标签。
ICACLS directory [/substitute SidOld SidNew [...]] /restore aclfile [/C] [/L] [/Q]
将存储的 DACL 应用于目录中的文件。
ICACLS name /setowner user [/T] [/C] [/L] [/Q]
更改所有匹配名称的所有者。该选项不会强制更改所有身份;使用 takeown.exe 实用程序可实现该目的。
ICACLS name /findsid Sid [/T] [/C] [/L] [/Q]
查找包含显式提及 SID 的 ACL 的所有匹配名称。
ICACLS name /verify [/T] [/C] [/L] [/Q]
查找其 ACL 不规范或长度与 ACE计数不一致的所有文件。
ICACLS name /reset [/T] [/C] [/L] [/Q]
为所有匹配文件使用默认继承的 ACL 替换 ACL。
ICACLS name [/grant[:r] Sid:perm[...]]
[/deny Sid:perm [...]]
[/remove[:g|:d]] Sid[...]] [/T] [/C] [/L] [/Q]
[/setintegritylevel Level:policy[...]]
/grant[:r] Sid:perm 授予指定的用户访问权限。如果使用 :r,这些权限将替换以前授予的所有显式权限。
如果不使用 :r,这些权限将添加到以前授予的所有显式权限。
/deny Sid:perm 显式拒绝指定的用户访问权限。将为列出的权限添加显式拒绝 ACE,并删除所有显式授予的权限中的相同权限。
/remove[:[g|d]] Sid 删除 ACL 中所有出现的 SID。使用
:g,将删除授予该 SID 的所有权限。使用
:d,将删除拒绝该 SID 的所有权限。
/setintegritylevel [(CI)(OI)]级别将完整性 ACE 显式添加到所有匹配文件。要指定的级别为以下级别之一:
L[ow]
M[edium]
H[igh]
完整性 ACE 的继承选项可以优先于级别,但只应用于目录。
/inheritance:e|d|r
e - 启用继承
d - 禁用继承并复制 ACE
r - 删除所有继承的 ACE
——————————————————————————————————————————————————
注意:
Sid 可以采用数字格式或友好的名称格式。如果给定数字格式,那么请在 SID 的开头添加一个 *。
/T 指示在以该名称指定的目录下的所有匹配文件/目录上执行此操作。
/C 指示此操作将在所有文件错误上继续进行。仍将显示错误消息。
/L 指示此操作在符号链接本身而不是其目标上执行。
/Q 指示 icacls 应该禁止显示成功消息。
————————————————————————————————————————————————————
ICACLS 保留 ACE 项的规范顺序:
显式拒绝
显式授予
继承的拒绝
继承的授予
perm 是权限掩码,可以指定两种格式之一:
简单权限序列:
N - 无访问权限
F - 完全访问权限
M - 修改权限
RX - 读取和执行权限
R - 只读权限
W - 只写权限
D - 删除权限
在括号中以逗号分隔的特定权限列表:
DE - 删除
RC - 读取控制
WDAC - 写入 DAC
WO - 写入所有者
S - 同步
AS - 访问系统安全性
MA - 允许的最大值
GR - 一般性读取
GW - 一般性写入
GE - 一般性执行
GA - 全为一般性
RD - 读取数据/列出目录
WD - 写入数据/添加文件
AD - 附加数据/添加子目录
REA - 读取扩展属性
WEA - 写入扩展属性
X - 执行/遍历
DC - 删除子项
RA - 读取属性
WA - 写入属性
继承权限可以优先于每种格式,但只应用于目录:
(OI) - 对象继承
(CI) - 容器继承
(IO) - 仅继承
(NP) - 不传播继承
(I) - 从父容器继承的权限
————————————————————————————————————————
示例:
icacls c:\windows\* /save AclFile /T
- 将 c:\windows 及其子目录下所有文件的ACL 保存到 AclFile。
icacls c:\windows\ /restore AclFile
- 将还原 c:\windows 及其子目录下存在的 AclFile 内所有文件的 ACL。
icacls file /grant Administrator:(D,WDAC)
- 将授予用户对文件删除和写入 DAC 的管理员权限。
icacls file /grant *S-1-1-0:(D,WDAC)
- 将授予由 sid S-1-1-0 定义的用户对文件删除和写入 DAC 的权限。
icacls.exe 完整解构
分析框架:底层原理|依赖文件|依赖关系|逻辑链路|配套链|边界|自动化 定位:Windows 现代 NTFS DACL 权限命令行工具,替代老旧 cacls.exe;操作 NTFS 安全描述符 DACL,支持备份还原、所有者、完整性标签、继承管理。
一、底层原理
- 内核对象基础 NTFS 每个文件 / 文件夹 MFT 记录存储安全描述符 SD,SD 包含:
Owner(所有者)、Group、DACL自主访问控制列表、SACL审计ACL、完整性标签ACE。
⚠️
/save仅保存 DACL;不保存所有者、SACL 审计、完整性标签,/restore也不会恢复这几项。
- ACE 排序规范(icacls 强制规范) icacls 写入 ACL 时会自动重排 ACE 顺序,Windows 访问校验遵循该优先级:
- 显式拒绝 ACE
- 显式允许 ACE
- 继承拒绝 ACE
- 继承允许 ACE
GUI 高级安全编辑器也遵循这套顺序;乱序 DACL 属于不规范 ACL,
/verify可检测。
- 权限掩码两套体系
- 简易权限缩写:
F完全、M修改、RX读取执行、R只读、W写入、D删除;是多细粒度位的组合封装。 - 细粒度原始位掩码:
DE,RC,WDAC,WO,RD,WD,AD,X,DC…,对应 Win32 底层访问掩码比特位。
-
继承标志位(OI/CI/IO/NP)
标记 含义 (OI)ObjectInherit对象继承:文件继承 ACE (CI)ContainerInherit容器继承:子文件夹继承 ACE (IO)InheritOnly仅继承,本对象不生效,只传给子对象 (NP)NoPropagateInherit不传播继承,只向下一级,不再递归深层 (I)Inherited该 ACE 是继承而来,非本对象显式 ACE - 完整性标签(Mandatory Label) Windows 强制完整性控制 MIC;
/setintegritylevel添加完整性 ACE:Low/Medium/High;低完整性进程无法写入高完整性对象。 - SID 解析:支持账号名,也支持
*S‑1‑xxx原始 SID 数字格式。
二、依赖文件
| 组件 | 路径 | 作用 |
|---|---|---|
icacls.exe |
%SystemRoot%\System32\icacls.exe |
主可执行程序 |
advapi32.dll |
%SystemRoot%\System32\advapi32.dll |
底层 Win32 安全 API:GetNamedSecurityInfo / SetNamedSecurityInfo、SID 转换 API |
aclui.dll |
%SystemRoot%\System32\aclui.dll |
权限掩码、继承标记字符串解析(与资源管理器安全界面共用同一套逻辑) |
ntfs.sys |
%SystemRoot%\System32\drivers\ntfs.sys |
NTFS 内核驱动,读写 MFT 中的安全描述符 SD,执行访问校验 |
lsass.exe |
系统进程 | SID ↔ 用户名 / 组名双向解析;处理本地账号、域账号 SID 翻译 |
备份输出的
aclfile是文本格式自定义格式文件,不是标准注册表,仅能被 icacls/restore读取。
三、依赖关系
调用链路
icacls.exe 命令行参数解析
↓
advapi32.dll Win32安全API
↓
1. SID名称解析 → RPC调用 lsass.exe
2. 获取/设置安全描述符SD → 系统调用转发内核
↓
ntfs.sys 读写磁盘MFT记录内SD(DACL/完整性标签)
↓
输出控制台文本 / 写入aclfile备份文件
前置依赖条件
- 文件系统必须为NTFS;FAT32/exFAT 无安全描述符,icacls 大部分参数报错。
- 运行身份权限:
- 读取 ACL:需要对象
READ_CONTROL权限。 - 修改 DACL (/grant/deny /remove):需要
WRITE_DAC权限。 - 修改所有者
/setowner:需要WRITE_OWNER权限;icacls 不会强制夺取所有权;无法修改时需要配合takeown.exe。
- 读取 ACL:需要对象
- 符号链接:默认操作目标文件;
/L参数操作符号链接本身,不跟随指向对象。 - 域环境:域 SID 解析依赖域控制器;离线会显示 SID 字符串。
四、逻辑链路(核心子命令时序)
1. /save 备份
- 遍历路径(带
/T递归子目录) - 调用
GetNamedSecurityInfo读取对象仅 DACL;丢弃 Owner/SACL/ 完整性标签 - 将路径、ACE、继承标志、权限掩码写入自定义文本 aclfile。
重要:SACL 审计、所有者、完整性标签不会备份进去。
2. /restore 还原
- 读取 aclfile 文本;解析每一条记录的路径 + DACL。
/substitute先替换 SID;- 调用
SetNamedSecurityInfo把 DACL 写回对应 NTFS 对象;不碰所有者、SACL、完整性标签。 /T不生效,备份文件内部已经记录全部子项。
3. /setowner user 修改所有者
- 解析用户名→SID;
- 设置 SD 内 Owner 字段;
限制:不会强制夺取所有权;当前账号没有 WRITE_OWNER 会直接失败;需要先 takeown。
4. /grant[:r] Sid:perm
- 不带
:r:新增 / 叠加 ACE;原有显式允许 ACE 保留。 - 带
:r:替换该 SID 全部原有显式允许 ACE,只保留本次授予的权限。 - 构造 ACE,追加 DACL,icacls 自动重排 ACE 顺序。
5. /deny Sid:perm
新增显式拒绝 ACE;拒绝 ACE 优先级最高;同时清除该 SID 相同权限的允许 ACE。
6. /remove[:g|:d] Sid
- 无后缀:删除该 SID全部 ACE(允许 + 拒绝)
:g仅删除授予(允许 ACE):d仅删除拒绝 ACE
7. /inheritance:e|d|r
e:启用继承;恢复从父对象继承 DACL。d:禁用继承,把继承 ACE 复制为对象显式 ACE(GUI:禁用继承→复制权限)r:禁用继承,完全删除全部继承 ACE(GUI:禁用继承→删除继承权限)
8. /reset
删除当前对象显式 DACL;完全使用父目录继承下来的 ACL。
9. /setintegritylevel
向 DACL 添加强制完整性 MIC ACE,控制低完整性进程访问。
通用参数
/T:递归本目录及全部子文件子文件夹执行操作/C:遇到访问错误继续执行,输出错误,不中断整个批量任务/L:作用于符号链接本身,不是链接指向目标/Q:静默,关闭成功输出,只打印错误
五、配套链
系统配套工具
takeown.exe:夺取对象所有者;icacls/setowner无法强制夺取,修改锁死文件 ACL 标准流程:takeown → icaclscacls.exe:旧版废弃工具;不支持完整性标签、继承控制、备份还原。- 图形 UI:文件夹属性→安全→高级安全设置,底层 API 与 icacls 同源。
脚本配套
- PowerShell
Get‑Acl / Set‑Acl:.NET 封装同一套 Win32 安全 API;适合复杂逻辑脚本。 - 备份恢复工作流:
icacls /save备份 DACL;注意单独处理所有者、SACL 审计、完整性标签(icacls 不保存)。
完整标准运维流程(处理权限锁死文件夹)
::1.夺取所有者
takeown /f "D:\target" /r
::2.重置ACL继承
icacls "D:\target" /reset /t /c
::3.重新授权
icacls "D:\target" /grant Administrators:(F) SYSTEM:(F) /t
六、边界约束 & 坑点
| 边界分类 | 详细风险说明 |
|---|---|
| 备份边界 | /save只存 DACL;所有者、SACL 审计策略、完整性标签不会保存;restore 也不会恢复,很多运维踩坑。 |
| /setowner 边界 | icacls 不能强制夺取所有权;权限不足直接报错,必须搭配 takeown。 |
| 继承坑 | /inheritance:d复制继承 ACE 为显式;/inheritance:r直接删除继承 ACE,二者极易混淆。 |
| SID 格式坑 | 数字 SID 必须前缀*,例如*S‑1‑1‑0;遗漏 * 会解析失败。 |
| 符号链接坑 | 默认跟随链接目标;修改链接本身权限必须指定/L。 |
| ACE 顺序坑 | 手动构造乱序 DACL,icacls 写入会自动重排;第三方工具生成乱序 ACL 可用/verify检测。 |
| 共享权限隔离 | icacls 只操作NTFS 本地 ACL;不操作 SMB 共享权限;网络访问有效权限 = NTFS ∩ 共享权限。 |
| 拒绝 ACE 行为 | /deny添加显式拒绝,拒绝优先级最高;不要滥用拒绝 ACE,排错困难。 |
| /grant:r 作用域 | :r只替换该 SID显式允许 ACE,不碰拒绝 ACE、继承 ACE。 |
| FAT32/ExFAT | 不支持 SD,所有 ACL 修改命令报错。 |
卡脖子痛点:
- 误以为
/save完整备份全部安全属性,实际丢失所有者、SACL、完整性标签。 - 锁死文件夹直接用 icacls 改所有者,忘记 takeown,操作全部失败。
- 混淆
/inheritance:d与/inheritance:r,权限意外丢失。
七、自动化流水线(批处理 + PowerShell)
1. 批处理示例
::备份DACL
icacls "C:\MyData" /save acl_backup.txt /T /C /Q
::还原DACL
icacls "C:\" /restore acl_backup.txt /C /Q
::授予管理员完全控制,替换原有显式权限
icacls "C:\MyData" /grant:r Administrators:(F) /T /C
::禁用继承,复制继承ACE到本对象
icacls "C:\MyData" /inheritance:d
::删除Everyone所有ACE
icacls "C:\MyData" /remove Everyone /T /C
::设置中等完整性级别
icacls "C:\MyData" /setintegritylevel M /T
2. PowerShell 封装批量巡检脚本
$target = "C:\MyData"
#导出icacls文本报告
& icacls $target /T /C | Out‑File "acl_report.txt"
#检测不规范ACL
& icacls $target /verify /T /C
#结合takeown+icacls修复锁死目录
takeown /f $target /r /c
icacls $target /reset /t /c
icacls $target /grant Administrators:(F) SYSTEM:(F) /t /c
3. 注意:备份缺失项补充方案
icacls
/save不备份 Owner/SACL;如需完整安全描述备份,使用 PowerShellGet‑Acl序列化,可完整保存 Owner/DACL/SACL。
#完整SD备份(包含所有者、DACL、SACL)
Get‑Acl "C:\MyData" -Audit | Export‑CliXml "Full_SD_Backup.xml"
#完整恢复
Import‑CliXml "Full_SD_Backup.xml" | Set‑Acl "C:\MyData"
在 PowerShell 中,icacls 命令通常对应于 Get-Acl、Set-Acl、Add-AccessControlEntry 和 Remove-AccessControlEntry 等命令。下面是 icacls 命令和 PowerShell 对应命令的对比:
| 功能 | icacls 命令 |
PowerShell 对应命令 |
|---|---|---|
| 查看文件或文件夹的权限 | icacls <文件路径> |
Get-Acl <文件路径> |
| 授予用户权限 | icacls <文件路径> /grant <用户>:<权限> |
Add-AccessControlEntry -Path <文件路径> -User <用户> -AccessType <权限> |
| 撤销用户权限 | icacls <文件路径> /remove <用户> |
Remove-AccessControlEntry -Path <文件路径> -User <用户> |
| 修改权限 | icacls <文件路径> /grant <用户>:<权限> |
Set-Acl <文件路径> -AclObject (Get-Acl <文件路径> |
| 备份权限 | icacls <文件路径> /save <文件> /t |
Get-Acl <文件路径> |
| 恢复权限 | icacls <文件路径> /restore <文件> |
Import-Clixml -Path <文件> |
| 删除指定文件夹的继承 | icacls <文件路径> /inheritance:r |
Set-Acl <文件路径> -AclObject (Get-Acl <文件路径> |
| 显示权限详细信息 | icacls <文件路径> /T |
Get-Acl <文件路径> |
说明:
Get-Acl:用于查看文件或文件夹的权限(类似于icacls的查看功能)。Set-Acl:用于设置文件或文件夹的权限,可以结合Add-AccessControlEntry或Remove-AccessControlEntry来修改权限。Add-AccessControlEntry:用于授予用户或组权限。Remove-AccessControlEntry:用于删除用户或组的权限。Export-Clixml和Import-Clixml:用于备份和恢复权限。Remove-AccessControlInheritance:用于移除权限继承。
示例:
-
查看文件的权限(
icacls对应Get-Acl):powershellCopy Codeicacls "C:\example\file.txt"对应的 PowerShell 命令:
powershellCopy CodeGet-Acl "C:\example\file.txt" -
授予用户权限(
icacls对应Add-AccessControlEntry):powershellCopy Codeicacls "C:\example\file.txt" /grant User:F对应的 PowerShell 命令:
powershellCopy Code$acl = Get-Acl "C:\example\file.txt" $permission = "User", "FullControl", "Allow" $accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule $permission $acl.AddAccessRule($accessRule) Set-Acl "C:\example\file.txt" $acl -
删除继承权限(
icacls对应Set-Acl和Remove-AccessControlInheritance):powershellCopy Code$acl = Get-Acl "C:\example\file.txt" $acl.SetAccessRuleProtection($true, $false) # 禁用继承 Set-Acl "C:\example\file.txt" $acl
使用 PowerShell 时,你可以更细粒度地控制文件和文件夹的权限,通过脚本化实现自动化管理。
cacls 和 icacls 在版本上的差异对比:
| 特性 | cacls |
icacls |
|---|---|---|
| 可用操作系统版本 | Windows XP及更早版本 | Windows Vista及之后版本 |
| 功能定位 | 基本的文件和文件夹权限管理工具 | 高级的文件和文件夹权限管理工具,支持更多功能 |
| 命令格式 | 简单的命令格式 | 更复杂、更灵活的命令格式 |
| 权限类型支持 | 基本的权限类型,如 r (读取)、w (写入)、f (完全控制) |
更细粒度的权限控制,包括 D (删除)、M (修改)等 |
| 继承权限管理 | 不支持继承权限管理 | 支持继承权限管理,可控制权限的继承关系 |
| 批量操作支持 | 不支持批量修改文件或文件夹权限 | 支持批量修改权限,可操作多个文件或文件夹 |
| 权限备份/恢复 | 不支持权限备份和恢复 | 支持权限的备份与恢复功能 |
| 命令的复杂性 | 简单,适合用于快速修改权限 | 更复杂,适用于需要精细控制权限的情况 |
| 支持的权限映射 | 不支持权限映射 | 支持权限映射,可以将权限从一个文件夹或文件传递到另一个 |
| 用户/组权限管理 | 基本支持用户和组权限设置 | 支持更细粒度的用户和组权限设置,包括详细的访问控制 |
| 命令行选项 | 选项较少,仅支持基本的权限操作 | 提供更多的命令选项,如 /grant、/deny、/setowner等 |
总结:
cacls是一个较老的工具,适用于旧版 Windows 操作系统,提供基本的权限管理功能,功能较为简单。icacls是新版工具,适用于 Windows Vista 及更高版本,提供了更强大的权限控制、更细粒度的管理以及更多的操作选项。
cacls 和 icacls 都是用于管理 Windows 文件和文件夹权限的命令行工具,但它们有一些重要的差异。以下是它们之间的对比:
| 特性 | cacls |
icacls |
|---|---|---|
| 可用版本 | 旧版(Windows XP及更早版本) | 新版(Windows Vista及之后版本) |
| 功能 | 用于查看和修改文件和文件夹的权限 | 用于查看、修改、备份和恢复文件夹和文件的权限 |
| 权限类型 | 只支持简单权限,如 r (读取)、w (写入)、f (完全控制) |
支持更复杂的权限控制,如 D (删除)、M (修改)等 |
| 支持继承权限 | 不支持继承权限的管理 | 支持继承权限设置,可以管理继承关系 |
| 权限备份/恢复 | 不支持权限备份和恢复 | 支持权限的备份和恢复功能 |
| 批量操作支持 | 不支持批量修改权限 | 支持批量修改权限,可以对多个文件/文件夹进行操作 |
| 支持的命令 | cacls <文件/文件夹>、cacls <文件/文件夹> /E /P <用户>:<权限> |
icacls <文件/文件夹>、icacls <文件/文件夹> /grant <用户>:<权限> 等 |
| 修改权限方式 | 只能修改现有权限 | 可以修改现有权限,也可以删除、备份和恢复权限 |
| 权限映射支持 | 不支持权限映射 | 支持权限映射,允许通过使用不同的权限来修改文件夹 |
| 命令复杂度 | 命令较简单,适合基础权限操作 | 命令更复杂,但提供了更多的功能和灵活性 |
| 支持的用户组和用户 | 基本支持用户组和用户权限控制 | 支持更细粒度的用户和组控制,包括允许对用户/组进行详细的权限分配 |
总结:
cacls是一个较旧且简单的工具,适合用于一些基础的权限管理,但不支持更复杂的权限配置与继承设置。icacls是一个功能更强大的工具,适用于较新的 Windows 系统,并且支持复杂的权限管理、权限备份与恢复以及批量操作等功能。
因此,如果您使用的是较新的操作系统,推荐使用 icacls,它提供了更灵活和强大的功能。
ICACLS 命令语法及功能
1. 保存权限到文件
ICACLS 路径 /save 保存文件 [/T] [/C] [/L] [/Q]
-
功能: 将指定路径下文件/文件夹的 DACL(自主访问控制列表)保存到文件中(不包含 SACL、所有者或完整性标签)。
-
参数:
-
/T: 递归处理所有子目录和文件。 -
/C: 忽略错误继续操作。 -
/L: 操作符号链接本身(而非目标)。 -
/Q: 静默模式(不显示成功消息)。
-
2. 从文件恢复权限
ICACLS 目录路径 [/substitute 旧SID 新SID [...]] /restore 保存文件 [/C] [/L] [/Q]
-
功能: 将保存的 DACL 应用到指定目录下的文件。
-
参数:
-
/substitute: 替换 SID(例如旧用户迁移到新用户)。 -
其他参数同上。
-
3. 修改所有者
ICACLS 路径 /setowner 用户 [/T] [/C] [/L] [/Q]
-
功能: 修改指定路径下所有匹配项的所有者(不强制更改所有权,需使用
takeown.exe强制修改)。 -
参数: 同上。
4. 查找包含特定 SID 的 ACL
ICACLS 路径 /findsid SID [/T] [/C] [/L] [/Q]
-
功能: 查找所有包含显式提及指定 SID 的 ACL 的文件/文件夹。
5. 验证 ACL 规范性
ICACLS 路径 /verify [/T] [/C] [/L] [/Q]
-
功能: 检查 ACL 是否符合规范格式或 ACE 条目数量是否一致。
6. 重置为默认继承权限
ICACLS 路径 /reset [/T] [/C] [/L] [/Q]
-
功能: 将所有匹配项的 ACL 替换为默认继承权限。
7. 授予/拒绝/移除权限
ICACLS 路径 [/grant[:r] SID:权限[...]]
[/deny SID:权限 [...]]
[/remove[:g|:d] SID[...]] [/T] [/C] [/L] [/Q]
[/setintegritylevel 级别:策略[...]]
-
功能: 直接修改权限或设置完整性级别。
-
参数:
-
/grant[:r]:-
:r表示替换现有显式权限,否则追加权限。 -
示例:
/grant Administrator:(F)授予管理员完全控制。
-
-
/deny: 显式拒绝指定权限(添加拒绝 ACE 并移除相同权限的允许 ACE)。 -
/remove[:g|:d]:-
:g移除所有允许权限,:d移除所有拒绝权限。
-
-
/setintegritylevel:-
设置完整性级别(
L低、M中、H高),可选继承标记(OI)(CI)。 -
示例:
/setintegritylevel (CI)(OI)L对目录应用低完整性级别。
-
-
8. 继承设置
/inheritance:e|d|r
-
功能: 控制权限继承。
-
e: 启用继承。 -
d: 禁用继承并复制现有 ACE。 -
r: 删除所有继承的 ACE。
-
关键参数说明
-
SID 格式:
-
可使用友好名称(如
Administrators)或数值形式(需以*开头,如*S-1-5-32-544)。
-
-
权限 (
perm) 格式:-
简单权限:
F(完全控制)、M(修改)、RX(读执行)、D(删除)等。 -
详细权限列表: 逗号分隔,如
(DE,WDAC)表示删除和修改 DAC。 -
继承标记: 如
(OI)(对象继承)、(CI)(容器继承)、(NP)(不传播继承)等。
-
-
ACE 排序规则:
显式拒绝 → 显式允许 → 继承拒绝 → 继承允许。
示例
icacls c:\windows\* /save AclFile /T
- 将 c:\windows 及其子目录下所有文件的 ACL 保存到 AclFile。
icacls c:\windows\ /restore AclFile
- 从 AclFile 恢复 c:\windows 及其子目录下文件的 ACL。
icacls file.txt /grant Administrator:(D,WDAC)
- 授予管理员对 file.txt 的删除和修改 DAC 权限。
icacls file.txt /grant *S-1-1-0:(D,WDAC)
- 授予 SID 为 S-1-1-0 的用户删除和修改 DAC 权限。
注意事项
-
管理员权限: 修改系统级路径需以管理员身份运行命令提示符。
-
备份 ACL: 操作前建议使用
/save备份原始权限。 -
符号链接: 使用
/L操作符号链接本身(默认操作目标)。 -
错误处理: 使用
/C忽略错误并继续执行。
通过此命令,可精细控制 Windows 系统的文件和目录权限。

浙公网安备 33010602011771号