有时您希望手动与运行服务帐户的 shell 交互。为 SYSTEM 获得一个工作的交互式 shell 非常容易。作为管理员,选择一个以 SYSTEM 身份运行的具有适当访问令牌的进程(例如services.exe)并使用它作为父进程生成一个子进程。只要您指定一个交互式桌面,例如 WinSta0Default,那么新进程将自动分配给当前会话,您将获得一个可见窗口。
为了使这更容易,NtObjectManager实现了Start-Win32ChildProcess命令,其工作方式如下:
PS> $p = Start-Win32ChildProcess powershell
现在,您将看到一个带有 PowerShell 副本的控制台窗口。如果您想生成本地服务或网络服务怎么办?您可以尝试以下操作:
PS> $user = Get-NtSid -KnownSid LocalService
PS> $p = Start-Win32ChildProcess powershell -User $user
进程启动,但是您会发现它立即死亡:
PS> $p.ExitNtStatus
STATUS_DLL_INIT_FAILED
错误代码 STATUS_DLL_INIT_FAILED基本上意味着初始化失败。追踪这一点在背后是一件痛苦的事,尤其是在诸如WinDBG之类的调试器通常控制进程之前发生故障时。您可以启用 Create Process 事件过滤器,但您仍然需要追踪它失败的原因。
我会为您省去痛苦,运行交互式服务进程的问题是本地服务/网络服务令牌无权访问会话的桌面/窗口站/BaseNamedObjects 等。它适用于 SYSTEM,因为该帐户几乎总是通过 SYSTEM 或 Administrators SID 被授予对所有内容的完全访问权限,但低特权服务帐户却没有。
解决此问题的一种方法是找到所有可能的安全资源并添加服务帐户。这不是很可靠,错过一个资源,它可能仍然无法工作,或者它可能在某个不确定的时间失败。相反,我们做操作系统所做的事情,我们需要使用登录会话 SID 创建服务令牌,这将授予我们访问会话资源的权限。
首先使用Start-Win32ChildProcess命令 在当前桌面上创建一个 SYSTEM powershell命令。接下来获取当前会话令牌:
PS> $sess = Get-NtToken -Session
我们现在可以打印出登录会话 SID,感兴趣:
PS> $sess.LogonSid.Sid
Name Sid
---- ---
NT AUTHORITY LogonSessionId_0_41106165 S-1-5-5-0-41106165
现在使用以下命令创建本地服务令牌(或网络服务、IUser 或任何服务帐户):
PS> $token = Get-NtToken -Service LocalService -AdditionalGroups $sess。 LogonSid.Sid
您现在可以使用以下命令在当前桌面上创建交互式进程:
PS> New-Win32Process cmd -Token $token -CreationFlags NewConsole
你应该发现它现在可以工作了:-)