假设攻击者破坏了为约束委派设置的帐户,但没有 SeEnableDelegation 权限。攻击者将无法更改约束 (msDS-AllowedToDelegateTo)。但是,如果攻击者对与目标 SPN 关联的帐户以及另一台计算机/服务帐户拥有 WriteSPN 权限,则攻击者可以临时劫持 SPN(一种称为 SPN 劫持的技术),将其分配给另一台计算机/服务器,并执行完整的 S4U 攻击以破坏它。
此外,如果目标 SPN 当前未与任何帐户关联,则攻击者可以类似地盗用它。
我将首先承认这不是一个开创性的发现,但它可以在特定情况下恢复看似死胡同的攻击路径。如果 RBCD 或影子凭证不可行,SPN 劫持也可以作为替代接管技术。
Kerberos 委托入门
Kerberos 委托是一种允许服务模拟用户到其他服务的机制。例如,用户可以访问前端应用程序,而该应用程序又可以使用用户的身份和权限访问后端 API。
Kerberos 委派有三种形式:无约束委派、约束委派和基于资源的约束委派 (RBCD)。
无约束委派
无约束委派要求用户将他们的票证授予票证 (TGT) 发送到前端服务(服务器 A)。然后前端服务可以使用该票证来模拟用户使用任何服务,包括后端服务(服务器 B)。
约束委派
约束委派允许前端服务(服务器 A)为用户获取 Kerberos 服务票证,以访问由其服务主体名称 (SPN) 指定的预定义服务列表,例如后端服务服务器 B。
请注意,约束委派允许服务凭空模拟用户,无论他们是否通过服务验证。许多人认为这取决于 TrustedToAuthForDelegation 属性的配置。但是,当与基于资源的约束委派链接时,可以绕过该限制,正如我在这篇博文中解释的那样。
基于资源的约束委派
RBCD 与约束委派非常相似,只是约束的方向是相反的。它指定允许谁委托给服务,而不是允许服务委托给谁。换句话说,如果在约束委派中允许服务器 A 委托给服务器 B,则约束将配置在服务器 A 的属性中。在 RBCD 中,它将配置在服务器 B 的属性中。
约束委派和 RBCD 之间的另一个重要区别是约束委派指定目标服务的 SPN。相反,RBCD 在安全描述符中指定原始服务的 SID。
所需权限
配置无约束委派和约束委派需要 SeEnableDelegation 权限,默认情况下,该权限仅授予域管理员。因此,即使用户对 AD 帐户具有完全控制权 (GenericAll),他也无法配置这些 Kerberos 委派类型中的任何一种,除非他还拥有 SeEnableDelegation 权限。与无约束委派和约束委派不同,RBCD 需要更改 msDS-AllowedToActOnBehalfOfOtherIdentity 属性的权限,但不需要特殊权限。
请注意,用户需要特殊权限才能更改约束委派配置,但更改 SPN 不需要特殊权限。因此,从不同的角度处理受约束委派的妥协方案可能会很有趣——操纵 SPN 属性而不是委派配置。
设置舞台
假设环境中有三台服务器:ServerA、ServerB 和 ServerC。ServerA 配置了对某个 SPN 的约束委派。攻击者破坏了 ServerA 和 NotAdmin 帐户,该帐户对环境中的计算机/服务帐户具有 WriteSPN 权限。攻击者的目标是攻破 ServerC。
Ghost SPN 顶升
第一种情况是最简单的。ServerA 配置为对先前与不再存在的计算机或服务帐户关联的 SPN 进行约束委派。它可以是标准 SPN,例如 cifs/主机名,与已删除的计算机/服务帐户或重命名的计算帐户相关联(如果 SPN 已相应更新)。或者,该帐户可能是从计算机/服务帐户中删除的具有非标准服务类的自定义 SPN,或者该帐户本身不再存在。
在这种情况下,攻击者可以将受影响的 SPN 添加到 ServerC,然后使用 ServerA 的帐户运行完整的 S4U 攻击,以获得到 ServerC 的特权用户的服务票证。
该票证的服务名称对于访问 ServerC 无效,因为主机名不匹配,并且服务类可能无用。但是,重要的是票证是为ServiceC加密的,服务名不在票证的加密部分,因此攻击者可以将其更改为有效的。
最后,攻击者可以通过--ticket 攻击ServerC。
攻击链如下图所示:
该攻击在以下屏幕截图中演示:
现场 SPN 顶升
第二种情况有点做作。ServerA 配置为对当前与 ServerB 关联的 SPN 进行约束委派,并且攻击者对 ServerB 和 ServerC 具有 WriteSPN 权限。
在完全修补的环境中,仅允许域管理员配置冲突的 SPN,这意味着 SPN 与两个或多个不同的帐户相关联。因此,如果这种情况下的攻击者试图将目标 SPN 添加到 ServerC,DC 将拒绝该更改,因为它已经与 ServerB 关联。
攻击者可以通过暂时从 ServerB 中删除目标 SPN,然后才将其添加到 ServerC 来绕过该障碍。然后,攻击者可以使用 ServerA 的帐户运行完整的 S4U 攻击,以获取到 ServerC 的特权用户的服务票证。
与前面的场景一样,该票证的服务名称对于访问 ServerC 无效。但是,重要的是,票据是为ServerC加密的,服务名称不在票据的加密部分,所以攻击者可以更改它。
最后,攻击者可以通过--ticket 攻击ServerC。
行为良好的攻击者还应该通过从 ServerC 中删除目标 SPN 并将其恢复到 ServerB 来回滚更改。
攻击链如下图所示:
使用 HOST 服务类进行 SPN 劫持
当目标 SPN 没有明确定义时,它会变得更有趣。默认情况下,计算机帐户具有与服务类 TERMSRV、RestrictedKrbHost 和 HOST 关联的 SPN。如果安装了其他服务,例如 LDAP 或 SQL Server,也会为这些服务添加额外的 SPN。
HOST服务类默认映射到以下服务类: alerter、appmgmt、cisvc、clipsrv、browser、dhcp、dnscache、replicator、eventlog、eventsystem、policyagent、oakley、dmserver、dns、mcsvc、fax、msiserver、ias、信使,netlogon,netman,netdde,netddedsm,nmagent,plugplay,protectedstorage,rasman,rpclocator,rpc,rpcss,remoteaccess,rsvp,samss,scardsvr,scesrv,seclogon,scm,dcom,cifs,spooler,snmp,时间表,tapisrv, trksvr、trkwks、ups、时间、胜、www、http、w3svc、iisadmin、msdtc。
如果攻击者试图针对映射到 HOST 的服务类,域控制器将拒绝将该服务类添加到 ServerC,即使它与 ServerB 没有直接关联。攻击者首先必须从 ServerB 中删除 HOST SPN,然后将目标 SPN 显式添加到 ServerC。然而,在将目标 SPN 添加到 ServerC 后,攻击者可以将 HOST SPN 添加回 ServerB 而不会遇到任何验证错误,尽管已经有与 ServerC 关联的映射 SPN,如下面的屏幕截图所示:
当请求上面屏幕截图中不明确的 SPN、cifs/SERVERB 的服务票证时,域控制器会为 ServerC 而不是 ServerB 发出它。
攻击链如下图所示:
攻击者如何使用 SPN 劫持?
如果攻击者破坏了对计算机帐户具有 GenericAll 或 GenericWrite 权限的帐户,则攻击者可以使用 RBCD 或 Shadow Credentials 破坏关联的主机或服务。我怀疑破坏仅对计算机帐户具有 WriteSPN 权限的帐户的可能性不大。但是,与已经配置了约束委派的主机的危害相联系,攻击者可以在监视或阻止 RBCD 和影子凭据的环境中使用此技术。防御者应遵循以下建议来减轻 SPN 劫持攻击。
检测 SPN-jacking
更改计算机帐户的 ServicePrincipalName 属性会在域控制器上生成 ID 为 4742(计算机帐户已更改)的安全事件。事件详细信息显示更改的属性及其新值。防御者可以检测到主机名与计算机的 DNS 名称不同的 SPN,如下面的屏幕截图所示:
从计算机帐户中删除 HOST 服务类也可能是可疑的。
S4U 攻击生成两个 ID 为 4769 的安全事件(请求了 Kerberos 服务票证)。
第一个事件是针对 S4U2Self。当账号信息和服务信息指向同一个账号时,防御者可以检测到,如下截图所示:
第二个事件是针对 S4U2Proxy。当 Transited Services 属性不为空时,防御者可以检测到它,如下图所示:
防止 SPN 劫持
捍卫者可以采用多种策略来防止此类滥用:
- 定期审核 Active Directory 中指向幽灵 SPN 的约束委派
- 定期审核 Active Directory 的异常 WriteSPN 权限
- 将所有特权帐户添加到受保护的用户组,以阻止任何通过 Kerberos 委派模拟他们的尝试
攻击者可以操纵计算机/服务帐户的 SPN 以将预配置的约束委派重定向到非预期目标,即使没有获得 SeEnableDelegation 权限。
虽然本文中描述的场景并不常见,但当为受限制委派配置受损帐户时,它们可以提供可行的攻击路径,否则将被视为良性或作为 RBCD 和影子凭据的替代方案。
防御者应采取必要措施来检测和防止此类攻击。