7.23 Windows 提权路径地图
「7D Windows 提权」系列 Part 1,免费开放。 很多人学提权,一上来就抱着一堆 CVE 编号背:MS17-010、CVE-2021-1675、CVE-2023-23397……背得滚瓜烂熟,真到靶场上拿到一个 shell,坐在那里发愣,不知道下一步该干嘛。这一篇就是帮你把脑子里那堆散装的 exp 串成一张图:Windows 提权到底有几条路,每条路什么时候走,按什么顺序排查,先看什么后看什么。看完这张地图,后面六天的每一篇你都会知道它在整张图的哪个位置。
一、先把最大的一个误区打破
新手最常见的执念是:"提权 = 找一个没打过补丁的漏洞,把 exp 扔进去执行。"
这个画面不能说错,但它只覆盖了提权世界里很小一块。现实中你在企业内网遇到的 Windows 机器,绝大部分补丁打得不算离谱——管理员再懒,每月 Windows Update 总会点一下。真正让你在靶场和授权测试里"啪"一下从普通用户蹦到 SYSTEM 的,十有八九不是什么惊天大漏洞,而是下面这种看起来特别朴素的事:
- 某个第三方服务的可执行文件放在
C:\Program Files\SomeVendor\下面,结果这个目录的 ACL 被运维图省事设成了"Users 组完全控制"; - 某个服务注册的路径是
C:\Program Files\My App\service.exe,没加引号; - 某个计划任务每天早上 8 点以 SYSTEM 身份跑
C:\scripts\backup.bat,而C:\scripts\目录 Everyone 可写; - 组策略里手贱开了 AlwaysInstallElevated,两个注册表键都写成了 1;
- 一个普通用户的 token 上居然挂着
SeImpersonatePrivilege。
这些事没有一件需要 0day,没有一件涉及内存破坏,没有一件需要你写汇编 shellcode。它们全部是配置错配——运维图省事、厂商默认配置不安全、历史遗留没人管——留给你的缝隙。攻击者做的事情,本质上就是"把这些缝隙接上,让一个本来就以高权限跑的进程,去执行你早就准备好的那段代码"。
把这句话刻进脑子:提权不是"打一个漏洞",而是"找一个配置错误,让高权限进程替你干活"。 理解了这一点,你看到的提权世界就会从"一堆 CVE"变成"一张配置审计清单"。
二、Windows 提权的九大方向全景图
把所有能让你从普通用户爬到 SYSTEM 的路径归拢一下,一共九个大类。先给一张全景图建立直觉:
下面用一张表把这九类各自的"一句话原理"和代表工具列出来,后面六篇我们会一类一类拆开:
| 大类 | 一句话原理 | 代表工具/技术 | 风险/难度 |
|---|---|---|---|
| 内核漏洞 | 内核里某个驱动函数有 bug,用户态程序触发后拿到 ring0 执行权 | CVE-2021-1675(PrintNightmare)、CVE-2023-23397、MS17-010 | 高:容易蓝屏、依赖补丁级别 |
| 服务错配 | 服务以 SYSTEM 跑,但它的 exe 或目录普通用户可写 | accesschk、PowerUp、sc qc | 低:最常见、最稳 |
| 注册表配置 | 服务 ImagePath 可写 / 启动时加载的 DLL 键可写 | reg query、PowerUp | 低:检测快 |
| 计划任务/启动项 | 高权限任务调用的脚本/快捷方式路径可写 | schtasks /query、PowerUp | 低:企业环境常见 |
| 令牌模拟/特权滥用 | 当前 token 带了 SeImpersonate/SeAssignPrimaryToken | JuicyPotato、PrintSpoofer、RoguePotato | 中:依赖特权存在 |
| 凭据抓取 | 从 SAM/LSASS/浏览器/自动登录里直接摸出明文或哈希 | Mimikatz、LaZagne、reg save | 中:常被 AV 拦 |
| AlwaysInstallElevated | 两个注册表键同时为 1,MSI 包以 SYSTEM 安装 | msfvenom、msiexec | 极低:一次命中即 SYSTEM |
| DLL 劫持 | 高权限程序加载一个普通用户可写路径下的 DLL | procmon、PowerUp | 中:需找对加载顺序 |
| UAC 绕过 | 已经是管理员但在中完整性级别,绕过 UAC 提高完整性 | fodhelper、eventvwr | 中:版本相关 |
优先级经验法则:实战中按"成本从低到高、稳定性从高到低"排序,永远先碰 ②③④⑦ 这四类纯配置错配——它们不需要上传 exp、不会蓝屏、跑完立刻拿到 SYSTEM;搞不定再考虑 ⑤⑥ 令牌和凭据;最后实在没招了才去碰 ① 内核漏洞(蓝屏代价太大)。
这里再展开说一下为什么"配置错配比内核漏洞优先"。内核漏洞利用的是软件 bug,这种 bug 的特点是"打一次就完"——你成功拿到 SYSTEM 就完了,但一旦失败(补丁已打、AV 拦截、版本不匹配),你什么都得不到,还暴露了自己。而配置错配利用的是人为失误,这种失误的特点是"它一直在那里,不会因为你试了一次就消失"。你今天没权限改,明天换个角度查权限,可能就发现目录其实可写;你今天没找到可利用的服务,明天再跑一遍 accesschk,可能就发现新加了一个第三方服务。配置错配是个"静态靶标",你可以反复试、慢慢找,不用承担失败的代价。这就是为什么老手把配置错配放在第一位——它不是最快的路,但是最稳的路。
三、拿到 shell 后到底先看什么:提权决策树
很多人卡在"第一步不知道干嘛"。其实拿到一个低权限 shell 后,你应该像一个老中医把脉一样,按固定顺序问自己几个问题。把这个流程写成决策树:
这张树图背后的逻辑特别朴素:先看最便宜的牌,再看最贵的牌。 令牌模拟(PrintSpoofer 这类)只要你 token 上有那个特权,一条命令 5 秒钟 SYSTEM,所以排第一;服务、注册表、计划任务这三类纯配置错配,不用传文件、不会蓝屏,排中间;内核 exp 要传文件、要选对版本、搞不好蓝屏,排最后。
三点五、提权到底在提什么:用户、组、完整性级别
很多人天天说"提权",却说不清自己到底在往哪提。先把这个底层概念讲透,后面所有技术你才知道自己在干什么。
Windows 上"权限"其实分三个独立的维度,别混在一起。第一个维度是用户身份。你现在是 corp\web_svc 还是 corp\admin,决定了你属于哪个本地组。本地管理员组(Administrators)里的账号,默认就能改这台机器的大部分配置。第二个维度是用户特权,就是 whoami /priv 里看到的那一堆 SeXxx 权限。普通用户可能恰好被分配了某个本不该有的特权,比如 SeImpersonatePrivilege——这就是后面 Potato 系列的入场券。第三个维度是完整性级别,这是从 Vista 引入的 UAC 机制,分低、中、高、系统四级。你是管理员账号但在"中完整性"跑,就等于"有管理员的身份但被 UAC 摁住了",这时候要走 UAC 绕过才能升到高完整性。
一张表把这三个维度和常见提权手法对应起来:
| 你当前的状态 | 缺什么 | 该走哪条路 |
|---|---|---|
| 普通域用户,无特殊特权 | 要变成本地管理员 | 服务/注册表/计划任务错配 |
| 本地管理员,但中完整性 | 要升到高完整性 | UAC 绕过 |
| 任意用户,token 带 SeImpersonate | 要直接变 SYSTEM | Potato 系列令牌模拟 |
| 任意用户,补丁老旧 | 要靠内核 bug | 内核 exp |
| 已经是 SYSTEM | 横向移动 | 凭据抓取后跳其他机器 |
理解了这张表,你就明白为什么"提权"不是一个动作,而是一组动作——你得先搞清楚自己现在站在哪个格子里,才能决定往哪个格子跳。很多新手对着一台机器折腾半天,其实他从一开始就站错了格子:比如他已经是本地管理员了,还在埋头找"怎么从普通用户提到管理员"的服务错配,完全不知道自己缺的只是一个 UAC 绕过。
四、信息收集:五条必须张口就来的命令
提权功夫七成在信息收集。下面五条命令是你每天要敲的,先把它们的输出格式和"重点看哪几行"讲清楚。
4.1 whoami /priv —— 看自己有哪些特权
whoami /priv典型输出:
特权信息
特权名 描述 状态
=============================== ============================ ======
SeChangeNotifyPrivilege 绕过遍历检查 已启用
SeImpersonatePrivilege 模拟客户端身份后进行身份验证 已启用
SeBackupPrivilege 备份文件和目录 已启用重点看:有没有 SeImpersonatePrivilege、SeAssignPrimaryTokenPrivilege、SeDebugPrivilege、SeTakeOwnershipPrivilege。这几个里面任何一个亮着"已启用",后面就有大把文章可做——尤其是 SeImpersonatePrivilege,这是 JuicePotato/PrintSpoofer/RoguePotato 系列的入场券。
4.2 systeminfo —— 看 OS 版本和补丁
systeminfo输出很长,重点看头部几行:
OS 名称: Microsoft Windows Server 2019 Datacenter
OS 版本: 17763.1007 N/A 内部版本
系统类型: x64-based PC
Hotfix(s): 3 个热修复程序已安装:
KB4486553
KB4470788
KB4471332重点看:OS 版本(2016/2019/2022/Win10 哪个 build)、Hotfix 列表。把版本号和已装补丁拿去对照 CVE 表,就知道哪些内核 exp 能用、哪些已经被堵。
4.3 sc query 与 sc qc —— 看服务
sc query state= all
sc qc 服务名sc query 列所有服务当前状态;sc qc 服务名 看这个服务的配置,重点是 BINARY_PATH_NAME 这一行——它告诉你服务启动时跑的是哪个 exe、参数是什么、有没有引号、运行账户是谁。
4.4 schtasks /query —— 看计划任务
schtasks /query /fo LIST /v输出巨长,实战里一般用 findstr 过滤关键行:
schtasks /query /fo LIST /v | findstr /i "TaskName Run As User Task To Run"重点找:Run As User 是 SYSTEM 或 BUILTIN\Administrators 的任务,然后看 Task To Run 指向的脚本/exe 路径是否可写。
4.5 reg query —— 看注册表
reg query HKLM\SYSTEM\CurrentControlSet\Services
reg query HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated
reg query HKCU\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated后两条就是检查 AlwaysInstallElevated 开关的,7.25 会细讲。
4.6 自动化工具:winPEAS 和 PowerUp
手敲五条命令当然能干活,但实战里没人这么干。两个自动化脚本会帮你把上面这些检查(加上成百上千个冷门检查)一键跑完:
- winPEAS:单文件 exe,跑一遍输出一大堆彩色报告,标注每个发现的"是否可利用"。优点是不用 PowerShell 执行权限,缺点是体积大、容易被 AV 拦。
- PowerUp(PowerSploit 套件里的模块):纯 PowerShell,
Import-Module .\PowerUp.ps1; Invoke-AllChecks一把梭。优点是隐蔽、无文件落地(可以内存加载),缺点是要能跑 PowerShell。
工具的存在不是让你不学原理——恰恰相反,你得先知道它在检查什么,才能在它报告"发现漏洞"时判断真假。新手一上来就跑 winPEAS,看到一堆黄色警告激动得不行,结果 90% 是误报。所以这个系列的思路是:先把原理和手动命令讲透,工具只是加速器。
两个工具到底怎么选?给你一张对照:
| 维度 | winPEAS | PowerUp |
|---|---|---|
| 形态 | 单文件 exe | PowerShell 脚本 |
| 要不要 PowerShell | 不要 | 要 |
| 体积 | 大(几 MB) | 小(几十 KB) |
| AV 检出率 | 高(特征明显) | 中(可内存加载) |
| 输出 | 彩色报告,分类清晰 | 纯文本,需自己看 |
| 适合场景 | PowerShell 被禁的老系统 | 现代系统,追求隐蔽 |
实战里我的建议是:先用手搓命令跑一遍核心检查,再用工具补漏。手搓命令的好处是你知道每一步在干什么,不会被工具的彩色输出带偏;工具的好处是它会扫到你想不到的冷门点。两者配合,才是完整的信息收集。
4.7 把信息收集结果整理成一页笔记
老手拿到 shell,不会一边跑命令一边干想,而是会在攻击机上开个笔记文件,边跑边记。下面是一个推荐的模板,你实战时照着填:
[目标 10.10.10.25]
身份: corp\web_svc
特权: SeImpersonate 已启用 <-- 亮点
OS: Server 2019 build 17763, 补丁止于 KB4471332
服务: MyCustomBackup (LocalSystem, C:\Program Files\CustomBackup\)
注册表: HKLM/HKCU AIE 均不存在
计划任务: \MyCompany\DailyBackup (SYSTEM, C:\scripts\backup.bat)
启动项: 公共 StartUp 目录 Everyone 可写
结论: 候选路线 ① Potato ② 服务目录可写 ③ 计划任务脚本可写为什么要记成这样?因为提权经常是跨多次 shell 会话的——你这次拿到的 shell 可能过两天就断了,下次再进来如果不重新枚举,根本忘了上次查到哪了。把关键信息记在笔记里,下次进来直接对着笔记继续,不用从头再跑一遍。这个习惯在长时间授权项目里特别值钱。
五、一张表理清"什么情况下走哪条路"
实战中拿到 shell 后,怎么快速决定方向?给你一张速查表:
| 现场观察 | 首选路线 | 对应篇章 |
|---|---|---|
whoami /priv 有 SeImpersonatePrivilege | PrintSpoofer/JuicyPotato 令牌模拟 | 后续专题 |
systeminfo 显示 2016 之前的老系统、补丁常年不更 | 内核 exp(MS17-010/PrintNightmare) | 后续专题 |
sc qc 看到未加引号的路径、或服务目录 ACL 宽松 | 服务错配 | 7.24 |
reg query 发现 AIE 两个键都是 1 | AlwaysInstallElevated | 7.25 |
| 服务 ImagePath 注册表键普通用户可写 | 注册表 ImagePath 篡改 | 7.25 |
schtasks /query 看到 SYSTEM 跑的 .bat/.exe 在可写目录 | 计划任务劫持 | 7.26 |
| 启动目录里有指向可写路径的 .lnk | 启动项劫持 | 7.26 |
| 已经是本地管理员但还在中完整性级别 | UAC 绕过 | 后续专题 |
| 上面全没中 | 凭据抓取 + DLL 劫持 + 回头打内核 | 后续专题 |
六、新手最容易踩的四个坑
讲了这么多流程,必须把新手在提权阶段最容易栽进去的四个坑单独拎出来。这四个坑不解决,你背再多命令也是白搭。
6.1 坑一:上来就甩内核 exp,蓝屏了还不知道为什么
这是最常见的新手病。拿到 shell 第一件事不是 whoami /priv,而是翻 CVE 表,挑一个"最新、最炫"的 exp 扔上去,结果目标机器蓝屏重启,你的 foothold 直接丢了,留下一脸懵的自己。
为什么会这样?因为内核 exp 对版本、补丁、架构(x86/x64)、甚至当前进程状态都极其敏感。CVE-2021-1675 在 Server 2019 某个 build 上能用,下一个 build 可能就蓝屏;同一份 exp 在干净系统上跑得好好的,在装了杀毒软件的机器上就把内核搞挂。
正确姿势:把内核 exp 放在决策树的最后一格。前面所有配置错配路线都走光了,再考虑它。而且动手之前,先在自己的测试环境(虚拟机)里把同一个 OS 版本跑一遍,确认不蓝屏,再往目标上扔。
6.2 坑二:把"当前用户能写"当成"服务以当前用户跑"
第二个高频误解。新手看到 icacls 输出里 BUILTIN\Users:(F),就激动地以为"我能写这个目录,所以服务是我跑的"。错。谁能写文件和服务以谁的身份跑是两件完全独立的事。
服务永远以它自己配置的 SERVICE_START_NAME(通常是 LocalSystem)身份启动,跟"这个文件目录谁能写"一点关系都没有。你能写文件,只意味着你可以把文件内容换掉;服务下次启动时,会用它自己的 SYSTEM 身份去执行你换掉的那个文件。两个条件缺一不可:文件可写 + 服务高权限。光满足一个没用。
这个误区还经常反过来坑人:新手看到服务路径在 C:\Windows\System32\ 下,就觉得"系统目录我不能写,放弃吧"——对,但理由不是"系统服务都不能碰",而是"这个具体目录 ACL 我不可写"。换一个第三方服务,路径在 C:\Program Files\Vendor\ 下,ACL 可能就松了。
6.3 坑三:winPEAS 报什么就信什么
第三个坑跟工具滥用有关。新手拿到 shell,先传 winPEAS,跑一遍,看到屏幕上红黄绿一大片,眼睛都花了,把每个黄色警告都当成"可利用点"去试。结果十个里九个是误报:
- 它报"AlwaysInstallElevated 可能启用",你一查其实是 0;
- 它报"未引用路径",你查发现路径其实加了引号;
- 它报"服务可写",你
icacls一看目录权限其实是只读。
工具是加速器,不是大脑。它输出的每一条结论,你都得用手搓命令复核一遍——这也是为什么这一篇坚持让你先把 sc qc、icacls、reg query 这几条手搓命令练熟。你手熟了,工具报出来的东西你一眼就能判断真假;手不熟,工具就是在带你绕路。
6.4 坑四:忽略"我当前到底有没有权限"
第四个坑是最隐蔽的:很多提权动作不需要"你有权限",只需要"那个高权限进程有权限"。新手经常卡在"我不能 sc stop 这个服务啊"上,然后放弃。
实际上你要分清楚三件事:
- 谁能改文件/注册表:通常是你(因为 ACL 松了);
- 谁能启动服务/触发任务:通常是系统自己(服务自启、任务定时跑);
- 谁以什么身份执行最终的代码:永远是那个高权限进程。
你要做的只是第一步——把文件/注册表改对。后面两步是系统自己干的,不需要你有权限。想通这一点,你就不会再纠结"我不能 sc start 怎么办"——等它自己触发就行了。当然,如果你恰好有 sc start 权限,那是锦上添花,不是前提。
6.5 坑五:把"能读"当成"能利用"
第五个坑经常出现在信息收集阶段。新手跑 reg query 或 icacls,发现自己能读到某个敏感路径,就激动地以为"这里面有可利用的东西"。错。能读和能写是两回事——你能读 C:\Windows\System32\config\SAM,不代表你能复制它出来;你能读到服务的 ImagePath,不代表你能改它。提权利用的永远是"写"权限,不是"读"权限。读权限只能帮你收集情报,真正让高权限进程替你干活的,永远是你能往那个位置写东西。
判断一个错配能不能利用,永远问自己一句:"我能往这个位置写东西吗?" 答案是能,再往下走;答案是不能,立刻换下一个目标。不要在"我能读但不能写"的地方浪费时间。
七、一个真实的排查节奏长什么样
最后把这些揉在一起,看一次真实的排查流程是什么感觉。假设你通过 Web 漏洞拿到了一个 nt authority\iusr 或普通域用户的 shell,你会这样工作:
C:\www> whoami
corp\web_svc
C:\www> whoami /priv
SeImpersonatePrivilege 已启用 <-- 亮了!先记下来,后面可能直接 PrintSpoofer
C:\www> systeminfo | findstr /B /C:"OS 名称" /C:"OS 版本"
OS 名称: Microsoft Windows Server 2019 Datacenter
OS 版本: 10.0.17763 N/A 内部版本
C:\www> sc query state= all | findstr "SERVICE_NAME"
... 一堆服务 ...
C:\www> sc qc W3SVC
BINARY_PATH_NAME : c:\windows\system32\inetsrv\w3wp.exe <-- 系统服务,别碰
C:\www> accesschk.exe /accepteula -uwcqv Users *
[1] MyCustomBackup
TYPE : 10 OWN PROCESS
START_TYPE : AUTO_START
BINARY_PATH: C:\Program Files\CustomBackup\backup.exe <-- 可疑!下一步看权限
START_NAME : LocalSystem注意这个节奏:每一步都在给下一步提供线索。你看到 SeImpersonatePrivilege 亮了,心里就有底"最坏情况还能走 Potato 路线";你看到 Server 2019 build 17763,就知道老的 MS17-010 类 exp 大概率没戏;你枚举服务时眼睛只盯着"BINARY_PATH_NAME 在 Program Files 之外、或者目录名带空格"的那些,因为它们最容易有问题;最后用 accesschk 一查,发现 MyCustomBackup 这个第三方服务的目录 Users 可写——恭喜,这就是下一篇 7.24 的故事。
八、为什么提权要按这个顺序,而不是乱撞
最后讲一个心态问题。新手拿到 shell 后的典型状态是:先试 PrintNightmare,蓝屏了;换一个 CVE-2021-1675,被 AV 拦了;再试一个 MS17-010,提示系统已打补丁;半小时过去什么都没干成,开始怀疑人生。
老手的状态完全不同:他像翻牌一样,按优先级一张一张翻。第一张牌是 whoami /priv,5 秒钟翻完;第二张牌是 systeminfo,10 秒钟看完;第三张牌是服务枚举,2 分钟跑完 accesschk;第四张牌是注册表,10 秒钟 reg query;第五张牌是计划任务,1 分钟跑完。每张牌翻完都有明确结论——"中了,收工"或"没中,下一张"。整个过程 10 分钟内完成,如果五张牌都没中,才会去考虑传内核 exp 这种"重武器"。
这就是为什么这一篇叫"路径地图"而不是"exp 合集"。你脑子里必须有一张地图,知道每条路长什么样、什么路况下走哪条;而不是口袋里揣着一堆手榴弹,见门就扔。 后面六天我们把这张图上的每一条路都亲自走一遍。学完之后你会发现,所谓"提权难",其实难在信息收集阶段——你不知道该看什么、不知道哪些输出是关键、不知道看到什么该兴奋、看到什么该忽略。这张地图解决的就是这个问题:它告诉你"看完哪些东西就能下结论"。
最后再强调一遍心态:提权不是考试,不是"必须拿到 SYSTEM 才算赢"。在很多授权场景里,你拿到 local_admin 就已经完成任务——剩下的横向移动、拿域控,是另一个阶段的事。不要在一台机器上死磕两小时非要 SYSTEM,看清楚形势,能 local_admin 就 local_admin,留着时间去打更有价值的目标。懂得什么时候收手,和懂得怎么提权一样重要。 另外提醒一句:提权做完之后,记得把你动过的东西改回去——替换的 exe 换回原名、追加的脚本行删掉、改过的注册表值复原。不然第二天运维发现业务异常,直接登上来排查,你的 foothold 当场暴露。提权成功但留下一堆痕迹,等于没提权。这一点后面每一篇都会反复强调,因为它是新手最容易忽略的职业素养。
九、本篇小结
- Windows 提权的本质是"找配置错配,让高权限进程替你干活",不是上来就找 exp。
- 九大方向:内核漏洞、服务错配、注册表、计划任务/启动项、令牌模拟、凭据抓取、AlwaysInstallElevated、DLL 劫持、UAC 绕过。
- 决策顺序:特权 → OS 版本 → 服务 → 注册表 → 计划任务 → 凭据/DLL/UAC → 内核 exp。
- 五条手搓命令:
whoami /priv、systeminfo、sc qc、schtasks /query、reg query;自动化用 winPEAS/PowerUp,但必须懂原理。 - 心态:按优先级翻牌,不要上来就甩内核 exp。
这张地图你不需要背下来,需要的是建立"看到现场 → 想到该走哪条路"的直觉。实战中拿到 shell,先花十分钟把信息收集跑完,你会发现可用的路永远不止一条——区别只是哪条最快、最稳、最不吵。后面六天我们把每条路都走一遍,走完你回头再看这张图,会觉得它特别朴素:无非就是"找一个高权限进程,让它替你跑东西"。记住这个本质,所有具体技术都是它的不同变体。下一篇我们就拿这个模型去拆第一条最常见的路,看看服务的可执行路径到底哪里会出问题。
授权警示:本系列所有内容仅用于已获书面授权的渗透测试与靶场学习,禁止对未授权系统进行任何提权操作。
下一篇 7.24 服务错配/未引用路径,我们正式打开地图上的第一条实战路线:服务的可执行路径到底哪里会出问题,未引用路径的解析歧义又是怎么被利用的。