以下文章来源于安全加 ,作者谢公子
作者:谢公子
SPN
SPN(ServicePrincipal Names)服务主体名称,是服务实例(比如:HTTP、SMB、MySQL等服务)的唯一标识符。
Kerberos认证过程使用SPN将服务实例与服务登录账户相关联,如果想使用 Kerberos 协议来认证服务,那么必须正确配置SPN。如果在整个林或域中的计算机上安装多个服务实例,则每个实例都必须具有自己的 SPN。如果客户端可能使用多个名称进行身份验证,则给定服务实例可以具有多个SPN。SPN 始终包含运行服务实例的主机的名称,因此服务实例可以为其主机的每个名称或别名注册SPN。一个用户账户下可以有多个SPN,但一个SPN只能注册到一个账户。在内网中,SPN扫描通过查询向域控服务器执行服务发现。这对于红队而言,可以帮助他们识别正在运行重要服务的主机,如终端,交换机等。SPN的识别是kerberoasting攻击的第一步。
♬..♩~ ♫. ♪ ~ ♬..♩..♩~ ♫. ♪ ~ ♬..♩..♩~ ♫. ♪ ~ ♬..♩..♩~ ♫. ♪ ~ ♬..♩
♫. ♪ ~ ♬..♩~ ♫. ♪..♩~ ♫. ♪ ~ ♬..♩..♩~ ♫. ♪ ~ ♬..♩..♩~ ♫. ♪ ~ ♬..♩
下面通过一个例子来说明SPN的作用:
当某用户需要访问MySQL服务时,系统会以当前用户的身份向域控查询SPN为MySQL的记录。当找到该SPN记录后,用户会再次与KDC通信,将KDC发放的TGT作为身份凭据发送给KDC,并将需要访问的SPN发送给KDC。KDC中的TGS服务对TGT进行解密。确认无误后,由TGS将一张允许访问该SPN所对应的服务的ST服务票据和该SPN所对应的服务的地址发送给用户,用户使用该票据即可访问MySQL服务。
SPN分为两种类型:
1.一种是注册在活动目录的机器帐户(Computers)下,当一个服务的权限为 Local System 或 Network Service,则SPN注册在机器帐户(Computers)下。域中的每个机器都会有注册两个2.SPN:HOST/主机名 和 HOST/主机名.xie.com
另一种是注册在活动目录的域用户帐户(Users)下,当一个服务的权限为一个域用户,则SPN注册在域用户帐户(Users)下。
这里以SQLServer服务注册为例:
SQLServer在每次启动的时候,都会去尝试用自己的启动账号注册SPN。但是在Windows域里,默认普通机器账号有权注册SPN,但是普通域用户账号是没有权注册SPN的。这就会导致这样一个现象,SQL Server如果使用“Local System account”来启动,Kerberos就能够成功,因为SQL Server这时可以在DC上注册SPN。如果用一个域用户来启动,Kerberos就不能成功,因为这时SPN注册不上去。
解决办法:
- 可以使用工具SetSPN -S来手动注册SPN。但是这不是一个最好的方法,毕竟手工注册不是长久之计。如果SPN下次丢了,又要再次手动注册。
- 所以比较好的方法,是让SQL Server当前启动域账号有注册SPN的权力。要在DC上为域账号赋予 “Read servicePrincipalName” 和 “Write serverPrincipalName” 的权限即可。
SPN的配置
微软官方文档:https://docs.microsoft.com/zh-cn/windows-server/networking/sdn/security/kerberos-with-spn
在 SPN 的语法中存在四种元素,两个必须元素和两个额外元素,其中 <service class> 和 <host> 为必须元素:
代码语言:javascript复制SPN格式:<service class>/<host>:<port>/<service name>
<service class>:标识服务类的字符串,可以理解为服务的名称,常见的有WWW、MySQL、SMTP、MSSQL等;必须元素
<host>:服务所在主机名,host有两种形式,FQDN(win7.xie.com)和NetBIOS(win7)名;必须元素
<port>:服务端口,如果服务运行在默认端口上,则端口号(port)可以省略;额外元素
<service name>:服务名称,可以省略;额外元素
一些服务的SPN示例:
#Exchange服务
exchangeMDB/ex01.xie.com
#RDP服务
TERMSERV/te01.xie.com
#WSMan/WinRM/PSRemoting服务
WSMAN/ws01.xie.com
使用SetSPN注册SPN
SetSPN是一个本地Windows二进制文件,可用于检索用户帐户和服务之间的映射。该实用程序可以添加,删除或查看SPN注册。
- 主机:win7.xie.com
- 域控:win2008.xie.com
- 当前用户:xie/test
注:注册SPN需要域管理员权限,普通域成员注册会提示权限不够!
以test用户的身份进行SPN服务的注册
代码语言:javascript复制setspn -S SQLServer/win7.xie.com:1433 test #test必须是当前的用户
或
setspn -U -A SQLServer/win7.xie.com:1433 test #test必须是当前的用户
以WIN7主机的身份在DC(win2008.xie.com)上进行SPN服务(SQLServer)的注册
代码语言:javascript复制setspn -S SQLServer/win7.xie.com:1533/MSSQL win7 #win7必须是当前的主机名
这里由于之前用 test 用户注册过,所以会提示重复,我们可以将端口修改为其他端口,则不是重复的SPN了
SPN的发现
由于每台服务器都需要注册用于Kerberos身份验证服务的SPN,因此这为在不进行大规模端口扫描的情况下收集有关内网域环境的信息提供了一个更加隐蔽的方法。
使用SetSPN查询:
windows系统自带的setspn可以查询域内的SPN。
代码语言:javascript复制查看当前域内所有的SPN:setspn -Q */*
查看指定域xie.com注册的SPN:setspn -T xie.com -Q */* 如果指定域不存在,则默认切换到查找本域的SPN
查找本域内重复的SPN:setspn -X
删除指定SPN:setspn -D MySQL/win7.xie.com:1433/MSSQL hack
查找指定用户/主机名注册的SPN:setspn -L username/hostname
PowerShell-AD-Recon:
该工具包提供了一些探测指定SPN的脚本,例如Exchange,Microsoft SQLServer,Terminal等
代码语言:javascript复制#Discover-PSMSSQLServers.ps1的使用,扫描MSSQL服务
Import-Module .Discover-PSMSSQLServers.ps1;Discover-PSMSSQLServers
#Discover-PSMSExchangeServers.ps1的使用,扫描Exchange服务
Import-Module .Discover-PSMSExchangeServers.ps1;Discover-PSMSExchangeServers
#扫描域中所有的SPN信息
Import-Module .Discover-PSInterestingServices.ps1;Discover-PSInterestingServices
GetUserSPNs.ps1:
GetUserSPNs 是 Kerberoast 工具集中的一个 powershell 脚本,用来查询域内用户注册的 SPN。
代码语言:javascript复制Import-Module .GetUserSPNs.ps1
GetUserSPNs.vbs:
GetUserSPNs 是 Kerberoast 工具集中的一个 vbs 脚本,用来查询域内用户注册的 SPN。
代码语言:javascript复制cscript .GetUserSPNs.vbs
PowerView.ps1:
PowerView是 PowerSpolit 中 Recon目录下的一个powershell脚本,PowerView 相对于上面几种是根据不同用户的 objectsid 来返回,返回的信息更加详细。
代码语言:javascript复制Import-Module .PowerView.ps1
Get-NetUser -SPN
PowerShellery:
PowerShellery下有各种各样针对服务SPN探测的脚本。其中一些需要PowerShell v2.0的环境,还有一些则需要PowerShell v3.0环境。
代码语言:javascript复制#Powershellery/Stable-ish/Get-SPN/ 下Get-SPN.psm1脚本的使用,需要powershell3.0及以上版本才能使用
Import-Module .Get-SPN.psm1
Get-SPN -type service -search "*"
Get-SPN -type service -search "*" -List yes | Format-Table
#Powershellery/Stable-ish/ADS/ 下Get-DomainSpn.psm1脚本的使用
Import-Module .Get-DomainSpn.psm1
Get-DomainSpn
RiskySPN中的Find-PotentiallyCrackableAccounts.ps1:
该脚本可以帮助我们自动识别弱服务票据,主要作用是对属于用户的可用服务票据执行审计,并根据用户帐户和密码过期时限来查找最容易包含弱密码的票据。
代码语言:javascript复制Import-Module .Find-PotentiallyCrackableAccounts.ps1;Find-PotentiallyCrackableAccounts -FullData -Verbose
该脚本将提供比klist和Mimikatz更详细的输出,包括组信息,密码有效期和破解窗口。
使用domain参数,将返回所有具有关联服务主体名称的用户帐户,也就是将返回所有SPN注册在域用户下的用户。
代码语言:javascript复制Import-Module .Find-PotentiallyCrackableAccounts.ps1;Find-PotentiallyCrackableAccounts -Domain "xie.com"