突破 windows session 0 隔离

1,062 阅读2分钟

“Session 0 隔离” 是什么?

在Windows XP、Windows Server 2003 或早期Windows 系统时代,当第一个用户登录系统后 服务(Service)应用程序(Application) 是在同一个Session 中运行的(即session 0)。

这种方式显而易见的有很高的风险,“非法”的应用程序能够轻而易举的干扰甚至破坏系统服务的正常运行。

因此从Vista 开始 Session 0 中只包含系统服务,其他应用程序则通过分离的Session 运行,将服务与应用程序隔离提高系统的安全性。

session 0 - 1.png

“Session 0 隔离”导致的问题

在真实业务中,我们的 A服务 部署是依赖公司提供的集成发布平台。在该平台 windows类型的应用发布是借助 Saltstack工具完成的。由于配置的关系 Saltstack 会以 session 0 去启动A服务;同时作为A服务创建的 子进程 K 也会以 session 0 启动的。

企业微信截图_20221108193726.png

而运行 K 所需的各种环境依赖(比如 GPU相关驱动),都是通过远程桌面登录手动安装的(session 1)。因此在 A 服务去启动 K 进程时,会出现启动失败。

若是通过远程桌面手动启动 A 服务,那么 A 服务和 K 进程就会变成session 1启动。能够正常运行。

突破 Session 隔离

在不考虑安全性的前提下,解决上面遇到的问题就变成了怎么将 A 服务以session 1去启动?

  1. 最简单的方法就是去调整Saltstack与节点连接的配置,调整为session 1。
  2. 另外在谷歌上搜索相关的文章,确实有大神给出了解决方案:穿透Session 0隔离

由于改变平台侧的配置会有很多的隐形成本,所以决定从修改服务的启动方式上做调整。即在session 0 中新建用户会话 session 1 再启动服务。

因此 A 服务的启动脚本如下:

function StartService {
    # 使用新用户登陆并调用执行计划 
    $pw = convertto-securestring -AsPlainText -Force -String $env:USER_PSD 
    $username = -Join($env:COMPUTERNAME,"\",$env:USER_ID) 
    $cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $username,$pw 
    $session = new-pssession -credential 
    $cred Invoke-Command -Session $session -ScriptBlock {Get-ScheduledTask -TaskName 'A' | Start-ScheduledTask} -AsJob 
}

不关键的扩展信息

由于使用的 Saltstack工具 还有一个特殊的配置:如果在部署脚本中直接运行 java -jar会阻塞进程,导致salt无法获取返回值,而超时报错。

因此在启动脚本中并没有执行java -jar 直接启动 java 服务,而是通过触发计划任务,曲线救国。

image2022-11-2_17-2-38.png

参考文档

  1. www.cnblogs.com/gnielee/arc…