红队面试提及过

前言

服务主体名称,是kerberos客户端用于唯一标识给特定kerberos目标计算机的服务实例名称。
kerberos身份验证使用SPN将服务实例与服务登录帐号相关联
如果在整个林中的计算机安装多个多个服务实例,则每个实例都需要具有自己的SPN。如果客户端可能使用多个名称进行身份验证,则给定的服务实例可以具有多个SPN

windows域环境是基于微软的活动目录服务工作的,它在网络系统环境中将物理位置分算,所属部门不同的用户进行分组,集中资源,有效地对资源访问控制权限进行细粒度的分配,提高了网络环境的安全性及网络资源的统一分配的管理的便利性 在域环境中运行大量应用包含了多种资源,为资源的合理分配,分类和再分配提供了便利,微软提供给域内的每种资源分配了不同的服务主机名称(SPN)

本质

域内各种服务资源的对应关系
如对应的服务类型是什么,机器名是多少,服务端口是多少
借助SPN可以快速定位当前目标域中所有存活的各类服务

类型

  1. 当服务的权限为Local system或Network Service,则SPN注册在域内机器帐户(Computers)下

image.png

  1. 当一个服务的权限为一个域用户,则SPN注册在域内用户帐户(Users)下

image.png

  1. 当计算机加入域中,主SPN会自动添加到域的计算机帐号的ServicePrincipalName属性中,在安装新的服务后
  2. SPN也会被记录在计算机帐号的相应属性中

在使用kerberos协议进行身份验证的网络,必须有一个内置帐号(NetworkService LocalSystem)或者用户帐号下为服务器注册SPN 对于内置帐号,SPN将自动进行注册 但是如果在域用户下运行服务,则必须为要使用的帐号手动注册SPN。因为域环境中每台服务器都需要在kerberos身份验证服务中注册SPN,所以攻击者会直接向域控制器发送查询请求,获取其需要的服务的SPN,从而知晓其需要使用的服务资源在那台机器上

特点

通过SPN,可快速定位开启了关键服务的机器,这样就不需要去扫对应服务的端口,有效规避了端口扫描动作,隐蔽性好

原理

LDAP协议全称是Lightweight Directory Access Protocol[轻量目录访问协议]
通俗可以理解为一个关系型数据库,其中存储了域内主机的各种信息

在域控中默认安装有ADSI编辑器,它是ldap编辑器 可以通过在域控中运行adsiedit.msc来打开

SPN查询实际上就是查询LDAP中存储的内容

SPN格式

  1. SPN=serviceclass "/" hostname[":"port] ["/" servicename]
  2. 服务组件名称 全限定域名 该服务监听的端口 一个字符串
  3. 同时带有计算机名和域名
  4. #MSSSQL服务
  5. MSSQLSvc/computer1.pentest.com:1443
  6. #Exchange服务
  7. exchangeMDB/computer1.pentest.com
  8. #RDP服务
  9. TERMSRV/EXCAS01.pentest.com
  10. #WSMan/WinRM/PSRemoting服务
  11. WAMAN/EXCAS01.pentest.com
  12. ldap/WIN-6BCSA1ED2BP.cate4cafe.com(:port)/CATE4CAFE
  13. 服务类/FQDN 端口/服务名
  14. 其中服务类和FQDN(对应机器名)是必须参数,端口和服务名是可选的

SPN扫描

又称之为”扫描kerberos服务实例名称”,在活动目录中发现服务的最佳方法
SPN扫描通过请求特定SPN类型的服务主机名称来查找服务。
因为SPN查询是kerberos票据行为的一部分,所以检测难度大

实战

系统自带的查找和设置SPN的命令

  1. setspn -l
  2. 参数接受计算机名或者用户名
  3. setspn -q */*
  4. 查询当前域下的所有SPN
  5. setspn -T KAIXIN -q */*
  6. 指定域
  7. setspn -T KAIXIN.COM -Q */* | findstr "MSSQLSvc"

image.png

image.png

我们可以将其下载出来查看主机名

  1. grep "CN=" name.txt | awk -F "," {'print $1'} | awk -F "=" {'print $2'}

image.png
image.png
这样横向的时候,可以横向更有价值的目标了

为域机器或者域用户创建SPN

  1. setspn -S <service>/<computername>.<domainname> <domain-user-account>
  2. setspn -S 服务器/机器名.域名 域用户

工具

  1. 1.GetUserSPNs.ps1