Windows 服务持久化排查
服务是 Windows 上权限最高、最稳定的自启方式:可以配置为开机自动启动,也可以指定以 SYSTEM 身份运行,因此常被用于长时间驻留。排查要从两个方向入手:一是服务的可执行文件路径是否落在非常规目录,二是以 svchost 宿主运行的共享服务是否被塞进了额外的服务 DLL。只看服务的显示名几乎没有意义,因为显示名可以随意填写,甚至与真正的实现完全无关。
基本信息
| 枚举命令 | Get-CimInstance Win32_Service;旧系统可用 sc query type= service |
|---|---|
| 详情查看 | sc qc 服务名 查看二进制路径、启动类型、运行账号 |
| 存储位置 | 注册表 HKLM 下的 SYSTEM\CurrentControlSet\Services\<服务名> |
| 服务 DLL | 共享服务的实现写在子键 Parameters 的 ServiceDll 值里 |
| 关注字段 | State、StartMode、PathName、StartName、ProcessId |
| 权限要求 | 读取全量服务信息与注册表需管理员权限 |
典型使用场景
- 排查主机被植入常驻服务,尤其是以 SYSTEM 身份运行的可疑项
- 确认某个端口对应的服务是什么、由谁启动
- 核对服务是否被改为自动启动以维持驻留
- 检查 svchost 宿主下被加载的异常服务 DLL
- 处置后确认服务已被停用或移除
枚举并筛可疑服务
枚举并筛可疑服务
Get-CimInstance Win32_Service | Select-Object Name,DisplayName,State,StartMode,StartName,PathName | Format-Table -AutoSize
Get-CimInstance Win32_Service | Where-Object { $_.PathName -notmatch 'System32|Program Files|Program Files \(x86\)|ProgramData' } | Select-Object Name,StartMode,PathName
sc.exe qc 可疑服务名 # 二进制路径与运行账号
reg query 'HKLM\SYSTEM\CurrentControlSet\Services\可疑服务名\Parameters' # 看 ServiceDll
Get-CimInstance Win32_Service | Where-Object StartMode -eq 'Auto' | Measure-Object | Select-Object Count字段读法
| 字段 | 含义 | 异常信号 |
|---|---|---|
| Name 与 DisplayName | 服务名与显示名 | 显示名仿冒系统组件,实际名与实现无关 |
| State | 运行状态 | 已停止但仍配置为自动启动,重启后会恢复 |
| StartMode | 启动类型 | 被改为 Auto 或 Auto 加延时启动 |
| PathName | 可执行文件路径 | 位于用户目录、临时目录或含随机文件名 |
| StartName | 运行账号 | 以 LocalSystem 运行的非微软服务 |
| ServiceDll | 共享服务的实现文件 | svchost 宿主下加载了非系统目录的 DLL |
路径缺少引号也是风险:可执行路径含空格却没加引号时,系统会按空格分段尝试解析,攻击者可以在中间路径放一个同名程序实现劫持。排查时把这类路径单列出来核对。
处置顺序要先停后禁再删:先确认服务不是业务组件,再停止运行,然后改为禁用并重启验证,最后才考虑删除注册表项。直接删除导致无法回退,且可能触发系统自动重建。