PS: 这篇文章是学习域委派的一个小小的前置知识。

# SPN 是什么?

SPN (ServicePrincipal Names) 服务主体名称,是服务实例 (比如:HTTP、SMB、MySQL 等服务) 的唯一标识符。
Kerberos 认证过程使用 SPN 将服务实例与服务登录账户相关联,如果想使用 Kerberos 协议来认证服务,那么必须正确配置 SPN。(回忆 kerberos 协议,用户拿着 ST 去访问服务是什么?其实不是目标机器,而是 SPN)
如果在整个林或域中的计算机上安装多个服务实例,则每个实例都必须具有自己的 SPN。如果客户端可能使用多个名称进行身份验证,则给定服务实例可以具有多个 SPN。SPN 始终包含运行服务实例的主机的名称,因此服务实例可以为其主机的每个名称或别名注册 SPN。一个用户账户下可以有多个 SPN,但一个 SPN 只能注册到一个账户。在内网中,SPN 扫描通过查询向域控服务器执行服务发现。这对于红队而言,可以帮助他们识别正在运行重要服务的主机,如终端,交换机等。SPN 的识别是 kerberoasting 攻击的第一步。

下面通过一个例子来说明 SPN 的作用
当某用户需要访问 MySQL 服务时,系统会以当前用户的身份向域控查询 SPN 为 MySQL 的记录。当找到该 SPN 记录后,用户会再次与 KDC 通信,将需要访问的 SPN 发送给 KDC。由 TGS 将一张允许访问该 SPN 所对应的服务的 ST 服务票据和该 SPN 所对应的服务的地址发送给用户,用户使用该票据即可访问 MySQL 服务。(kerberos 最终访问服务那个阶段)
从这个例子也可以看出,其实 SPN 的存在就是分权,让一个具体的服务成为了一个角色有了权限。

# SPN 格式

SPN = serviceclass/hostname:port/servicename
serviceclass:服务组件的名称
hostname:以”/” 与后面的名称分隔,是计算机的 FQDN (全限定域名,同时带有计算机名和域名)。
port:以冒号分隔,后面的内容为该服务监听的端口号。
servicename:一个字符串,可以是服务的专有名称 (DN)、objectGuid、Internet 主机名或全限定域名。

  • MSSQLSvc/computer1.pentest.com:1443 # MSSQL 服务
  • exchangeMDB/computer1.pentest.com # Exchange 服务
  • TERMSRV/EXCAS01.pentest.com #RDP 服务
  • WSMAN/EXCAS01.pentest.com # WSMan/WinRM/PSRemoting 服务

image-20220617162251696

# SPN 分类

SPN 分为两种类型:

  • 一种是注册在活动目录的机器帐户 (Computers) 下,当一个服务的权限为 Local System 或 Network Service,则 SPN 注册在机器帐户 (Computers) 下。域中的每个机器都会有注册两个 SPN:HOST / 主机名 和 HOST / 主机名.ruyue.com(域名)
  • 另一种是注册在活动目录的域用户帐户 (Users) 下,当一个服务的权限为一个域用户,则 SPN 注册在域用户帐户 (Users) 下。

但是在 Windows 域里,默认普通机器账号有权注册 SPN,但是普通域用户账号是没有权注册 SPN 的。这就会导致这样一个现象,由于 SQLServer 在每次启动的时候,都会去尝试用自己的启动账号去注册 SPN。SQL Server 如果使用 “Local System account” 来启动,Kerberos 认证就能够成功,因为 SQL Server 这时可以在 DC 上注册 SPN。如果用一个域用户来启动,Kerberos 认证就不能成功,这就导致 SPN 注册不上去。

image-20220617162534384

# 关于 SPN 的命令

# 查询 SPN

由于每台服务器都需要注册用于 Kerberos 身份验证服务的 SPN,因此这为在不进行大规模端口扫描的情况下收集有关内网域环境的信息提供了一个更加隐蔽的方法。

查看当前域内所有的 SPN:setspn -Q /
查看指定域 xie.com 注册的 SPN:setspn -T xie.com -Q / 如果指定域不存在,则默认切换到查找本域的 SPN
查找本域内重复的 SPN:setspn -X
查找指定用户 / 主机名注册的 SPN:setspn -L username/hostname

image-20220617162645699

# 注册 SPN

注册 SPN 需要域管理员权限

setspn -s <service>/<computername>.<domainname> <domain-user-account>
setspn -s 服务名/机器名.域名 域用户(主机名)

PS:SPN 的名称是服务名 / 机器名。域名这一段,这一段不能和其他的重复

image-20220617162722250

image-20220617162725420

# 删除 SPN

其实就是把注册的 - s 参数换成 - d

setspn -d testSPN/888.ruyue.com momo

image-20220617162755151