You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows系统如何记录尝试停止指定服务的操作用户信息

问题根因

你之前写的Go代码无法触发,核心原因有两个:

  • 你已经通过修改服务安全描述符加了访问限制,普通用户发起的停止服务请求会在SCM(服务控制管理器)层直接被拦截,根本不会发送到你的服务进程内部,服务内的逻辑自然没有执行机会。
  • 你写的UserDetails()函数没有绑定任何服务控制事件的监听回调,就算请求能到达服务进程,没有挂载到服务控制处理流程里的函数也不会自动执行。另外这个函数里调用user.Current()拿到的是服务进程自身的运行账号,根本不是发起停止请求的用户。
可落地方案

方案1:系统安全审计(零代码、最可靠)

这是最稳的方案,所有操作在系统层记录,不存在被绕过的可能:

  • 打开本地组策略编辑器,定位到计算机配置 > Windows 设置 > 安全设置 > 高级审核策略配置 > 系统审核策略 - 本地组策略对象 > 对象访问,开启审核权限使用的成功、失败审计;再定位到同目录下的系统 > 审核安全系统扩展,同样开启成功、失败审计。
  • 给目标服务配置SACL(系统访问控制列表):先执行sc sdshow <你的服务名>拿到当前服务的安全描述符,给普通用户组、交互式用户组添加停止服务权限的访问失败审计规则。配置完成后,任何用户尝试调用停止服务接口的行为,不管是否成功,都会自动记录到系统安全日志中,日志自带发起请求的用户SID、用户名、操作进程ID、操作时间,直接在事件查看器的Windows 日志 > 安全路径下筛选事件ID4656、4674就能查到全量记录。
  • 这个方案不需要修改现有服务的任何代码,就算攻击者用管理员权限尝试操作,记录也会落盘。

方案2:ETW订阅SCM事件(自定义程度高)

Windows SCM内置了ETW(事件跟踪)提供方,专门对外抛送所有服务管控操作事件:

  • 写一个独立的轻量守护进程(不要和目标服务放在同一个进程内,避免服务被强杀时日志进程一起挂),订阅SCM的ETW会话(提供方GUID为{f1a16186-8f19-4d5b-96f2-62c09f29862d}),捕获所有服务控制类事件。
  • 从捕获到的事件里可以直接解析出操作类型(停止/启动/修改配置)、发起操作的进程PID、客户端用户令牌信息,解析出用户名等你需要的字段后,可以按自定义格式写入日志文件,不需要开启系统审计策略,日志结构可以完全按需定制。

方案3:服务内回调拦截(仅适合无高权限用户的场景)

如果你不想做系统级配置,可以调整现有服务的权限配置和逻辑:

  • 不要直接在服务安全描述符里删掉所有用户的停止权限,而是保留用户发送停止请求的权限,在服务内部的控制回调里直接返回ERROR_ACCESS_DENIED拒绝停止请求,这样停止请求可以到达你的服务进程,你就能拿到请求上下文。
  • 不要用你现在写的UserDetails()函数逻辑,需要先通过Go的Windows服务包注册服务控制处理回调,在收到SERVICE_CONTROL_STOP事件时,调用RpcBindingInqClientToken接口拿到发起RPC请求(SCM和服务进程通过RPC通信)的客户端用户令牌,从令牌里解析出用户名、域信息,写完日志后再返回拒绝停止的状态。
  • 注意:这个方案抓不到高权限用户直接通过进程终止接口强杀服务的行为,这类操作不走SCM的服务控制通道,服务内的回调根本不会触发,可靠性不如前两个系统级方案。
原有代码的问题提示

你贴的Go代码本身有几个明显问题,就算触发到逻辑也会异常:

  • 写文件的错误判断写错了变量:你定义的写文件错误变量是erro,但判断时用的是err != nil,会漏判写文件失败的场景。
  • 写文件的权限参数传0不符合Windows文件权限要求,至少要传0644,否则创建出的日志文件可能无法正常读写。
  • 工具函数里不要直接调用log.Fatal类方法,这类方法会直接终止进程,放在服务逻辑里会导致服务异常崩溃。

内容的提问来源于stack exchange,提问作者Fierceee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 16:34:13