关键在于收紧服务安全描述符(dacl),切断未授权用户对服务的读取、查询、启动、配置等底层访问能力;需使用内部服务名(如spooler)而非显示名称配置gpo,移除authenticated users和users组权限,仅保留administrators、system及审批运维组的最小必要权限,并同步限制sc.exe、powershell.exe等绕过工具及调试、服务登录等高危用户权限。

要防范非法权限调用和服务驻留,关键不是“禁用服务”或“隐藏界面”,而是从服务对象本体出发,收紧其安全描述符(DACL),切断未授权用户对服务的读取、查询、启动、配置等底层访问能力。这种控制直接作用于Windows服务内核对象,比图形界面屏蔽或命令行封禁更根本、更难绕过。
明确目标服务并确认准确内部名称
服务显示名称(如“Print Spooler”)不能用于策略配置,必须使用其唯一内部服务名(如Spooler)。错误的服务名会导致GPO完全不生效。验证方式:
- 在目标服务器上运行:
sc qc Spooler(查看配置) - 或执行:
Get-Service | Where-Object {$_.DisplayName -like "*打印*"} | Select Name, DisplayName
只对真实存在且业务允许受限的关键服务操作,例如RemoteRegistry、WinRM、WSearch、Sysmon(若为第三方)等高风险或非必要服务。
在组策略中精细设置服务安全描述符
路径:计算机配置 → 策略 → Windows 设置 → 安全设置 → 系统服务
- 右键空白处 → “添加服务”,输入已确认的内部服务名(如
RemoteRegistry) - 双击该服务 → 勾选“定义此策略设置” → 点击“编辑安全性”
- 在权限窗口中:
- 移除
Authenticated Users和Users组(或显式拒绝其权限) - 仅保留
Administrators、SYSTEM及经审批的运维组(如SG-ServerAdmins) - 对运维组授予最小必要权限:通常“读取”+“查询状态”+“启动”+“停止”即可,避免“完全控制”
- 不建议移除所有非管理员权限后仍保留“读取”——若目标是防驻留探测,应至少移除“读取”和“查询状态”,否则
sc query xxx仍可返回服务存在性信息
- 移除
阻断命令行与脚本层面的绕过路径
即使服务权限收紧,用户仍可能通过工具间接探测或触发行为:
- 在同一GPO中,用户配置 → 管理模板 → 系统 → 可执行文件的限制 → 启用“不允许运行指定的Windows应用程序”,添加:
sc.exepowershell.exe(如需严格管控;可后续用AppLocker按签名/路径细化) - 更推荐方式:使用AppLocker(计算机配置 → 应用程序控制策略 → AppLocker → 可执行规则)
- 新建“拒绝”规则,路径设为
%SystemRoot%\System32\sc.exe,作用于Domain Users - 同时可加规则限制
wmic service、net start等常用替代命令
- 新建“拒绝”规则,路径设为
配合用户权限分配切断底层访问能力
某些权限会间接支撑服务操作,需同步清理:
- 计算机配置 → Windows 设置 → 安全设置 → 本地策略 → 用户权限分配
- 检查并确保普通用户未被赋予:
调试程序(SeDebugPrivilege)—— 可绕过DACL直接打开服务对象作为服务登录(SeServiceLogonRight)—— 允许以服务身份运行任意代码管理审核和安全日志(SeSecurityPrivilege)—— 可通过事件日志反推服务启停行为 - 将上述权限仅授予明确需要的管理员组
- 检查并确保普通用户未被赋予:
验证是否真正生效
策略部署后必须实测,而非仅看GPO编辑界面:
- 客户端执行
gpupdate /force,然后以标准域用户全新登录(用户策略需新会话) - 测试以下行为是否失败:
services.msc→ 应无法打开或提示被禁用sc query RemoteRegistry→ 应返回“拒绝访问”或“访问被拒绝”,而非服务状态Get-Service RemoteRegistry(PowerShell)→ 抛出AccessDenied异常net start Spooler→ 提示“拒绝访问”
服务安全描述符控制是防御非法驻留的核心防线。它不依赖界面是否存在,也不受shell命令是否可用影响——只要服务对象本身拒绝访问,任何调用都会在系统调用层被拦截。










