写这一篇的时候,我正盯着那台 Windows Server 2016 靶机的 systeminfo 输出。标题里标着“⓫⁄₃ ⟦ OSCP ⬖ 研记 ⟧ Windows权限提升 ➱ 获取目标主机的基本信息(下)”,上一篇已经把系统版本、当前用户、域内信息这些静态面摸了一遍,这一篇继续沿着 OSCP 笔记的节奏,把信息收集的下半段讲透:用户权限、网络服务、已装软件、计划任务、敏感文件、防火墙和日志,并且把这些信息分别映射到对应的提权路径上。
如果你正在备考 OSCP,或者平时就是在 Windows 靶机上练手,这篇可以直接当成一份 checklist 用。我会把每个命令为什么要跑、输出里哪个字段值钱、以及我自己踩过的坑都写出来。内容只用于授权靶场和合规的实验室环境,别拿到真实系统上乱来,这是底线。
1. 信息收集为什么是提权的分水岭
1.1 没有信息收集的提权,就是盲人摸象
刚练提权那阵子,我拿到初始 shell 之后是有点兴奋的,心里想的全是“赶紧找个 exp 一把梭”。结果呢?要么内核漏洞版本对不上,要么明明有服务配置错误却因为没翻服务列表而错过,甚至有一次把靶机直接打崩了,只能重置环境重来。后来复盘才发现,问题不在 exploit 不好用,而在信息没收集完就急着动手。
提权本质上是一个“匹配问题”:你手里掌握的弱点,必须和目标机器上可利用的窗口对得上。比如你有个 PrintSpoofer,但当前进程根本没有 SeImpersonatePrivilege,那工具再新也白搭;你有个内核漏洞 exp,但系统已经打了对应补丁,那编译得再顺利也是原地踏步。而信息收集,就是把这些窗口一个一个找出来。
所以我现在把提权前期工作统一看成“目标主机基本信息收集”,它的重要性不亚于漏洞利用本身。OSCP 考试里时间紧、靶机多,谁能更快把一台机器的信息摸清,谁就能更早判断出提权路径,省下大量试错时间。这个道理放到真实项目里更成立。
1.2 我把信息收集拆成了四步框架
练了十几台靶机之后,我给自己定了一个四步框架:系统信息、用户权限、网络服务、应用软件。每拿到一台 Windows 机器的 shell,就按这个顺序把命令滚一遍,输出全存到本地一个 txt 里,再逐个字段分析。
| 收集类别 | 常用命令 | 主要映射的提权方向 |
|---|---|---|
| 系统信息 | systeminfo、set、wmic os | 内核漏洞、架构不匹配、环境变量泄漏 |
| 用户权限 | whoami /priv、whoami /groups、net user | 令牌假冒、备份权限、管理员组成员 |
| 网络服务 | ipconfig /all、netstat -ano | 网段定位、高价值端口、横向入口 |
| 应用软件 | reg query Uninstall、wmic service | 第三方漏洞、服务错误配置、计划任务 |
这套框架最大的好处是“不会漏项”。刚开始我全凭记忆,想到哪查到哪,结果经常查完用户忘了软件,查完网络忘了启动项。后来把四类任务写成一个 checklist,每拿到 shell 就按部就班过一遍,提权成功率明显上来了。上一篇覆盖的是系统信息里偏基础的部分,这一篇重点讲用户权限、网络服务、应用软件,以及最后那类最容易漏掉的“隐藏宝藏”。
2. 系统信息深挖:从 systeminfo 到补丁对比
2.1 systeminfo 的正确打开方式
systeminfo 是 Windows 信息收集里最基础也最啰嗦的命令,输出一大堆,但真正对提权有用的字段就那么几个。我一般拿到 shell 后第一件事就是跑它,然后把输出存下来慢慢看。
C:\Users\webadmin> systeminfo Host Name: FILESRV01 OS Name: Microsoft Windows Server 2016 Standard OS Version: 10.0.14393 N/A Build 14393 System Manufacturer: VMware, Inc. System Type: x64-based PC Hotfix(s): 3 Hotfix(s) Installed. [01]: KB3176497 [02]: KB3176936 [03]: KB4525236OS Version 这一行是核心。10.0.14393 对应 Windows Server 2016 / 1607 基线版本,Build 版本号决定你去哪一类漏洞库里搜 exp。Hotfix(s) 列表更重要,它直接告诉你系统打了哪些补丁。像上面这台机器只有 3 个补丁,基本就是打完纯镜像之后没怎么更新,这种目标在内核提权上是高优先级。
System Type 是 x64-based PC,意味着后续编译 exp、加载 shellcode 都要按 64 位来。别小看这个判断,我曾经见过有人给 32 位目标传了 64 位后门,也见过 64 位系统上硬跑 32 位 exp 报错的,浪费时间不说,还容易暴露行为。System Manufacturer 显示 VMware,说明是虚拟机,VMware Tools 这类虚拟化特有的攻击面可以记一笔,但优先级不高。
2.2 补丁对比的实操:wesng 与人工核对
拿到 Hotfix 列表之后,下一步就是拿它去匹配已知漏洞。我最常用的工具是 wesng,它是一个补丁对比脚本,核心逻辑很简单:把 systeminfo 输出里的补丁列表,和公开漏洞公告里要求的 KB 编号做差集,列出这台机器可能受影响的 CVE。
# 在本地攻击机上先更新漏洞库,再对比 python wesng.py --update python wesng.py systeminfo.txt -o output.csvwesng 的输出会以 CSV 格式给出候选 CVE 列表,包括影响类型和补丁要求。我一般会再用人工过一遍,流程是这样:先看有没有已经集成到 Metasploit 或者有成熟公开 exp 的漏洞,类似 MS17-010、CVE-2020-1472 这种,这些利用成本低、失败率相对可控;再确认 exp 匹配当前系统版本和架构,Windows 10 的 exp 硬搬到 Server 2016 上经常是编译过了但跑不起来;最后还要结合后面 netstat 收集到的端口信息,确认漏洞触发条件是否满足,比如 SMB 相关漏洞要求 445 端口开放,如果防火墙挡了,就算补丁对得上也打不了。
这里要提醒一句:wesng 有误报,它只能说明“补丁缺失情况符合某个 CVE 的条件”,不代表这个 exp 一定能在目标上稳定利用。我自己的经验是把它当成筛选器,把候选范围缩到三五个以内,再逐个看 exp 细节,而不是看到什么 CVE 就打什么。
2.3 环境变量与架构判断的细节
set命令查看环境变量,属于很多人会跳过但偶尔有惊喜的操作。USERNAME 能确认当前运行身份,USERPROFILE 指向当前用户目录,TEMP 和 TMP 是临时目录路径,这些信息对后续写文件时判断目录可写性有用。真正值钱的是 PATH 里出现非系统默认路径,比如某个自定义安装目录,这个目录往往就是后续要关注的软件攻击面。
C:\Users\webadmin> set USERNAME=webadmin USERPROFILE=C:\Users\webadmin TEMP=C:\Users\webadmin\AppData\Local\Temp PATH=C:\Windows\system32;C:\Windows;C:\Program Files\CustomApp\bin;...架构判断在 systeminfo 里已经能看到 System Type,也可以用wmic os get osarchitecture单独拿。如果目标返回 AMD64,那就说明是 64 位系统。这个信息影响的不只是 payload 选型,还影响注册表路径的读取方向:64 位系统上 32 位软件的卸载信息存储在 WOW6432Node 节点下,后面讲软件收集时会再次提到。
3. 用户、权限与组关系:定准你的攻击目标
3.1 whoami 三层拆解:用户、特权、组
whoami 绝对是我在 Windows 提权里执行频率最高的命令,而且不是只跑一遍whoami就完了,要跑完整的三个变体。whoami看当前用户名,whoami /priv看当前令牌启用的特权,whoami /groups看所属组和完整性级别。
C:\Users\webadmin> whoami /priv Privilege Name Description State ========================================= ========================================== ======= SeImpersonatePrivilege Impersonate a client after authentication Enabled SeChangeNotifyPrivilege Bypass traverse checking Enabled SeIncreaseWorkingSetPrivilege Increase a process working set Disabled看到 SeImpersonatePrivilege 是 Enabled,这是我最兴奋的一行。在 Windows 服务环境里,服务账户经常被授予这个权限,用于模拟客户端身份。攻击者可以利用某些系统服务接口,让系统以 SYSTEM 身份生成可用的 token,再用当前进程去“借用”这个身份执行命令,从而获得 SYSTEM 权限。这也是土豆家族(各种 Potato)工具的核心原理。具体用哪个变种要看系统版本,Windows 10 1809 和 Server 2019 之后老方法被修补,要换新工具,这个细节我后面单独写。
除了 SeImpersonatePrivilege,还有几个特权值得优先看。SeBackupPrivilege 允许绕过文件 ACL 读取敏感文件,拿到它之后可以尝试直接读 SAM、SYSTEM 注册表配置单元,甚至用reg save导出离线分析。SeRestorePrivilege 反过来,可以覆盖系统文件,经常用来替换服务二进制。SeTakeOwnershipPrivilege 可以接管任意对象的所有权,拿到之后改一下 ACL 就能读原本拒绝访问的文件。SeLoadDriverPrivilege 可以加载驱动,风险较高,我一般在靶机上也会谨慎操作。
whoami /groups的关注点也明确:一是看当前用户是否属于 Administrators 组,二是看完整性级别。如果 Mandatory Label 显示 Medium,说明当前是标准用户令牌,需要提权;如果看到 High,说明已经有管理员权限,提权方向要转向绕过 UAC 或者横向移动。曾经见过输出里 BUILTIN\Administrators 显示“Group used for deny only”,意思是当前令牌被特意过滤掉了管理员权限,这种就是典型的服务账户降权配置。
3.2 本地用户与管理员组枚举
net user和net localgroup这两组命令,我每次都跑,作用不是直接提权,而是判断“这台机器上还有谁”。如果有别的本地用户,尤其是不常见的用户名,那我后续会用这些用户名去尝试复用口令、查看可写目录,有时候还能找到对方遗留在磁盘上的文件。
C:\Users\webadmin> net user User accounts for \\FILESRV01 ------------------------------------------------------------------------------- Administrator backup_admin guest webadminnet user 用户名可以看单个用户详情,里面有几个字段特别重要。Last Logon 能判断这个账户是不是活跃账号,如果一个用户几个月没登录,说明它的口令可能长时间没变,反而更值得关注。Local Group Memberships 会直接显示该用户是否在 Administrators 组里,比自己去翻组列表更直观。Password last set 字段也有参考价值,长时间没改密的账户,口令复用概率高。Password expires 如果显示 Never,也说明这个账户的口令策略宽松。
net localgroup Administrators用来确认管理员组成员。常见输出是 Administrator、webadmin 这种本地账户,但在域控上还会出现 DOMAIN\Domain Admins 这类域组,这也是判断机器是否在域内的一个辅助证据。我还会顺手跑一下net accounts,拿到密码策略信息,比如最短密码长度、锁定阈值,这些信息在横向移动时猜解口令有用,虽然提权阶段用不上,但记录下来没坏处。
3.3 PowerShell 与 WMI 视角的用户枚举
如果目标系统是 Windows 10 或 Server 2016 以上,我偶尔会用 PowerShell 的Get-LocalUser和Get-LocalGroupMember来补充枚举,输出是结构化对象,比 cmd 的文本好处理。WMI 的Get-WmiObject Win32_UserAccount也能列出本地账户,而且跨版本兼容性不错,适合脚本化。
Get-LocalUser | Format-List Name,Enabled,LastLogon Get-LocalGroupMember -Group "Administrators"坑在于 PowerShell 可能被配置为受限语言模式,很多 cmdlet 会被禁止,或者执行策略挡住脚本运行。所以我的习惯是:先用 cmd 的 net 命令把基础信息跑完,再用 PowerShell 查漏补缺,不把宝全押在一套命令上。另外,从 WMI 拿到的账户 SID 里,如果看到以-500结尾的 SID,那对应的是内置 Administrator 账户,就算它被改名了也能认出来,这类账户在提权和横向里的优先级都比较高。
4. 网络、服务与应用:找到横向和提权的入口
4.1 ipconfig 与网络定位
ipconfig /all在提权阶段不太被重视,其实信息量很大。我每次都会看 DNS 后缀、默认网关和 DNS 服务器地址,这三个字段能快速判断机器是不是域内机器,以及网络出口在哪。
C:\Users\webadmin> ipconfig /all Ethernet adapter Ethernet0: Connection-specific DNS Suffix . : lab.local IPv4 Address. . . . . . . . . . . : 10.10.10.5 Subnet Mask . . . . . . . . . . . : 255.255.255.0 Default Gateway . . . . . . . . . : 10.10.10.1 DNS Servers . . . . . . . . . . . : 10.10.10.10看到 DNS 后缀是 lab.local,DNS 服务器指向内网 10.10.10.10,基本可以确定这台机器在域内,而且 10.10.10.10 很可能就是域控兼 DNS 服务器,这条信息对后续横向移动非常重要。默认网关 10.10.10.1 是出网边界,如果要反弹 shell,就要确认本机到外网的连通性,以及防火墙对出方向端口有没有限制。如果机器有多个网卡或多个 IP,说明它可能身处多个网段,提权成功后横向可达的范围更大。这里插一句,如果你拿到的扫描报告上有“目标主机支持 rsa 密钥交换【原理扫描】”这类网络指纹告警,先记着就好,它只是网络层的一个侧面,真正的信息收集还是得落到命令行上。
4.2 netstat 活动连接与内部服务
netstat 是另一个我必跑的信息收集命令,重点是-ano参数,a 显示所有连接和监听端口,n 显示数字地址和端口,o 显示关联的进程 PID。
C:\Users\webadmin> netstat -ano Proto Local Address Foreign Address State PID TCP 0.0.0.0:80 0.0.0.0:0 LISTENING 4 TCP 0.0.0.0:135 0.0.0.0:0 LISTENING 692 TCP 0.0.0.0:445 0.0.0.0:0 LISTENING 4 TCP 0.0.0.0:1433 0.0.0.0:0 LISTENING 1220 TCP 0.0.0.0:3389 0.0.0.0:0 LISTENING 896 TCP 10.10.10.5:49675 10.10.10.10:389 ESTABLISHED 812本机监听端口里出现 1433,说明装了 SQL Server,这个服务经常以高权限运行,而且它的弱口令和密码在配置文件里经常能找到线索;3389 是 RDP,虽然提权阶段用不上,但横向移动时很关键。再看 ESTABLISHED 状态的连接,10.10.10.5:49675 到 10.10.10.10:389,这是到 LDAP 域控的通道,几乎坐实了域控身份。如果当前用户权限允许,tasklist /svc /fi "PID eq 1220"可以把 PID 关联到具体服务名。普通用户下 tasklist 可能拿不到完整进程信息,但至少端口和 PID 是能拿到的,记下来供后续分析。
4.3 已安装软件与服务信息:别被 wmic product 坑了
查已安装软件,很多人第一反应是wmic product get name,version,vendor,但这条命令在真实环境里坑很深。它执行慢,有时候要跑好几分钟,还会触发系统一致性检查,甚至卡死。我不建议在靶机上等它,有那时间都够跑好几轮别的命令了。
更快的办法是翻注册表卸载列表:
reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" /s | findstr /i "DisplayName DisplayVersion" reg query "HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall" /s | findstr /i "DisplayName DisplayVersion"这两条命令分别查 64 位和 32 位软件的卸载信息,速度比 wmic 快得多。拿到软件版本后,重点看第三方软件,比如压缩工具、数据库客户端、运维工具,这类软件往往有历史漏洞,而且不像系统补丁那么及时。
服务信息也不能漏,wmic service get name,displayname,pathname,startmode可以列出一大堆服务,我主要用来排查 Unquoted Service Path,也就是服务路径带空格但没有用引号包裹的情况。快速定位思路是用 findstr 过滤带 Program Files 的服务路径,再看路径两端有没有引号。如果服务以 SYSTEM 权限运行,而它的可执行文件所在目录当前用户可写,那就存在替换服务二进制的提权条件。进一步的权限确认可以用 Sysinternals 的 accesschk,先看机器里有没有现成工具,有的话直接accesschk.exe -ucqv <服务名>,能看到当前用户对服务的具体权限。
5. 容易被忽略的“隐藏宝藏”
5.1 任务计划与启动项
任务计划是我早期经常漏掉的一块,后来被队友提醒了一次才养成习惯。Windows 里很多运维会创建计划任务来定期执行脚本,这些任务如果是 SYSTEM 运行,而且脚本路径写到用户可写目录,就是现成的提权点。
schtasks /query /fo LIST /v | findstr /i "TaskName RunAs User Next Run"/fo LIST /v 是详细输出格式,但信息量太大,不加过滤根本看不过来,所以我用 findstr 把任务名、运行身份、下次运行时间过滤出来。优先关注 Run As User 是 SYSTEM 的任务,再看它指向的脚本或程序路径是否可写。如果某个任务还带“下次运行时间”很近,那甚至可以等它自动触发;有些任务也支持schtasks /run /tn <任务名>手动触发,能不能用试一下就知道了。
注册表启动项也是同样的思路,我一般会查四个位置:
reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce" reg query "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" dir "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp"启动项里指向的 exe 或脚本路径如果可写,重启或者下次登录就会执行。但这个方案要等重启,在靶机上时间成本太高,所以我通常把它放在其他手段都不行的时候再考虑。
5.2 敏感文件与历史记录
敏感文件收集属于“加分项”,一旦命中就是高分,所以我放在比较靠后的位置,先把前面的基础信息跑完。我常查的路由有这么几个:
type C:\Windows\Panther\unattend.xml type C:\Windows\Panther\Unattend\unattended.xml type C:\inetpub\wwwroot\web.config dir /s /b C:\Users\ 2>nul | findstr /i "password pass secret"unattend.xml 是无人值守安装文件,里面经常明文保存本地管理员密码,这是 Windows 密码泄露最经典的路由之一。web.config 是 IIS 站点配置,里面的 connectionStrings 节点经常直接给出数据库账号口令,拿到之后如果本机正好开着 1433 端口,就能直接对上。搜索用户目录里包含 password、secret 这些关键词的文件也是个办法,但全盘搜非常慢,我一般用dir /s /b加 findstr 的组合,而且限定在用户目录和 inetpub 这类常见目录里。
PowerShell 历史记录是我特别想单独说一句的。默认路径是%APPDATA%\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt,直接 type 出来就能看到管理员之前敲过什么命令。如果对方运维习惯在命令行里敲数据库密码、远程连接命令,那这条历史文件的信息量直接爆炸。cmd 历史默认不落盘,除非装了 doskey,但 PowerShell 历史是自动保留的,所以拿到 shell 之后记得去翻。
5.3 防火墙状态与安全日志
防火墙状态对提权阶段的一个直接影响是反弹 shell 的连通性。我见过不少同学反弹 shell 连不上,排查半天发现是 Windows 防火墙挡了出方向端口。所以拿到 shell 后我会先看一眼:
netsh advfirewall show allprofiles如果三个配置文件都是 State ON,说明本机防火墙在拦截入站连接,反弹 shell 就需要优先选择已放行的端口,比如 80、443,或者考虑改用 DNS 隧道这类更隐蔽的方式。netsh advfirewall firewall show rule name=all可以列出所有规则,但输出巨长,我一般配合 findstr 过滤端口和方向,不整体铺开看。
安全日志这块属于更进阶的操作。如果当前用户恰好有读取日志的权限,比如属于 Event Log Readers 组,那wevtutil qe Security /c:20 /rd:true /f:text可以拉出最近 20 条安全日志。Event ID 4624 是登录成功,4688 是进程创建,通过分析可以掌握管理员登录的时间规律,甚至在实战里判断目标环境是否有人在实时操作。auditpol /get /category:*可以查看审计策略,了解这台机器到底记录了哪些行为。这个环节在靶机上偶尔会遇到,属于“隐藏宝藏”,费不了多少时间,但信息价值可能很高。
我个人在实际操作里体会最深的一点是:信息收集的深度,直接决定了提权之路能不能打通。服务路径带空格的问题,我第一次遇到时绕了大半个小时,后来才发现之前跑的 service 列表里早就写明了 pathname,只是没认真看。现在我把 systeminfo、whoami /priv、netstat -ano 这些基础命令的输出全部重定向到本地一个文件里,再逐字段做注释,久而久之就形成了自己的信息收集模板。下次换一台新机器,直接套模板跑一遍,效率和成功率都能上来。下一篇准备写怎么把这些信息转换成具体的利用链,重点讲不同提权手法的触发条件,到时候再细聊。