本 POC 的灵感来源于 James Forshaw(@tiraniddo)在 BlackHat USA 2022 上分享的题为"Taking Kerberos To The Next Level"的主题演讲,他演示了通过滥用 Kerberos 票据实现 UAC 绕过。通过在服务票据中添加一个 KERB-AD-RESTRICTION-ENTRY,但填入伪造的 MachineID,我们可以轻松绕过 UAC,并通过访问 SCM 创建系统服务来获得 SYSTEM 权限。James Forshaw 在一篇名为 "Bypassing UAC in the most Complex Way Possible!" 的博文中解释了其背后的原理,这让我非常感兴趣。尽管他没有提供完整的漏洞利用代码,但我在 Rubeus 的基础上构建了一个 POC。作为用于原始 Kerberos 交互和票据滥用的 C# 工具集,Rubeus 提供了一个简便的接口,使我们能够轻松发起 Kerberos 请求并操纵 Kerberos 票据。
你可以在我的博客 "Revisiting a UAC Bypass By Abusing Kerberos Tickets" 中看到关于 KRBUACBypass 的相关文章,包括背景原理及其实现方式。正如文章中所说,本文的灵感来源于 @tiraniddo 的 "Taking Kerberos To The Next Level"(没有他的分享我无法完成此工作),而我在大学毕业前将其作为工具实现。
由于我们没有也无法访问当前用户的凭据,因此无法手动生成 TGT。但是,Benjamin Delpy(@gentilkiwi)在他的 Kekeo 中添加了一个技巧(tgtdeleg),允许我们滥用非约束委派来获取带有会话密钥的本地 TGT。
Tgtdeleg 滥用 Kerberos GSS-API,在不获取主机提升权限的情况下获取当前用户的可用 TGT。该方法使用 AcquireCredentialsHandle 函数获取当前用户的 Kerberos 安全凭据句柄,然后调用 InitializeSecurityContext 函数,针对 HOST/DC.domain.com 使用 ISC_REQ_DELEGATE 标志和目标 SPN,准备伪委派上下文以发送给域控制器。这导致 GSS-API 输出中的 KRB_AP-REQ 在 Authenticator 校验和中包含 KRB_CRED。然后从本地 Kerberos 缓存中提取服务票据的会话密钥,用于解密 Authenticator 中的 KRB_CRED,从而获得可用的 TGT。Rubeus 工具集也整合了此技术。详细信息请参考 "Rubeus – Now With More Kekeo".
有了这个 TGT,我们可以生成自己的服务票据,可行操作流程如下:
KERB-AD-RESTRICTION-ENTRY,但填入伪造的 MachineID。一旦拥有服务票据,就可以使用 Kerberos 身份验证通过 HOST/HOSTNAME 或 RPC/HOSTNAME SPN 访问服务控制管理器(SCM)命名管道或 TCP。请注意,SCM 的 Win32 API 始终使用 Negotiate 身份验证。James Forshaw 创建了一个简单的 POC:SCMUACBypass.cpp,通过 Hook 两个 API——AcquireCredentialsHandle 和 InitializeSecurityContextW,将 SCM 调用的身份验证包名称(pszPackage)改为 Kerberos,从而使 SCM 在本地身份验证时使用 Kerberos。
更多详情请阅读:
现在让我们看一下运行效果,如下图所示。首先通过 asktgs 函数为当前服务器的 HOST 服务请求一个票据,然后通过 krbscm 创建一个系统服务以获得 SYSTEM 权限。
KRBUACBypass.exe asktgs
KRBUACBypass.exe krbscm
