2、Windows权限模型:用户账户控制(UAC)、访问令牌、安全标识符(SID)、权限与特权
好,咱们今天聊点硬核的。Windows的权限模型,说白了就是操作系统用来判断「你是谁、你能干什么」的一套规则。我做了这么多年渗透测试,见过太多因为不懂这套规则而翻车的案例。你想想看,一个系统再怎么加固,如果权限模型被绕过了,那基本就是裸奔。
这一节,我会把UAC、访问令牌、SID、权限和特权这几个核心概念拆开揉碎了讲。嗯,咱们一个一个来。
2.1 安全标识符(SID)—— 每个实体的身份证
Windows里每个用户、每个组、甚至每台计算机,都有一个唯一的SID。你可以把它理解成身份证号。系统不会用「张三」这个名字来判断权限,而是用SID。因为名字可以改,但SID不会变。
举个例子,管理员账户Administrator的SID是 S-1-5-21-xxxxx-500,末尾的500是固定的。我在项目中遇到过有人把管理员账户改名成「Admin」,以为这样就能防住攻击者。结果呢?攻击者直接枚举SID,发现500结尾的账户,照样提权成功。改名?不存在的。
关键点:权限判断依赖SID,而不是用户名。这是很多管理员容易忽略的。
查看SID的方法很简单,用 whoami /user 或者 wmic useraccount get name,sid。我习惯用PowerShell:
Get-WmiObject Win32_UserAccount | Select-Object Name, SID
常见的SID有这些:
| SID | 含义 |
|---|---|
| S-1-5-18 | SYSTEM(本地系统) |
| S-1-5-19 | NT Authority\LocalService |
| S-1-5-20 | NT Authority\NetworkService |
| S-1-5-21-xxxxx-500 | Administrator |
| S-1-5-21-xxxxx-501 | Guest |
| S-1-5-32-544 | Administrators组 |
小技巧:提权时,如果看到某个进程以S-1-5-18运行,那基本就是SYSTEM权限了。直接拿下。
2.2 访问令牌(Access Token)—— 你的通行证
每次你登录Windows,系统会给你发一个访问令牌。这个令牌里包含了你的SID、所属组的SID、以及你拥有的特权。说白了,它就是你的「权限通行证」。进程在访问资源时,系统会检查这个令牌,而不是每次都去查数据库。
访问令牌分两种:
- 主令牌(Primary Token):分配给进程,代表进程的身份。
- 模拟令牌(Impersonation Token):用于线程临时模拟其他用户。我在做渗透测试时,经常用这个来窃取高权限令牌。
令牌里有个关键字段叫 完整性级别(Integrity Level)。这是Windows Vista之后引入的机制,用来防止低权限进程篡改高权限进程。完整性级别从低到高分别是:
- 不可信(Untrusted)
- 低(Low)—— 比如IE保护模式
- 中(Medium)—— 普通用户
- 高(High)—— 管理员
- 系统(System)—— SYSTEM
为什么会这样?因为即使你是管理员,默认情况下你的令牌完整性级别也是「高」,而不是「系统」。这就意味着你不能直接访问SYSTEM级别的进程。嗯,这里要注意,很多提权漏洞就是利用了这个差异。
避坑指南:我曾经在测试中直接尝试用管理员权限去结束SYSTEM进程,结果被拒绝访问。后来才发现是完整性级别不够。所以,别以为管理员就万能了。
查看当前令牌信息:
whoami /all
这个命令会列出你的SID、组SID、特权、完整性级别。我每次拿到shell后,第一件事就是跑这个命令,看看自己到底有多大权限。
2.3 用户账户控制(UAC)—— 微软的「防呆」设计
UAC,全称User Account Control。很多人觉得它烦人,每次安装软件都要弹窗确认。但从安全角度看,它确实有用。
UAC的核心机制是:即使你是管理员,默认情况下你的令牌也是「过滤后的管理员令牌」。什么意思呢?就是你登录时,系统会给你两个令牌:
- 一个完整的、带管理员特权的令牌
- 一个过滤后的、去掉管理员特权的标准用户令牌
默认情况下,你的桌面进程用的是标准用户令牌。只有当你明确点击「是」确认UAC弹窗时,系统才会用完整的管理员令牌去执行那个程序。
说白了,UAC就是让管理员在「普通用户」和「超级管理员」之间手动切换。我见过很多运维为了省事,直接把UAC关掉。结果呢?恶意软件一进来,直接就是管理员权限,连弹窗都没有。
我的建议:UAC不要关。如果你觉得弹窗烦,可以调整到「仅当程序尝试更改计算机时通知我」,但别完全禁用。
UAC的绕过方式有很多,比如:
- 利用白名单程序(如msconfig、fodhelper)自动提权
- 利用COM接口的AutoElevation属性
- 利用DLL劫持
我记得有一次,我通过修改注册表 HKCU\Software\Classes\ms-settings\shell\open\command,直接绕过了UAC弹窗,拿到了高权限。嗯,这个手法现在依然有效,只是需要特定版本的系统。
2.4 权限(Permissions)与特权(Privileges)—— 能做什么 vs 能改什么
这两个概念容易混淆,我简单区分一下:
- 权限(Permissions):针对具体对象的访问控制。比如「你能读这个文件吗?」、「你能写这个注册表键吗?」。权限由ACL(访问控制列表)管理。
- 特权(Privileges):系统级别的操作能力。比如「你能关闭系统吗?」、「你能调试进程吗?」。特权是全局的,不针对某个文件。
举个例子:你可能有权限读取C盘下的某个文件,但你没有 SeShutdownPrivilege(关机特权),所以你不能关机。反过来,你有关机特权,但文件权限不够,照样读不了。
常见的特权有:
| 特权名称 | 含义 | 提权价值 |
|---|---|---|
| SeDebugPrivilege | 调试进程 | 极高——可以注入任意进程 |
| SeTakeOwnershipPrivilege | 获取对象所有权 | 高——可以接管文件/注册表 |
| SeBackupPrivilege | 备份文件和目录 | 高——可以读取任何文件 |
| SeRestorePrivilege | 还原文件和目录 | 高——可以写入任何位置 |
| SeImpersonatePrivilege | 模拟客户端 | 极高——可以窃取令牌 |
| SeAssignPrimaryTokenPrivilege | 分配主令牌 | 极高——可以创建高权限进程 |
重点:如果你在渗透测试中看到某个服务或进程拥有 SeImpersonatePrivilege 或 SeDebugPrivilege,那基本就是提权的突破口。我曾经用 JuicyPotato 利用 SeImpersonatePrivilege,直接从普通用户提到SYSTEM,整个过程不到30秒。
查看当前用户拥有的特权:
whoami /priv
如果看到 SeImpersonatePrivilege 的状态是「已禁用」,别慌。很多特权默认是禁用的,但你可以通过API启用它。比如用 AdjustTokenPrivileges 函数。嗯,这部分后面讲提权技术时会详细说。
2.5 小结
这一节的内容,说白了就是Windows权限模型的骨架:
- SID 是身份标识,改不了。
- 访问令牌 是通行证,决定了你能进哪个门。
- UAC 是门卫,防止你滥用管理员身份。
- 权限 是具体对象的门禁,特权 是全局的万能钥匙。
我个人习惯在拿到一个Windows系统后,先跑 whoami /all 和 whoami /priv,快速定位自己的位置。然后根据完整性级别和特权列表,决定下一步的提权方向。你想想看,如果连自己手里有什么牌都不清楚,怎么打?
下一节,我们会深入讲如何利用这些模型中的弱点进行提权。嗯,那才是真正有意思的部分。