ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Windows权限提升必读:服务、计划任务与敏感文件信息收集指南

Windows权限提升必读:服务、计划任务与敏感文件信息收集指南

接着说上回没聊完的。我在 OSCP 研记系列里复盘 Windows 权限提升时,把“获取目标主机的基本信息”这块内容拆成了上下两篇。上一篇侧重系统版本、补丁级别、当前用户、管理员组这一类的静态信息,用来回答“这台机器能不能打已知漏洞、我当前是什么身份、能不能碰更高权限的对象”。这一篇我把镜头往深处推,梳理服务、计划任务、进程、网络连接、共享资源,以及散落在磁盘各处的敏感文件。对备考 OSCP 或者刚开始接触内网渗透的人来说,这部分才是真正决定提权路径怎么走的“动态情报”。

为什么要先做这么一轮信息收集?因为权限提升本质上不是拿着脚本挨个试漏洞,而是先搞清楚目标身上有哪些“不合理的配置”。一台系统补丁打得很全的机器,可能某个第三方服务的安装路径任何人都能写;一台看起来平平无奇的工作站,可能桌面放着带密码的运维脚本。这些信息不会自动出现在你面前,需要你主动翻出来。下篇要做的,就是把“提权路由图”给画出来。

1. 信息收集该看什么:先把提权路由图画出来

1.1 上下两篇怎么分工

信息收集如果一股脑全做,很容易漏项,也容易冗余。我的习惯是把它拆成“静态”和“动态”两层。静态层对应上一篇,主要看操作系统本身:主机名、系统版本、补丁安装情况、系统架构、当前用户名、隶属组、当前进程 token 的权限级别。这一层解决的问题是:内核有没有可能出问题,我这个用户是不是已经在某个高权限组里,有没有我能直接读却读不到的东西。

动态层就是这一篇的内容,重点看机器上正在跑什么、哪些行为后期可以被干预。具体来说包括服务列表、计划任务、进程列表、网络连接、共享目录、敏感文件。这一层解决的是:除了内核漏洞之外,还有没有别的路能拿到 system 或管理员权限;这台机器在内外网之间扮演什么角色;有没有现成的凭据可以直接复用。

分层的好处是排查速度快。每次拿到一台目标机器,我都是按固定顺序过一遍:先看静态信息,再看动态信息,最后才决定往哪个方向发展。不会出现打了半天发现某个服务路径可写、白白错过更稳路径的情况。

1.2 信息价值判断的漏斗

信息收集最容易犯的错是“什么都记下来,什么都没分析”。我习惯在收集过程中就把每条信息挂到一个漏斗上:这条信息到底指向哪条提权路径,值不值得深挖。

常见映射关系大概是这样的:

收集到的信息可能的利用方向价值判断
第三方服务路径包含空格且未加引号服务路径劫持高,优先验证目录权限
服务二进制所在目录当前用户可写替换服务程序高,如果服务是 system 启动则大概率拿下
计划任务指向用户可写的脚本替换脚本内容高,等待触发即可
当前用户能读取其他用户的目录凭据复用中高,取决于目录内容
存在本机数据库端口监听数据库凭据复用或漏洞利用中,看版本和弱口令
网络共享中存在备份或脚本静态凭据提取中高,文件内容决定
进程以 system 权限运行且存在已知漏洞进程级漏洞利用视版本而定,需要进一步验证

这个漏斗的真正意义,不是让你把所有信息都收集完再动手,而是每一条新信息都要主动问一句“如果这条利用不了,我下一步要看什么”。比如服务路径可写,那就验证目录权限;验证完确实可写,那当前用户提权路径就基本确定了,后面很长一段时间都会顺着这条线走。

1.3 什么时候算收集够了

有人会问,信息收集要做到什么程度才收手?我的答案是:当你已经发现一条“可以推得动”的路径时,就该停下来去验证,而不是继续满盘翻找。提权测试最忌讳的是收集一小时、利用五分钟,然后发现路径不通,回头又花一小时看日志。

但反过来,如果当前信息只够支撑模糊的猜想,那就继续补。常见的情况是已经发现某个服务路径可写,但不确定服务是不是 system 启动,这时候就需要回到服务列表里确认 startname。这种“收集——验证——再收集”的循环,才是信息收集的正确节奏。信息收集不是一次性的前置工作,它是贯穿整个提权过程的基础动作。

2. 服务与计划任务枚举:最容易找到“到手点”的地方

2.1 服务信息采集命令集

Windows 服务这块,老生常谈的几个命令各有适用场景。我最常用的是下面这几条,按优先级排下来。

wmic service get name,displayname,startmode,state,pathname,startname /format:list

这条命令能把服务名、启动模式、运行状态、二进制路径、启动账户都输出成列表,方便一条一条看。缺点是 wmic 在比较新的 Windows 版本里被默认禁用了,很多 Server 2019 之后的系统跑了会提示不存在,这时候改用 PowerShell。

Get-CimInstance Win32_Service | Select-Object Name,State,StartMode,StartName,PathName | Format-List

效果和 wmic 差不多,而且不需要额外依赖。如果是 PowerShell 被约束语言模式限制的环境,那就退回 cmd 下的 sc 命令:

sc query type= all state= all

sc query 输出比较简略,不显示二进制路径,需要配合后面的具体查询来看。用下面的命令查单个服务的详细信息:

sc qc 服务名

这条能看到服务的二进制路径、启动账户、服务类型,是排查服务配置错误时的核心命令。

实践中有个细节:服务名存在空格时,sc 命令要用引号包住服务名,否则会把空格后面的内容当成另一个参数。

2.2 高价值服务四类属性

服务列表拿到手之后,别每个都看,机器上几十个服务逐个看会累死。我一般只快速筛四类属性,记住这个简单判断框架。

第一类是服务路径包含空格且未加引号,也就是常说的 Unquoted Service Path。Windows 执行这种路径时会把空格当成分隔符,按顺序尝试解释路径。如果前面的目录层级存在且当前用户可写,就可以放一个伪造的执行文件进去。判断方法就是看路径里有没有空格,以及是否有引号包裹。

第二类是服务二进制所在目录或文件当前用户可写。这类问题通常出现在第三方软件上,安装时的默认权限可能给 Everyone 或者 Users 留下了写权限。可以用 icacls 快速验证:

icacls "C:\Program Files\某第三方服务\service.exe"

只要当前用户对 exe 文件有写权限,替换二进制之后重启服务就能稳定提权,比折腾内核漏洞省事得多。

第三类是服务本身的权限配置错误。也就是说当前用户虽然没有文件写权限,但可以修改服务的配置项,把 binPath 指向自己上传的程序。用 sc sdshow 查看服务的安全描述符,如果里面出现 Everyone 或者 Authenticated Users 允许 SERVICE_CHANGE_CONFIG,那就很值得深挖。

第四类是服务以 system 权限运行,同时启动路径指向用户目录、临时目录这类当前用户可写的区域。这种配置在开发环境、测试环境里非常常见,属于典型的弱配置。

我习惯把四个点整理成一张速查表,排错的时候对着找:

关注点检查命令判断标准
未加引号的服务路径sc qc 服务名路径含空格且无引号,前面目录可写
服务二进制可写icacls 二进制路径当前用户具备写权限
服务配置可改sc sdshow 服务名描述符中包含允许修改的权限
高权限服务指向用户目录sc qc 服务名system 启动且路径落在 C:\Users\xxx 下

2.3 计划任务别忽略

计划任务比服务更容易被忽略,但利用方式和思路其实是相通的。查看计划任务用这条:

schtasks /query /fo LIST /v

输出会很长,我一般直接配合 findstr 做关键词过滤,只看任务名、运行账户、执行命令这几列:

schtasks /query /fo LIST /v | findstr /i "TaskName Run As User Task To Run"

重点关注两类任务:以 SYSTEM 或管理员账户运行的任务,以及执行脚本位于当前用户可写目录的任务。只要满足这两个条件,替换脚本内容后等待任务触发,就能拿到高权限执行。计划任务的触发时间有时很反直觉,可能是开机启动,也可能是某个事件触发,确认任务逻辑的时候多花点时间把触发器看全。

值得注意的是,很多 OEM 工具和第三方软件自动注册的计划任务,权限并不像系统任务那么严格,反而成了提权路上最顺手的入口。

3. 进程、网络与共享:画出“目标在干什么”

3.1 进程枚举与权限关联

进程列表的作用,是告诉你这台机器当前正在运行业务的即时状态。相比服务列表,进程列表能反映当前有没有杀软、有没有数据库客户端、有没有运行中但未注册成服务的高权限程序。基础命令就这几条:

tasklist /v

加上 /v 参数能看到进程归属的用户名,一眼扫过去就能知道哪个进程在以 system 或管理员身份运行。

Get-Process | Select-Object Id,ProcessName,Path,Company

PowerShell 版多显示进程路径,方便后续结合目录权限来判断。另一个有用的小技巧是用 tasklist /svc,把进程与它所属的服务对应起来,这样就能把 3.1 的进程列表和 2.2 的服务列表串起来。

拿到进程列表后,我重点关注三类:第三方软件的更新进程、数据库进程、以及任何以 system 运行但路径在用户目录的程序。这三类进程如果存在已知漏洞,或者其加载路径可写,后续能做的事情非常多

3.2 网络连接与监听端口

网络信息是判断内网横移价值的核心。先拿到网卡基本配置:

ipconfig /all

重点看接口上绑定的 IP 地址是否有多网段地址。比如一台机器同时有 192.168.10.x 和 172.16.5.x 两个网段的地址,说明它可能是内外网交界处的跳板机,横向价值极高。

再看当前活动的网络连接:

netstat -ano

把监听状态的端口整理出来,和进程 PID 对应上,基本就能还原出这台机器对外暴露了哪些服务。比如看到 3306 在监听且进程是 mysqld,说明这机器上跑着 MySQL;看到 3389 在监听,说明可能开了远程桌面。

这些信息的重要程度常常被低估。很多人在信息收集阶段只看服务不看端口,结果纵向提权完成后,横向路却不知道怎么走。实际上,一份端口监听清单就是一份“横向路线图”:优先访问那些只在内网地址上监听的数据库端口、共享端口、管理端口,往往能拿到比目标机器本身更值钱的数据。

3.3 共享资源与隐藏的业务信息

共享这块,工作组环境和域环境差别很大。域环境里机器之间互访很常见,工作组环境则少一些。但不管哪种,都值得先看一眼本机共享:

net share

再看看当前网络内可见的共享:

net view

如果看到其他机器开放的共享,可以用 net use 尝试连接,连通性取决于是否有对应凭据。这里跟前一阶段收集到的用户凭据正好能配合上——先拿凭据,再看共享,顺序不要反。

共享目录里最容易出现的有三类内容:备份文件、部署脚本、安装包。备份文件包含可能包含完整数据库备份或系统镜像,部署脚本常常硬编码各种账号密码,安装包则可能藏有未加密的配置文件。相比慢慢翻用户目录,共享目录的信息密度通常更高,值得优先扫。

4. 敏感文件与凭据线索搜索:不放过任何“顺手牵羊”

4.1 目录级搜索:配置文件、脚本、备份

到了这一步,目标主机的基本信息拼图已经完整了一大半,剩下的是挖掘磁盘里的静态敏感文件。优先找这些目录:当前用户的桌面、下载、文档,管理员桌面的可读部分,C:\inetpub、C:\backup、C:\temp,以及用户主目录下所有可见子目录。

搜索文件内容我一般用 findstr,因为它是系统自带命令,动静小、不落地,比上传第三方搜索工具稳妥:

findstr /s /i /m "password passwd pwd secret credential" C:\Users\*.txt C:\Users\*.bat C:\Users\*.ps1 C:\Users\*.xml C:\Users\*.config 2>nul

第一次搜索建议把范围限定在用户目录和常见配置目录,命中率最高。等初步结果出来后,再扩大到整个磁盘范围的搜索。如果目标机器是中文系统,注意编码问题,有时候需要用 chcp 437 切回英文代码页,避免出现搜索乱码。

命中敏感文件之后,处理规范要记好:不要直接在目标机器上打开文件分析,哪怕是一个 txt 文件,也可能触发杀软钩子。优先把文件内容复制回本地分析环境,或者用 type 命令输出并记录到本地笔记里。这样既留了证据,也能避免在不必要的环境中暴露意图。

4.2 Windows 系统自身的“隐写”

除了翻配置文件,Windows 本身有几处“官方后门式”的位置,专门存放用户密码信息。排第一的是注册表自动登录项:

reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"

这里如果出现 DefaultPassword 字段,那就等于拿到了明文口令。很多 IT 运维为了方便,会在个人电脑上启用自动登录,这个信息在真实目标里出现频率比我预想的高得多。

接下来是已保存的网络凭据:

cmdkey /list

列出的是当前用户保存过的远程连接凭据,如果里面有管理员凭据条目,配合后续横向移动会非常舒服。

还有一类是应答文件。Windows 部署时用到的 unattend.xml、sysprep.xml 等文件,经常包含本地管理员密码的明文或 Base64 编码值,一般放在 C:\Windows\Panther、C:\Windows\System32\sysprep 等目录。

dir /s /b C:\*.xml 2>nul | findstr /i "unattend sysprep"

最后别忘了环境变量本身,有时也会存储临时凭据。用 set 命令看完环境变量,重点看是否出现类似于 API Key、Token、密码字段的变量名,这类信息通常是运维脚本留下的坑。

4.3 凭据搜索的“度”与抗干扰

凭据搜索最容易失控,我在这里卡了很多次。首要原则是控制动静。不要一上来就在整块磁盘上跑 findstr,杀毒软件对这类行为非常敏感,尤其是老牌 EDR,识别到 findstr 扫描大量文件会直接弹告警,导致后续操作受限。

我的做法是先搜索高价值目录,比如用户主目录、部署目录、备份目录,第一轮不追求全面,只追求命中率。一轮结束后,根据命中的文件内容决定是否扩大搜索范围。搜索时尽量用系统自带命令,不要往目标机器上传第三方搜索工具,否则杀软特征库万一命中,反而得不偿失。

另外,权限不够时不要强行读取别人目录的内容。以当前用户权限读不到的内容,记录下来“哪条路径不可读”本身就是一条情报——它说明这条路径的主人有更高权限,值得后续提权之后再回头来看。

5. 实操记录与常见问题排雷

5.1 命令不能用时的回退方案

真实环境永远不会像培训环境那么乖乖听指令。我整理了一张命令回退表,遇到“命令不存在”或“当前环境限制”的时候直接查,能省不少排查时间。

场景首选命令回退方案
查询服务列表Get-CimInstance Win32_Servicesc query type= all state= all
查询服务配置sc qc 服务名读注册表 HKLM\SYSTEM\CurrentControlSet\Services\服务名
查询计划任务schtasks /query /fo LIST /v读注册表 HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tree
搜索文件内容findstr /s /i /m 关键词 路径PowerShell Select-String
查看网络连接netstat -anoGet-NetTCPConnection

遇到 wmic 不可用时别慌,Windows 10 1809 之后 wmic 就被逐步移除了,这是正常现象。PowerShell 如果遇到约束语言模式,很多 cmdlet 会不可用,那就退回纯 cmd 命令。最极端的情况是终端本身有问题,可以考虑用计划任务或者服务查询把信息写到日志文件里再慢慢看。

5.2 自动化工具的定位

像 winPEAS 这类自动化枚举工具,在 OSCP 备考圈子里已经算是标配。我的观点是:工具可以用,但要清楚它在你整个流程里扮演的角色。winPEAS 真正的价值是“不遗漏”,它会把服务、计划任务、网络、注册表、文件搜索的信息整合成一份报告,并按风险等级高亮。但输出的报告比较长,新手最容易犯的错是把整份报告都抄进笔记,然后仍然不知道下一步干嘛。

我的用法是:先用 2 到 4 章里讲的手工命令把关键信息过一遍,形成自己的判断,再用 winPEAS 做交叉验证。比如手工排查发现某个服务路径有问题,winPEAS 报告里如果同样高亮了这条,那基本可以确认值得投入时间深挖。如果 winPEAS 高亮了某个风险点,但手工排查没注意到,那就回头补做一次手工验证。

工具转移也有讲究,winPEAS 体积不小,目标机器如果下载通道受限,可以通过共享目录、Web 服务器等方式中转。但不管怎么传,都要意识到动静问题:文件落地的一瞬间,杀软就可能开始扫它了。所以我的习惯是,先手工收集,再决定要不要上工具。

5.3 几条实操心得

写了这么多,最后分享几个我踩过坑之后形成的操作习惯。

第一条,每台目标机都要按固定清单走。不要因为上一台机器上没有服务问题,就觉得这台也不用看服务。不同机器的安装时间、安装人员、软件来源完全不同,固定清单能保证你每次不漏项。

第二条,发现路径可写但没验证时,别急着高兴。某次实验里我看服务配置后发现路径指向 C:\Users\某用户\AppData\Local 下的一个程序,理论上当前用户可写,但实际 icacls 一看,那个子目录被单独设置了拒绝写入。类似情况不少,所以任何“疑似可利用”的信息,都要落到命令验证上才算数。

第三条,信息收集要克制。拿到机器后最忌讳的是满盘乱翻,把自己当成搜索引擎。先抓系统、服务、进程、网络、共享这几样主干,再顺着主干上暴露出的异常点做敏感文件搜索。主干信息没看完之前,不要急着去看文件。顺序反了,大概率会在低价值文件里浪费大量时间。

信息收集这件事,做得好的人不是收集得最多的,而是花最短时间确认最靠谱路径的人。这一篇里列的所有命令和思路,拿到授权测试环境跑几遍就会变成肌肉记忆。等你把服务、计划任务、网络、共享、敏感文件这五块信息都能流利地捞出来,再回头看提权,你会发现大部分路都是被信息直接铺好的。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进