
在一台 Windows 机器上敲下whoami /priv看到满屏的 SeXxx 名字多数人的第一反应是看不懂第二反应是反正后面写着 Enabled应该都是好东西。我一开始也是这么想的直到某次给一台对外提供服务的机器做权限盘点才发现一张 SeImpersonatePrivilege 的牌配合一个被忽略的后台服务就足以让一个普通的 IIS 应用程序池账号走到 SYSTEM。Windows 的权限体系里真正危险的东西从来不是Administrators 组这种一眼看得见的东西而是那些藏在访问令牌里、默认静默启用、名字看上去人畜无害的用户权限。这篇内容围绕 Windows 上最常被拿出来讨论的九大高危权限展开从权限模型的基础概念、逐个权限的原理拆解到枚举判定、典型利用链路的思路、日常运维里的权限故障排查最后到防御加固。不管你是做运维、写代码、还是做内部安全评估的看完之后至少能做到三件事拿到一台机器能自己判断手里的权限牌面、遇到你没有权限这类报错能快速定位到是哪一层出的问题、知道在自己的环境里应该优先关掉哪些口子。文中涉及的利用链路只讲原理和判定思路具体落地请务必在自己的授权环境里进行。1. 先把 Windows 权限模型的两套体系分清楚在讨论九大权限之前必须先把一个最容易混淆的概念掰开Windows 里权限这个词对应着两套完全不同的体系一套叫访问权限Access Rights一套叫用户权限User Rights / Privileges。绝大多数我需要权限的报错来自前者而真正能让攻击者一步登天的来自后者。搞混了这两套后面的分析全部会跑偏。1.1 访问权限与用户权限一个管门一个管钥匙访问权限针对的是对象——文件、文件夹、注册表项、服务、共享、打印机、命名管道都算对象。它的表现形式就是你右键属性里那一排勾选框读取、写入、修改、完全控制。这套东西由对象的**DACLDiscretionary Access Control List自主访问控制列表**定义谁能不能碰这个对象看的是你的 SID 有没有出现在这张表里、以及出现在哪个条目上。它回答的问题是这个门我能不能进。用户权限针对的是进程和账户——它不绑定任何具体对象而是绑定在账户登录后拿到的访问令牌上。比如 SeBackupPrivilege 不针对某个文件它的含义是持有这个权限的进程在打开文件时可以声明自己是来做备份的于是可以绕过 DACL 检查。它回答的问题是我手里有没有这把万能钥匙。我见过太多人在这上面栽跟头一个业务账号读不了某个共享目录运维第一反应是去secpol.msc里加用户权限改了半天没用——因为问题根本在目录的 NTFS 权限上跟用户权限半分钱关系没有。反过来一台机器上某个服务账号莫名其妙能读到整个磁盘你去翻 NTFS 权限翻不出问题真正的原因是它持有 SeBackupPrivilege。顺手把 Windows 和 Linux 的权限模型做个对照很多从 Linux 转过来的人会更容易理解概念WindowsLinux身份标识SID安全标识符UID / GID权限组全局组、本地组、通用组支持嵌套用户组支持附加组对象权限DACL 中的 ACE 条目粒度极细rwx 三类位 ACL 扩展特权用户权限Privilege令牌持有Capability能力进程持有最高权限SYSTEM / TrustedInstallerroot提权路径服务、令牌、驱动、计划任务SUID、sudo 配置、内核漏洞可以看到 Linux 的 root 权限是全有或全无的粗粒度模型而 Windows 把最高权限拆成了一堆细颗粒的能力SYSTEM 拥有几乎全部用户权限某些系统组件比如 Windows 模块安装程序还持有额外的特殊权限。这种设计让 Windows 更灵活但也意味着谁是管理员这件事在 Windows 上远没有谁是 root那么清晰。1.2 令牌、SID、ACL一条链上的三个环节理解九大权限只需要把三个概念串起来登录 → 令牌 → 访问检查。你输入账号密码登录系统验证通过后LSA本地安全机构会为你构造一个访问令牌Access Token。这个令牌里装着你的 SID、你所属所有组的 SID 列表、你的完整性级别以及一张特权列表——就是whoami /priv打印出来的那部分。这张特权列表不是凭空的它来自本地安全策略里用户权限分配的配置或者来自域控下发的组策略。之后你去访问任何一个对象内核的安全引用监视器会把你的令牌和对象的 DACL 做一次匹配先看你的令牌里有没有完全控制这类权限对应的 SID 条目没有就拒绝如果有 SeBackupPrivilege 并且你在打开对象时主动声明了备份意图就跳过 DACL 匹配。整个过程就是访问检查Access Check。这里有个关键细节特权列表里的每一项都有一个状态字段取值是 Enabled、Disabled、Removed。Disabled 不等于没有它只是没激活进程可以在运行时调用AdjustTokenPrivileges把它打开。这就是为什么很多利用链需要先把权限启用再动手也是为什么很多防护产品会盯着AdjustTokenPrivileges这个 API 调用。再往下还有一层就是完整性级别Integrity Level分为 Low、Medium、High、System 四档。它管的是写入方向低完整性进程不能往高完整性对象里写。浏览器、下载目录跑在 Low 或 Medium系统关键进程跑在 System。这个机制是后来加的主要为了限制沙箱逃逸但它也给日常操作制造了大量我是管理员却写不进去的困惑。1.3 完整性级别与 UAC为什么管理员也常常没权限UAC 的本质是令牌分裂。一个属于 Administrators 组的用户登录后系统会给他两个令牌一个是完整的管理员令牌High 完整性一个是过滤后的标准用户令牌Medium 完整性。默认所有程序用的是后者。所以你虽然是管理员但打开记事本去改C:\Windows\System32\drivers\etc\hosts照样提示需要权限——因为当前进程的令牌里Administrators 组的 SID 是被标记为仅用于拒绝的。只有当你点了以管理员身份运行、或者在同意提示上点了是系统才会用完整令牌重新创建进程。理解这一点之后我明明是管理员为什么没权限这类问题基本能自查了先看当前进程是不是提权状态可以用whoami /groups里的强制标签和 Administrators 组的属性来判断。还有一类特殊的登录会话值得提一句服务账号。LocalSystem、LocalService、NetworkService 这三个内置账号以及各种以虚拟账号形式运行的服务它们的令牌和交互式登录的令牌差别很大。LocalSystem 的令牌里几乎带有所有高危特权NetworkService 和 LocalService 则持有 SeImpersonatePrivilege。这正是第 4 章要展开的核心——服务账号为什么是提权链路上最香的目标。1.4 从系统权限到数据权限行级权限与 API 密钥的同类逻辑把视野拉远一点权限问题不只是操作系统层面的。数据库里的行级权限Row-Level Security本质上是同一套思路不是让用户能不能进这张表而是让他只能看到属于自己的那几行。SQL Server 的 Security Policy、PostgreSQL 的 Row Security Policy实现方式都是给查询自动附加一个谓词条件跟 Windows 在访问检查时给令牌和 DACL 做匹配思路完全一致——都是在数据/对象和主体之间插一层判定把判定结果从是/否细化到哪些。同理现在大量系统要调用 AI 接口API 密钥的权限设计也遵循最小权限原则给推理服务的密钥只应该有调用推理接口的权限不该带上模型管理、账单查询、密钥轮换这些能力。我见过不止一个团队把所有密钥都配成主密钥然后这个密钥被打包进了前端代码或者写进了日志后果就不用多说了。系统层权限、数据层权限、接口层权限三者的设计原则是同一条能少给就少给能限范围就限范围能加过期时间就加过期时间。2. 九大高危权限逐个拆解它们到底能干什么所谓九大权限是安全圈里对 Windows 特权列表中风险最高的九个用户权限的习惯性归纳。它们分别是SeImpersonatePrivilege、SeAssignPrimaryTokenPrivilege、SeTcbPrivilege、SeDebugPrivilege、SeBackupPrivilege、SeRestorePrivilege、SeTakeOwnershipPrivilege、SeLoadDriverPrivilege、SeCreateTokenPrivilege。前四个和令牌、进程打交道中间四个和文件、对象、驱动打交道最后一个最神秘基本只出现在 SYSTEM 的令牌里。先上一张总览表后面逐个展开权限名中文显示名典型持有者风险等级核心能力SeImpersonatePrivilege模拟客户端之后服务账号、管理员极高模拟其他令牌身份执行SeAssignPrimaryTokenPrivilege替换进程级令牌服务账号、管理员极高替换进程主令牌SeTcbPrivilege作为操作系统的一部分SYSTEM极高绕过大量安全检查SeDebugPrivilege调试程序管理员提权后启用极高打开任意进程并读写内存SeBackupPrivilege备份文件和目录备份操作员、管理员高绕过 ACL 读任意文件SeRestorePrivilege还原文件和目录备份操作员、管理员高绕过 ACL 写任意文件SeTakeOwnershipPrivilege取得文件或其他对象的所有权管理员高抢占任意对象所有权SeLoadDriverPrivilege加载和卸载设备驱动程序管理员高加载内核驱动SeCreateTokenPrivilege创建令牌对象SYSTEM极高构造任意内容的主令牌2.1 SeImpersonatePrivilege 与 SeAssignPrimaryTokenPrivilege服务账号的顺手牵羊这两个权限放在一起讲因为它们在利用链路上几乎总是成对出现。SeImpersonatePrivilege 的含义是当某个客户端连接到我的服务并完成认证之后我可以拿到代表这个客户端的令牌并以此身份去访问其他资源。这个权限本来是设计给服务用的——比如一个以 NetworkService 运行的 Web 服务需要以访问者的身份去读他们各自的主目录就得用模拟。问题出在谁来认证这件事上。如果攻击者能诱导机器上一个高权限主体比如 SYSTEM主动向攻击者控制的服务发起认证攻击者就能拿到一个 SYSTEM 的令牌然后用 SeImpersonatePrivilege 把它挂到自己的线程上摇身一变成为 SYSTEM。这就是所谓土豆系列Potato工具族的核心思路从最早的 Rotten Potato 到后来的 Juicy Potato、PrintSpoofer、GodPotato改进的都是如何诱导 SYSTEM 认证这一段令牌模拟那段逻辑基本没变。SeAssignPrimaryTokenPrivilege 则更进一步它允许进程在创建新进程时直接指定用哪个令牌作为主令牌而不是只能靠模拟。两者配合就能实现以另一个身份完整地创建并运行一个进程而不只是临时借用身份。这也是为什么很多自动化提权检测脚本会把这两个权限同时出现在一个账号上视为高危信号。注意任何以服务身份运行的应用IIS 应用程序池、SQL Server 服务账号、计划任务账号默认大概率带这两个权限这不是配置错误而是运行需要。真正的风险点是这个服务能不能被低权限用户触发向外的认证以及这个账号除了这俩权限之外还额外带了什么。防线要设在触发条件上而不是简单地删权限——删了服务直接跑不起来。2.2 SeDebugPrivilege 与 SeTcbPrivilege最高权限的两把钥匙SeDebugPrivilege 是我个人认为最值得单独拿出来讲的一个。它的官方描述很温和——调试程序看起来像是给程序员用的。但实际能力是持有该权限的进程可以打开任意其他进程的句柄并请求完全访问权限包括读取和写入对方的内存。DACL 检查在它面前形同虚设。这意味着什么你可以打开一个高权限进程的内存把其中的令牌对象复制出来可以在目标进程里写入一段代码让目标进程替自己加载模块也可以把内存 dump 下来做离线分析。微软自家的调试工具、性能分析工具都依赖它所以管理员提权后默认是持有这个权限的——只不过在过滤令牌里它是 Disabled 状态需要主动启用。SeTcbPrivilege 的名字是作为操作系统的一部分光听名字就知道分量。它的实际含义是绕过绝大部分内核级安全检查。持有了它很多需要可信前提才允许的操作就对你开放了比如构造登录会话、操作安全审计相关的接口。它是 SYSTEM 的标配普通管理员账户默认拿不到一旦你在某个非 SYSTEM 账号上看到它基本可以判定这台机器的权限分配出了严重问题。这两个权限的共同点是它们不制造漏洞它们只是让已有的漏洞变得毫无阻碍。一台装了 EDR 的机器即使攻击者拿到了 SeDebugPrivilege打开受保护进程时依然会被拦截这就是 PPLProtected Process Light轻量级受保护进程机制存在的意义——它对内核里最敏感的几个进程做了额外保护连持有 SeDebugPrivilege 的进程也不放行。2.3 SeBackupPrivilege 与 SeRestorePrivilege绕过 ACL 的搬运工这两个权限的设计初衷非常正当备份软件需要把整个磁盘的文件都读出来包括那些所有者不是备份账号、DACL 里也没给备份账号任何权限的文件还原软件又需要把这些文件写回原位置覆盖掉现有文件。所以必须有机制让备份这个身份绕过 DACL。这个机制就是打开文件时带上FILE_FLAG_BACKUP_SEMANTICS标志内核检测到调用者持有 SeBackupPrivilege 或 SeRestorePrivilege就跳过访问检查。听起来很合理问题在于它是全盘的不是针对某个目录的。一个持有 SeBackupPrivilege 的账号可以读这台机器上任何一个它想读的文件包括 SAM、SYSTEM、SECURITY 这三个注册表配置单元文件——里面装着本地账户的密码哈希、LSA 机密、缓存凭据。也可以读C:\Windows\NTDS\ntds.dit域控上的账户数据库通常需要配合卷影副本。有一个非常合法的用法可以直观感受这个权限的威力robocopy /b。这个/b参数就是备份模式会启用 SeBackupPrivilege 来绕过权限。你可以做个小实验在一台机器上用普通账号跑robocopy /b它会提示需要备份权限换成带这个权限的账号再跑它会安静地把所有文件复制出来。SeRestorePrivilege 更值得警惕因为它能写。理论上可以覆盖系统目录下的任意文件包括可执行文件、DLL、配置文件。实际能不能成功还要看文件是不是被系统占用、完整性级别是否匹配但在很多场景下往System32里替换一个会被高权限进程加载的 DLL路径就通了。2.4 SeTakeOwnershipPrivilege 与 SeLoadDriverPrivilegeSeTakeOwnershipPrivilege 的能力一句话能说清把任意安全对象的所有者改成你自己。所有者这个身份在 Windows 里很特殊——即使 DACL 里完全没有你的条目只要你是所有者你就有权修改 DACL。所以完整链路是两步先抢所有权再改 DACL 给自己完全控制。管理员默认持有这个权限但同样需要提权后才能用。日常使用的典型场景就是第 5 章要讲的删除文件提示需要权限。这里先记住一个命令takeown它就是微软提供的、利用这个权限的官方工具。SeLoadDriverPrivilege 允许进程调用NtLoadDriver加载内核驱动。内核驱动运行在 Ring 0能力没有上限。利用它需要两个前提一是能往HKLM\SYSTEM\CurrentControlSet\Services下写一个服务项二是要加载的驱动本身能通过签名验证。所以现代 Windows 上这条链路通常得配合一个已知存在漏洞但带合法签名的驱动来用这类驱动在安全圈里被反复公开跟进也是驱动黑名单机制要解决的问题。从防御角度这两个权限的关键不在有没有而在于能不能被非预期的主体触发。加载驱动这件事会在系统日志里留下明显的记录服务安装会触发 4697 和 7045这两条日志是必采项后面第 6 章细说。2.5 SeCreateTokenPrivilege最神秘的那一个这个权限允许进程调用NtCreateToken直接构造一个主令牌并且可以指定这个令牌里包含哪些 SID 和哪些特权。理论上你可以造一个看起来属于 Domain Admin、带全部特权的令牌出来。它只授予 SYSTEM普通管理员账号默认没有。说它神秘是因为在实际环境中几乎看不到它出现在非 SYSTEM 的令牌里所以一旦出现通常意味着权限分配被严重破坏或者有人手工改过本地安全策略。我的建议很简单把任何非 SYSTEM 账号持有 SeCreateTokenPrivilege列为一条高优先级告警规则。另外几个不在九大名单里但同样值得关注的权限顺便列一下方便排查时对照SeManageVolumePrivilege允许直接对卷做底层操作可以读写原始扇区、SeRelabelPrivilege改对象的完整性标签用来绕过完整性级别限制、SeCreateSymbolicLinkPrivilege创建符号链接配合特定的文件操作可以做出欺骗效果、SeEnableDelegationPrivilege开启委派域环境里风险很高。它们出现频率相对低但原理和前九个是同一类。3. 枚举与判定先看清自己手里有什么牌讲完原理接下来是动手部分。权限评估的第一步永远是枚举——不打无准备之仗先把自己手上的牌摊开看清楚。这一章的所有命令都是系统自带的只读命令不会对机器做任何修改可以在任何授权范围内的机器上放心执行。3.1 whoami /priv、/groups、/all 的正确读法最基础的一条命令是whoami /privwhoami /priv输出三列Privilege Name权限名、Description描述、State状态。重点看两处一是哪些权限名出现在列表里尤其是前面列的九个二是 State 是不是 Enabled。前面说过 Disabled 不代表没有可以用whoami /priv配合提权后的进程再看一次——很多时候同一个账号在普通进程和提权进程里State 是不一样的。whoami /groups用来确认自己的组成员身份重点看 Administrators 组那一行的属性。如果显示组用于拒绝说明当前是过滤令牌你并不是真的以管理员身份在跑如果显示已启用组才是真的提权状态。同时这一行还会显示强制标签Mandatory Label可以直接看出当前完整性级别。whoami /all是把前两者加上 SID 列表一起打印信息最全适合在做完整盘点时一次性收集。在实际评估中我更关注的信号顺序是这样的先看当前完整性级别和是否提权再看有没有那九个权限再看权限的 State最后看账号组成员身份里有没有备份操作员远程管理用户这类特殊组。这个顺序能把无效信息快速筛掉。3.2 用 PowerShell 做脚本化盘点单台机器手工看没问题几十台机器就得脚本化。下面这段 PowerShell 用来把关键信息一次性收集出来可以直接在授权范围内批量跑# 收集当前令牌的关键信息输出为一个对象 $id [System.Security.Principal.WindowsIdentity]::GetCurrent() $result [PSCustomObject]{ User $id.Name IsElevated ([System.Security.Principal.WindowsPrincipal]::new($id)).IsInRole( [System.Security.Principal.WindowsBuiltInRole]::Administrator) Integrity $id.Groups | Where-Object { $_.Value -like S-1-16-* } | ForEach-Object { $_.Value } Groups ($id.Groups | ForEach-Object { (New-Object System.Security.Principal.SecurityIdentifier($_.Value)).Translate( [System.Security.Principal.NTAccount]).Value }) -join ; Privileges (whoami /priv | Out-String) } $result这段脚本的意图是把是不是提权、什么完整性级别、属于哪些组三件事一次性拿全IsElevated那一行尤其有用——很多人以为自己是管理员结果在一个过滤令牌里跑脚本后面所有操作都白费。要继续深挖可以遍历本机所有服务的服务账号把每个服务使用的身份列出来Get-CimInstance Win32_Service | Select-Object Name, StartName, State, PathName | Where-Object { $_.StartName -notlike NT AUTHORITY\Local* } | Sort-Object StartName这条命令的价值在于你能一眼看出哪些服务用的是普通域账号哪些用的是 SYSTEM哪些用了明文密码写在服务配置里。配合每个账号的权限就能画出一张谁在什么条件下能做什么的图。3.3 权限可用性的三个前置条件手里有权限不等于能用这是很多新手最容易忽略的一点。判定一个权限能不能落地要过三道关。第一关是令牌状态。权限在列表里但 State 是 Disabled需要在当前进程里主动启用。启用这个动作本身需要进程有调整令牌的权限普通进程可以调整自己令牌里的特权只要该特权在列表里这一点经常被误解为Disabled 就等于没有。第二关是上下文。SeImpersonatePrivilege 要在有客户端来认证的场景下才有价值SeBackupPrivilege 要在打开文件时主动带上备份标志才生效SeLoadDriverPrivilege 需要在注册表里先有对应的服务项。脱离了场景谈权限是没有意义的。第三关是有没有被更强的保护挡住。lsass 被 PPL 保护、驱动加载有签名强制、关键目录有完整性级别限制、EDR 对特定 API 做了 hook。这些是权限在手也做不了事的典型情形。做判定时把这三关串起来看比单纯背权限名靠谱得多。4. 从权限到落地的典型链路与实操要点这一章讲的是权限怎么变成实际效果的链路。我刻意只讲思路和判定不提供可直接复制执行的攻击代码——原因很简单这些东西在公开资料里已经很多了缺的从来不是工具而是为什么这么做能成功的理解以及在自己的环境里怎么判断这条链路通不通。4.1 SeImpersonate 链路服务账号最容易踩的坑这条链路的三个环节是诱导高权限主体认证、捕获令牌、用令牌身份执行。诱导认证这一段历史上被反复折腾过很多轮。原理上都是找一个能被低权限用户触发、并且会以机器身份或 SYSTEM 身份向外发起认证的组件。打印相关的组件是重灾区因为它天然需要向外做认证而且很多场景下普通用户就能触发。这就是为什么在不需要打印服务的服务器上直接停掉相关服务是一个性价比极高的加固动作。捕获令牌这一段通常是开一个本地监听等目标带着机器账号或 SYSTEM 身份的认证信息连过来。这一步在域环境里尤其危险因为机器账号往往在域里有相当的权限可以从机器账号出发去做后续的横向操作。用令牌身份执行这一段就是 SeImpersonatePrivilege 的用武之地把捕获到的令牌挂到当前线程上或者配合 SeAssignPrimaryTokenPrivilege 直接创建新进程。实操心得判断一个服务账号是否走这条链路的最快方式是先确认它是不是 LocalService / NetworkService / 某个虚拟服务账号然后看这台机器上有没有可以被低权限用户触发对外认证的组件处于启用状态。两个条件同时满足风险就是实打实的。加固时不要动服务账号本身的权限去关掉不需要的组件。4.2 SeBackup / SeRestore 链路绕过 ACL 的读写这条链路清晰得多因为它不依赖任何诱导动作。持有 SeBackupPrivilege 就能读任意文件持有 SeRestorePrivilege 就能写任意文件唯一要解决的是绕开系统对正在使用中的文件的锁定。读的部分标准的做法是用卷影副本Volume Shadow Copy先对卷做一次快照然后从快照里把需要的文件复制出来。这样既不干扰生产也不受文件锁定影响。用vssadmin或者是 PowerShell 的 WMI 接口都能创建快照。目标文件通常有这么几类本地账户数据库相关的注册表配置单元、IIS 配置、应用配置文件里写的连接字符串、以及各类证书文件。写的部分风险点在于替换会被高权限进程加载的文件。这需要精确判断哪些文件会被加载、加载时机是什么、有没有签名校验。在现代 Windows 上系统目录下的核心文件基本都有签名保护但如果目标是一个没有签名检查的自定义应用目录风险就大了。所以对业务方来说一个实用的建议是应用目录不要给服务账号 SeRestorePrivilege即使是为了自动更新这个理由。自动更新应该走独立的更新服务用临时授权的方式而不是给常驻账号一个可以写任意路径的权限。顺便说一个容易被忽略的正当用法robocopy /b和takeown /f这两个命令在排查权限故障时非常有用它们分别利用了 SeBackupPrivilege 和 SeTakeOwnershipPrivilege 的机制。运维日常处理删不掉的文件读不了的文件时用它们比手工点属性对话框快得多。4.3 SeDebugPrivilege 链路这条链路的核心只有一句打开目标进程 → 拿到高权限令牌 → 以该身份创建新进程。整个流程需要的 API 就那么几个OpenProcess、OpenProcessToken、DuplicateTokenEx、CreateProcessWithTokenW所以它能被非常稳定地自动化。也正因为稳定这条链路是最需要防守的一条。防的位置有三个一是让高价值进程不被轻易打开。lsass 上的 PPL 保护就是干这个的开启之后即使持有 SeDebugPrivilege 也无法用常规方式打开它。这个开关在注册表里配置需要开启后重启才生效代价是部分第三方安全软件可能受影响需要做兼容性验证。二是限制 SeDebugPrivilege 的持有范围。管理员组默认有这个权限无法取消但可以通过配置让它在某些场景下不自动启用。更实际的做法是把高价值操作放到独立的管理跳板机上日常业务机器上的账号不给管理员。三是监控异常进程访问。这是 EDR 的强项但在没有 EDR 的环境里Windows 自带的审计策略也能给出一些信号——开启对象访问审计之后对敏感进程的句柄请求会被记录下来。日志量会很大所以通常只针对特定进程开。4.4 SeTakeOwnership 链路这条链路最短也最合法。整个流程就是takeown抢所有权icacls改 ACL完事。举例takeown /f C:\目标目录 /r /d y icacls C:\目标目录 /grant 当前用户:(OI)(CI)F /t第一条命令递归地把目录及子项的所有者改成本次执行的身份/d y是自动回答确认替换目录权限的提示。第二条命令递归地给自己授予完全控制权限(OI)(CI)表示继承给文件和子目录。这条链路本身没有技术门槛门槛在判断能不能做。判断依据有三条你对这个路径有没有实际的管理需求、改完之后会不会破坏原来依赖该权限运行的业务、以及能不能改回去。第三条最容易被忽略——很多人抢完所有权就忘了恢复结果某个自动更新程序在半夜跑的时候因为权限变化失败了第二天排查半天。注意对系统目录、WinSxS、Program Files 下的微软组件目录抢所有权是要付代价的。这些目录的所有者通常被刻意设置为特定系统账号改动可能影响组件服务、系统更新和回滚。真要做先记录原始所有者做完用icacls /setowner改回去。4.5 SeLoadDriver 链路这条链路的技术门槛在于签名验证。现代 Windows 上64 位内核驱动必须有合法签名而且微软维护了一份已知存在漏洞的驱动黑名单会随更新下发。所以实际可行性取决于目标机器的补丁状态和驱动的选择——这已经属于比较专门的方向这里只讲防御侧的判定。防御侧就两条一是任何驱动加载和服务创建都要有日志。刚才提到的 4697服务安装和系统日志里的 7045新服务安装是必看项这两条日志会记录服务名、可执行文件路径、启动类型如果出现一个陌生的、路径指向用户可写目录的服务基本就是有问题。二是开启驱动签名强制并保持更新同时关注已知漏洞驱动的黑名单更新。这两条做到这条链路基本走不通。5. 日常运维里的权限故障排查实录聊完利用侧回到更常见的场景——我又没干什么坏事为什么它不让我操作。这一章整理的是这些年被问到最多的几类权限报错以及我的排查顺序。5.1 你需要来自 administrators 的权限才能删除这个提示几乎是 Windows 用户的集体记忆。它的触发原理是删除一个文件需要你在父目录上有删除子项的权限或者在该文件本身有删除权限。很多时候你以为自己有权限是因为文件所在目录你确实有完全控制但那个具体的文件继承被中断了DACL 里没有你的条目只有 SYSTEM 或者某个已经不存在的账号。排查顺序是这样的先看文件属性里安全选项卡上的所有者是谁再点高级看权限条目的继承状态。如果所有者不是你用takeown抢过来如果所有者是你但 DACL 里没你用icacls加一条如果加权限也失败说明所有者都不是你回到第一步。还有一种更隐蔽的情况文件被占用。Windows 持有打开句柄的进程会阻止删除报错信息有时候会伪装成权限问题。这种情况用资源监视器的CPU → 关联的句柄搜索文件名能找到是谁占着处理掉进程再删。5.2 你需要 trustedinstaller 提供的权限这个提示出现在动系统文件的时候。Windows 从 Vista 开始把一部分关键文件和组件目录的所有者从 Administrators 改成了NT SERVICE\TrustedInstaller原因是系统组件需要防止被误改维护工作由 Windows 模块安装程序统一执行。正确的处理方式不是粗暴地抢所有权而是先判断这件事有没有必要做。如果只是要改一个配置文件通常有更合适的入口比如组策略、注册表项、应用自己的配置接口。如果确实必须改文件流程是抢所有权改内容然后把所有权改回去takeown /f C:\Windows\System32\目标文件 icacls C:\Windows\System32\目标文件 /setowner NT SERVICE\TrustedInstaller改回去这一步不能省。我见过有人的机器在改完某个系统文件的所有者之后后续的累积更新一直失败最后只能做就地修复安装——这个成本远高于最开始多花五分钟改回来。5.3 IIS 应用程序池、Docker、文件权限的常见坑这几类问题在现实中出现的频率极高简单列一下排查要点。IIS 应用程序池改应用程序池标识时经常报权限设置失败错误码可能是 0x80005000 这类。这个错误码通常跟身份凭据的格式或权限有关——如果是自定义账号要确认这个账号在服务器上有作为服务登录的权限输入的用户名格式要带域名或机器名前缀。另一个高频问题是应用池账号访问不了网站目录这时候看的是目录的 NTFS 权限而不是用户权限别跑错地方。Docker Desktop on Windows最常见的权限报错是普通用户执行docker ps提示无法连接命名管道。原因是 Docker Desktop 默认只允许管理员和docker-users组成员访问那根命名管道。解决办法官方也给了就是把当前用户加进这个本地组然后重新登录。企业环境里更规范的做法是通过组策略统一加组而不是让每个开发自己用命令行加。文件权限修复目录被人手工改乱之后最省事的恢复方式是用icacls的/reset把子项权限恢复成从父项继承icacls D:\业务数据 /reset /t /c/reset会把显式权限条目替换成从父容器继承来的权限/t递归子目录/c表示遇到错误继续。这条命令非常有效但也非常有破坏性——它会清掉所有手工设的例外条目。执行前一定要先把当前权限导出备份icacls D:\业务数据 /save D:\acl_backup.txt /t备份文件放在一个你不会在恢复过程中顺手改掉的路径下恢复的时候用/restore读它。事件日志里的噪音很多人在系统日志里看到应用程序-特定 权限设置并未向在应用程序容器 不可用 SID (不可用) 中运行的地址授予本地激活权限这类条目来自 DCOM 组件事件来源是 DistributedCOMID 10016。这类日志绝大多数是无害的噪音微软官方也说明过如果某个组件正常工作这条日志可以忽略。不要因为看到SID 不可用就以为权限被破坏了。但如果这类日志突然大量增加值得看一眼对应的组件是不是被改动过。5.4 常见问题速查表把上面这些整理成一张表遇到问题可以先查表定位方向报错或现象最可能的原因首选排查动作你需要来自 Administrators 的权限才能删除对象所有者非本人或父目录缺删除子项权限查属性中的所有者必要时 takeown你需要 TrustedInstaller 提供的权限对象所有者为系统组件账号优先找替代入口必须改则改完恢复所有者用户拒绝访问内存文件目标进程受保护或权限不足确认目标进程的保护状态与完整性级别应用程序池权限设置失败 0x80005000账号格式、凭据或作为服务登录权限缺失检查账号写法与本地策略中的登录权限Docker 权限错误用户不在 docker-users 组加入组并重新登录系统提示配置信息不完整或已损坏设备无法启动驱动注册信息异常设备管理器卸载重装驱动文件无法写入提示只读或拒绝访问完整性级别不匹配或属性为只读检查强制标签与文件属性明明是管理员仍提示需要提权当前进程使用过滤令牌以管理员身份重新运行6. 防御视角把这九把刀收回鞘里前面五章基本都在讲怎么看、怎么用但落到实际工作里绝大多数人的身份是防守方。这一章把加固动作整理成可执行的三块账号改造、日志监控、清单落地。6.1 服务账号与最小权限改造核心思路就一句不要试图删掉服务账号必须的权限而是减少它可以被利用的触发面同时不给它额外的权限。具体动作上先做一次全量盘点把本机上所有服务的服务身份列出来找出那些用了域账号的服务。对每一个问三个问题它真的需要域账号吗能不能改成虚拟服务账号它需要用到哪些网络资源能不能用受约束的委派代替全权访问它的密码存在哪里是不是明文写在脚本或者配置文件里。实操心得我在实际环境里做这项工作时投入产出比最高的一步是把不需要域账号的服务换成虚拟账号。这一步不需要改业务代码只改服务配置能一次性消掉一大批凭据管理问题和横向移动的路径。改完之后观察一周的应用日志基本不会出问题。第二块是给应用账号分级。不要用同一个账号跑多个不相关的应用因为权限会叠加。每个应用一个账号每个账号只授它自己需要的目录权限用本地组来管理而不是直接给用户授权这样人员变动的时候只需要改组。6.2 日志与监控哪些事件必须采没有日志就没有检测。Windows 自带的安全日志里跟权限相关的关键事件 ID 就那些我把必须采的列成一张表事件 ID来源含义关注点4672安全为新登录分配了特殊权限出现时机与账号是否匹配4673安全使用了特权服务特别关注备份、调试类特权4674安全对特权对象进行了操作对象路径是否敏感4688安全创建了新进程需要开启命令行记录才有价值4697安全安装了服务服务路径是否在用户可写目录7045系统安装了新服务与 4697 对照看1102安全安全日志被清除出现即需要立刻查启用这些审计需要先在本地策略或组策略里配置审核策略。我的建议是先只开审核特权使用和审核进程创建这两项观察一周日志量再决定要不要开更细的对象访问审计——对象访问审计在文件服务器上会产生海量日志没有集中收集和分析能力的话不要轻易全开。6.3 一份可直接抄的加固清单把前面所有章节的结论压缩成一份清单可以直接拿去当检查表用序号加固项验证方式1业务机器不给用户管理员权限核查本地 Administrators 组成员2服务账号使用虚拟账号或专用低权账号遍历服务配置核对身份3不需要打印服务的服务器停用相关组件核查服务运行状态4开启 lsass 的 PPL 保护核查注册表配置并验证应用兼容5备份操作员组严格控制成员核查该组成员列表6应用账号不授予 SeRestorePrivilege核查本地安全策略中的用户权限分配7开启关键审计策略并集中收集核查审核策略配置与日志留存8驱动签名强制保持开启且系统及时更新核查启动配置与补丁状态9定期导出权限基线并做差异比对定期执行导出并与上一版对比导出权限基线这件事值得多说一句。系统自带的secedit可以把本地安全策略整体导成配置文件定期导一份跟上一版做文本对比新增或变更的用户权限分配会非常明显。这比人工翻界面可靠得多也不依赖任何第三方工具secedit /export /cfg D:\baseline\sec_%date:~0,4%%date:~5,2%%date:~8,2%.inf跑一段时间之后你会发现真正有价值的不是某一时刻的状态而是变化。任何一次权限变更背后都应该有一个对应的工单或者变更记录如果对不上那就是需要查的信号。最后说个我自己的体会。这几年做权限相关的评估遇到的最复杂的问题往往不是技术问题而是没人说得清某个权限为什么被授出去。一个账号带着一堆高危权限跑了好几年问遍所有人得到的答复都是一直这样不能动动了会出问题。这种情况下比较务实的做法是先在测试环境复刻这个账号的配置然后逐条权限去掉看哪一条去掉之后业务会挂——通常你会发现九条里有七八条其实是历史遗留删掉之后什么都没发生。真正需要保留的往往只有一两条而那一两条才是值得花精力去做监控和隔离的重点。剩下的就是安静地清掉然后在下一次盘点的时候把这份记录当成基线的一部分。