《Windows Internals》10.2.10 服务隔离:为什么 Service SID 能让服务拥有自己的安全身份?
个人主页杨利杰YJlio❄️个人专栏《Sysinternals实战教程》 《Windows PowerShell 实战》 《WINDOWS教程》 《IOS教程》《微信助手》 《锤子助手》 《Python》 《Kali Linux》《那些年未解决的Windows疑难杂症》让复杂的事情更简单让重复的工作自动化文章目录1. 《Windows Internals》10.2.10 服务隔离为什么 Service SID 能让服务拥有自己的安全身份2. 先说结论服务隔离解决的是“同账户多服务边界不清”的问题3. 为什么仅靠服务账户隔离不够3.1 只靠服务账户的典型问题4. 什么是 Service SID4.1 Service SID 和服务账户有什么区别5. Service SID 是如何参与访问控制的6. Service SID 在服务启动时是如何进入 Token 的7. 如何查看一个服务的 Service SID8. Unrestricted 和 Restricted 有什么区别8.1 Unrestricted服务 SID 进入 Token用于正常 ACL 授权8.2 Restricted进一步限制服务访问边界9. 从桌面支持视角如何理解服务隔离9.1 一个推荐排查思路9.2 常用排查命令查看服务配置查看服务 SID查看服务 SID 类型查看服务对应进程查看某个 svchost 托管哪些服务查看目录 ACL给服务授权目录访问10. 服务隔离的核心流程10.1 SCM 启动服务10.2 生成服务身份10.3 注入 Service SID10.4 按 ACL 访问资源11. 服务隔离和虚拟服务账户有什么关系12. 常见误区服务隔离不是“绝对安全”而是降低影响范围12.1 误区一服务有了 Service SID 就绝对安全12.2 误区二服务隔离可以替代最小权限运行12.3 误区三只要服务运行在 LocalSystem 下Service SID 就没意义12.4 误区四共享 svchost 中的服务隔离效果和独立进程完全一样13. 总结提升下一篇预告1. 《Windows Internals》10.2.10 服务隔离为什么 Service SID 能让服务拥有自己的安全身份在学习《Windows Internals》10.2.10 服务隔离Service isolation这一小节时我觉得它对 Windows 桌面支持、系统服务排障、安全加固都非常有价值。很多人理解 Windows 服务时容易停留在一个比较简单的层面服务运行在LocalSystem、LocalService、NetworkService或某个域账户下面所以服务的权限主要由运行账户决定。这个理解没错但还不够细。因为在真实系统里很多服务可能运行在同一个账户下。如果只靠账户做隔离就会出现一个问题多个服务共享同一个账户身份时系统很难精确区分“到底是哪一个服务”在访问资源。这就引出了 Windows 服务隔离机制中的关键能力Service SID。简单理解Service SID 就是 Windows 为每个服务生成的一种独立安全身份。它可以被加入服务进程的访问令牌中然后被写入文件、注册表、命名管道、互斥体等资源的 ACL 中用来实现更细粒度的访问控制。这一篇文章就围绕Service isolation 服务隔离从概念、原理、Service SID、ACL 授权、桌面支持排障价值几个角度把这一节讲清楚。2. 先说结论服务隔离解决的是“同账户多服务边界不清”的问题Windows 服务经常运行在以下账户下服务账户常见用途风险点LocalSystem高权限系统服务权限极大被滥用风险高LocalService本地低权限服务多个服务可能共享同一身份NetworkService需要网络身份的服务网络访问相关风险更明显域账户企业业务服务凭据、权限、横向访问风险NT SERVICE\ServiceName虚拟服务账户更适合服务级隔离如果只按账户区分服务会出现一个很现实的问题多个服务共用一个账户时系统只能看到“这个账户在访问资源”但不能天然精确区分“具体是哪一个服务”。例如两个服务都运行在LocalService下ServiceA → LocalService ServiceB → LocalService如果某个资源只授予LocalService访问权限那么 ServiceA 和 ServiceB 都可能获得访问能力。这就不是精细化隔离而是账户级粗粒度隔离。Service SID 的价值就在于即使多个服务运行在同一个账户下Windows 仍然可以为每个服务提供一个唯一的服务级安全身份。也就是说隔离粒度从账户级别进一步细化到服务级别这就是服务隔离的核心。3. 为什么仅靠服务账户隔离不够如果一个服务单独使用一个专用账户隔离效果当然更好。但在实际 Windows 系统中服务数量很多如果每个服务都创建一个完整用户账户会带来明显管理成本。因此 Windows 长期存在大量共享账户运行服务的情况例如多个服务运行在LocalSystem多个服务运行在LocalService多个服务运行在NetworkService多个服务托管在同一个svchost.exe进程中这就形成了一个经典矛盾账户越共享管理越简单但安全边界越模糊。3.1 只靠服务账户的典型问题如果只靠服务账户做隔离会带来几个问题身份粒度太粗只能识别账户不能精确识别服务。资源授权不够细资源 ACL 只能写账户不能只授权某个具体服务。横向影响范围大一个服务被利用后攻击者可能借同一账户访问其他资源。审计不够清晰安全日志里可能只看到账户难以判断具体服务来源。所以从安全设计角度看账户身份只能解决“谁运行”Service SID 才能进一步解决“是哪一个服务在运行”。4. 什么是 Service SIDService SID可以理解为 Windows 为服务生成的唯一安全标识符。它的名称形式通常类似NT SERVICE\ServiceName例如NT SERVICE\CryptSvc NT SERVICE\WinDefend NT SERVICE\Spooler它底层对应的 SID 通常类似S-1-5-80-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx其中S-1-5-80表示服务 SID 命名空间后面的长数字通常根据服务名称生成每个服务拥有自己独立的 Service SID。你可以把它理解为服务在 Windows 安全模型中的身份证。4.1 Service SID 和服务账户有什么区别对比项服务账户Service SID表示对象运行服务的账户某一个具体服务粒度账户级服务级是否唯一对应服务不一定是是否适合 ACL 授权可以但较粗更适合精确授权典型形式LocalSystem、NetworkServiceNT SERVICE\CryptSvc主要价值提供运行上下文提供服务级安全身份一句话总结服务账户决定服务“以谁的权限运行”Service SID 决定系统能否“把某个服务单独识别出来”。5. Service SID 是如何参与访问控制的Service SID 最大的价值不是“看起来多了一个身份”而是它可以被用于ACL 访问控制。Windows 中很多资源都可以配置 ACL例如文件夹文件注册表项命名管道事件日志互斥体服务对象其他内核对象如果资源 ACL 中写入某个服务的 Service SID那么就可以做到只允许这个服务访问而不是允许整个账户下的所有服务访问。例如某个服务叫ContosoUpdateSvc可以把某个目录只授权给这个服务icacls C:\ProgramData\Contoso /grant NT SERVICE\ContosoUpdateSvc:(OI)(CI)M含义是NT SERVICE\ContosoUpdateSvc服务身份(OI)(CI)继承到文件和子文件夹MModify 修改权限。这样授权后就可以实现ContosoUpdateSvc 可以访问 其他同账户服务不能随便访问 普通 Users 也不能随便访问这就是服务隔离真正落地的地方。Service SID ACL才是服务隔离真正发挥作用的组合。6. Service SID 在服务启动时是如何进入 Token 的Windows 服务启动时SCM 不只是简单调用CreateProcess。它还会围绕服务账户、Token、Service SID、权限、profile 等信息构造一个完整运行上下文。Service SID 参与的大致流程如下SCM 准备启动服务读取服务配置确定服务账户创建服务进程 Token将 Service SID 注入 Token服务进程启动访问资源时参与 ACL 检查其中关键点是Service SID 必须进入服务进程的访问令牌后续访问资源时才可能被 ACL 识别。访问资源时Windows 的安全检查会综合判断用户 SID组 SIDService SID权限Restricted SID资源 ACL访问类型。所以 Service SID 并不是一个“显示名称”而是实实在在参与安全访问检查的身份元素。7. 如何查看一个服务的 Service SID在 Windows 中可以使用sc showsid查看服务对应的 SID。例如查看CryptSvcsc showsid CryptSvc可能会看到类似结果名称: CryptSvc 服务 SID: S-1-5-80-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx 状态: 已启用也可以查看某个服务的 SID 类型sc qsidtype CryptSvc常见 SID 类型包括SID 类型含义NONE不使用服务 SIDUNRESTRICTED将 Service SID 加入服务 Token可用于 ACL 授权RESTRICTED以更受限制方式参与访问检查隔离更强如果需要配置服务 SID 类型可以使用sc sidtype 服务名 unrestricted例如sc sidtype ContosoUpdateSvc unrestricted如果希望更强隔离可以考虑sc sidtype ContosoUpdateSvc restricted但需要注意修改服务 SID 类型可能影响服务访问资源生产环境必须先测试验证。8. Unrestricted 和 Restricted 有什么区别Service SID 不是只有“有或没有”。它还涉及不同启用模式。8.1 Unrestricted服务 SID 进入 Token用于正常 ACL 授权UNRESTRICTED可以理解为把 Service SID 加入服务进程 Token使资源 ACL 可以识别这个服务。这种模式常用于给某个服务单独授权目录给某个服务单独授权注册表项给某个服务单独授权命名管道让日志和安全审计更容易区分服务来源。它适合大多数服务隔离场景。8.2 Restricted进一步限制服务访问边界RESTRICTED更严格。它不仅让服务拥有 Service SID还会让访问检查更加受限制。通俗理解就是服务访问资源时除了要满足普通账户权限外还要满足受限 SID 相关访问条件。这可以减少服务越权访问资源的机会但也更容易导致服务因为权限不足而异常。所以企业桌面支持中要注意Restricted 更安全但兼容性风险更高Unrestricted 更常用也更适合作为服务级 ACL 授权基础。9. 从桌面支持视角如何理解服务隔离对桌面支持工程师来说服务隔离不是纯内核理论。它和日常排障非常相关。当一个服务访问资源失败时不要只看这个服务是什么账户运行的还要继续看这个服务有没有 Service SID 资源 ACL 有没有授权给这个 Service SID 这个服务是否运行在共享 svchost 中 当前 Token 里到底有哪些 SID 和权限9.1 一个推荐排查思路可以按下面顺序排查确认服务名确认运行账户查看 Service SID确认 SID Type查看资源 ACL检查实际 Token定位访问失败原因9.2 常用排查命令查看服务配置sc qc CryptSvc查看服务 SIDsc showsid CryptSvc查看服务 SID 类型sc qsidtype CryptSvc查看服务对应进程Get-CimInstanceWin32_Service-FilterNameCryptSvc|Select-ObjectName,DisplayName,State,ProcessId,StartName查看某个 svchost 托管哪些服务tasklist /svc /fi imagename eq svchost.exe查看目录 ACLicacls C:\ProgramData\Contoso给服务授权目录访问icacls C:\ProgramData\Contoso /grant NT SERVICE\ContosoUpdateSvc:(OI)(CI)M这些命令组合起来可以帮助我们判断问题到底是服务账户权限不足、Service SID 未启用还是资源 ACL 没有正确授权。10. 服务隔离的核心流程可以把服务隔离理解成 4 个步骤10.1 SCM 启动服务SCM 根据服务配置启动服务进程并确定服务运行账户。10.2 生成服务身份Windows 根据服务名称生成唯一的 Service SID。10.3 注入 Service SIDSCM 将 Service SID 注入服务进程 Token 中。10.4 按 ACL 访问资源服务访问资源时Windows 根据资源 ACL 判断是否允许访问。整体逻辑如下允许拒绝SCM 启动服务确定服务账户生成或加载 Service SIDService SID 注入 Token服务访问资源资源 ACL 是否允许该 Service SID访问成功访问被拒绝这一套流程的最终效果是减少攻击面实现更精细授权降低服务间越权访问风险提高系统安全性和稳定性11. 服务隔离和虚拟服务账户有什么关系这两个概念很容易混在一起但它们不是一回事。概念重点例子Service SID服务的唯一安全身份NT SERVICE\CryptSvc虚拟服务账户服务运行账户的一种形式NT SERVICE\MyService服务隔离使用服务身份限制资源访问ACL 授权给 Service SID虚拟服务账户通常长得也像NT SERVICE\ServiceName所以初学者容易觉得它和 Service SID 是完全同一个东西。更准确地理解是虚拟服务账户解决“服务以什么账户运行”的问题Service SID 解决“如何在访问控制中精确识别某个服务”的问题。在很多场景下它们可以配合使用从而让服务拥有更清晰的身份边界。12. 常见误区服务隔离不是“绝对安全”而是降低影响范围12.1 误区一服务有了 Service SID 就绝对安全不对。Service SID 只是提供服务级身份。它能不能发挥作用还取决于SID 是否启用Token 中是否包含该 SID资源 ACL 是否正确授权服务是否运行在共享进程中是否存在过宽的账户权限。12.2 误区二服务隔离可以替代最小权限运行不对。服务隔离和最小权限运行是互补关系最小权限运行减少服务 Token 中不必要的权限服务隔离让服务拥有独立身份并参与 ACL 控制。两者配合使用效果更好。12.3 误区三只要服务运行在 LocalSystem 下Service SID 就没意义不对。即使服务运行在LocalSystem下Service SID 仍然可以用来做服务级资源授权。例如只允许某个 LocalSystem 服务访问特定目录而不是让所有 LocalSystem 服务都能访问。12.4 误区四共享 svchost 中的服务隔离效果和独立进程完全一样不完全一样。共享进程意味着多个服务共用一个进程 Token。因此在高安全要求场景中需要结合服务是否拆分svchost 分组Service SID权限并集资源 ACL综合判断隔离效果。13. 总结提升如果让我用一句话总结《Windows Internals》10.2.10 服务隔离Service isolation我会这样说Service SID 让 Windows 服务不再只依赖运行账户进行粗粒度隔离而是让每个服务都可以拥有属于自己的安全身份并通过 ACL 对文件、注册表、命名管道等资源进行服务级精确授权。这篇文章最值得记住的 8 个结论是仅靠服务账户隔离粒度比较粗。多个服务共享同一账户时安全边界容易模糊。Service SID 为每个服务提供唯一安全身份。Service SID 可以进入服务进程 Token。资源 ACL 可以直接授权给NT SERVICE\ServiceName。服务隔离可以减少服务间越权访问。桌面支持排障时要同时看账户、Service SID、Token 和资源 ACL。Service SID、最小权限运行、虚拟服务账户、svchost 拆分应结合理解。我觉得这一节真正给我的启发是服务账户决定服务运行在哪个身份基础上Service SID 决定系统能不能把某个服务单独识别并精确授权。这也是从“会看服务”走向“理解 Windows 服务安全模型”的关键一步。下一篇预告下一篇可以继续写《Windows Internals》10.2.11 虚拟服务账户The virtual service account为什么NT SERVICE\ServiceName既不是普通本地用户也不是域账户却能成为服务专属运行身份》这一篇可以继续把虚拟服务账户NT SERVICE\ServiceName服务账户与 Service SID 的区别服务 profileHKCU密码管理企业桌面支持排障价值全部串起来。 返回顶部点击回到顶部