一、Kerberos协议介绍
Kerberos是一种由MIT(麻省理工大学)提出的一种网络身份验证协议。它旨在通过使用密钥加密技术为客户端/服务器应用程序提供强身份验证。该认证过程的实现不依赖于主机操作系统的认证,无需基于主机地址的信任,不要求网络上所有主机的物理安全,并假定网络上传送的数据包可以被任意地读取、修改和插入数据。在以上情况下, Kerberos 作为一种可信任的第三方认证服务,是通过传统的密码技术(如:共享密钥)执行认证服务的。可以用于防止窃听、防止重放攻击、保护数据完整性等场合,是一种应用对称密钥体制进行密钥管理的系统。
Kerberos认证
1)Kerberos相关概念
在Kerberos协议中主要是有三个角色的存在:
1.访问服务的客户端Client(以下表述为Client 或者用户)
2.提供服务的Server(以下表述为服务),如HTTP服务,SQL服务。
3.密钥颁发中心(Key Distribution Center,KDC),默认安装在DC (域控制器)上,是Kerberos的主要服务,由AS和TGS组成。在Kerberos中Client是否有权限访问Server端的服务由KDC发放的票据来决定。
2)kerberos认证过程
1.AS_REQ阶段,这个阶段中客户端向KDC发起请求,凭据是客户端用户哈希加密的时间戳,KDC使用保存的用户哈希进行解密,如果解密成功则证明凭证正确
2.AS_REP阶段中返回用krbtgt哈希加密的TGT票据,里面包含了PAC,PAC中包含了用户的SID和所在组等信息。
3.TGS_REQ 阶段中,客户端凭借拿到的TGT向KDC发起请求,KDC使用krbtgt哈希进行解密,如果结果正确,就会进行TGS_REP阶段。
4.TGS_REP阶段返回用所请求服务哈希加密的TGS票据,这一步不管用户有没有访问目标服务的权限,只要TGT正确,都会返回TGS。
5.AP_REQ 阶段,用户已经拥有一个有效的 TGS 来与服务进行交互,客户端拿着TGS 去请求服务。
6.AP-REP 阶段服务使用自己的哈希解密票据,如果解密正确,就会拿着PAC去KDC那边问客户端有没有访问权限,这个时候域控解密PAC,查看里面客户端包含的SID和组信息,同时和服务的ACL进行对比,判断有没有权限,最后返回结果。
二、Kerberos攻击面
1)AS-Reproasting
1.原理
AS-REP Roasting是一种对用户账号进行离线爆破的攻击方式。但是该攻击方式利用比较局限,因为其需要用户账号设置 "Do not require Kerberos preauthentication(不需要kerberos预身份验证) " 。而该属性默认是没有勾选上的。
预身份验证是Kerberos身份验证的第一步(AS_REQ & AS_REP),它的主要作用是防止密码脱机爆破。默认情况下,预身份验证是开启的,KDC会记录密码错误次数,防止在线爆破。当关闭了预身份验证后,攻击者可以使用指定用户去请求票据,此时域控不会作任何验证就将 TGT票据 和 该用户Hash加密的Session Key返回,接下来可以使用hashcat对其破解,最终获得该用户的明文口令。
2.攻击利用
使用powerview来查询关闭了预身份认证的用户。
Import-Module .\powerview.ps1Get-DomainUser -PreauthNotRequired
使用ASREPRoast.ps1脚本来发送as-rep请求,并将结果储存在txt文件中。
Import-Module .\ASREPRoast.ps1 Get-ASREPHash -UserName yyh -Domain test19.local | Out-File -Encoding ASCII hash.txt
在$krb5asrep后面添加$23拼接,目的是让hashcat识别。
hashcat.exe -m 18200 hash.txt 密码.txt --force
2)Kerberoasting
Kerberoasting攻击是域攻击的常用方法之一,是一种针对域口令攻击方法。Kerberoasting利用Kerberos协议请求访问某服务时存在的一个缺陷进行攻击。
1.原理
当域内用户去请求域内某个服务资源时,先会通过AS进行身份认证,通过后会返回一个用用户密码hash加密的TGT给用户,用户拿着TGT向TGS去请求,TGS会返回一个用对应服务账号的密码hash加密过的专门用于访问特定服务的服务票据回来,只要用户提供的票据正确,服务就会返回自身hash加密的TGS票据。那么如果我们有一个域用户,就可以申请服务的TGS票据,本地爆破服务hash得到服务密码,Kerberos协议使用的加密可以使用y=f(x,key)来表示,算法f为已知的对称加密算法如rc4_hmac_nt,密钥key为ntlm值,待加密数据x为用户名,主机IP,和当前时间戳等,当获取到y即加密后的数据(tgs票据),即可爆破密钥,密钥越简单,被破解的几率越大,这个过程叫做Kerberoasting。
2.关键点
Kerberosting需要选择简单的key,在三种爆破对象中,也就是用户账户,机器账户,服务账户,在比较安全的域中用户账户的安全性会比较高,而机器账户密码是随机生成的,而且三十天更换一次,只有服务账户会出现弱口令的情况,因为在服务部署的时候往往会产生一个固定密码,而且可能从来不去改,所以优先选择服务账户,机器账户也是特殊的服务账户,因为它也有SPN,SPN是唯一标识符,就像下图中的格式,可以理解为代表了特定的服务,SPN只要符合格式,不管服务存不存在都可以用来进行密码爆破。加密方式的话肯定选择越简单越好,我们一般选择rc4加密。
3.攻击利用
选择查询服务账户的工具,可以使用系统内置的setspn,powerview也有一样的功能,执行查询命令只需要普通权限就可以。
setspn.exe -q / setspn.exe -T only -q / #指定域控
得到目标后使用一款工具去请求票据,比如图中的mimikatz工具,运行结果保存在了.kirbi中。
kerberos::ask /target:MSSQLSvc/sql.test.local:1433 /export
使用kerberoast工具包的 tgsrepcrakc.py脚本枚举,破解的概率和时间取决于口令复杂度以及字典和机器的性能。
python tgsrepcrakc.py 密码.txt 票据.kirbi
3)用户名枚举和密码爆破
1.原理
用户名枚举这个方法就是用来进行信息收集,获取用户名单。在AS-REQ阶段中,数据包cname的值是用户名,当用户不存在时,会提示错误,存在时,虽然密码不正确还是返回错误,AS-REP返回包中是不一样的。
KRB5DC_ERR_PREAUTH_REQUIRED 需要额外的预认证(用户存在)
KRB5DC_ERR_CLIENT_REVOKED 客户端凭证已被吊销(禁用 )
KRB5DC_ERR_C_PRINCIPAL_UNKNOWN 在Kerberos数据库中找不到客户端(不存在)
kerbrute_windows_amd64.exe userenum --dc 域控ip -d 域名 用户名字典.txt
4)密码爆破
1.原理
密码爆破时,如果爆破成功会产生AS-REP而不是报错,因为爆破次数过多会出现账号锁定,所以可以在采用密码喷洒的方式,使用同一个密码来爆破账号。
kerbrute_windows_amd64.exe passwordspray --dc 域控ip -d 域名 用户名字典.txt 固定密码
5)MS14-068
1.原理
MS14-068是一个非常严重的洞,因为利用它可以从任意用户提升到域管。这个漏洞的原理的关键在于KDC没有正确检查PAC的签名,也就是特权属性证书,这里说的签名就是PAC的服务检验和 以及KDC校验和,签名原本需要checksum算法,也就是必须用到key,我们没有krbtgt和服务的哈希,按理说没办法生成有效的签名,但这里却允许使用所有的checksum算法包括MD5,我们只需要把pac进行MD5,就能生成新的校验和。因此可以随意更改PAC的内容,回想之前的kerberos认证过程,kdc检查了PAC中的SID和组来判断权限,我们在下面这个kerb-validation-info结构中改掉user id和group id,之后再用md5 给他生成一个服务检验和以及KDC校验和,也就是伪造了PAC,从而实现权限提升,这是MS14-068的关键。
域用户(513)
域管理员(512)
架构管理员(518)
企业管理员(519)
组策略创建者所有者(520)
使用EXP去伪造一个票据,然后将票据注入到会话中,就完成了权限提升。
6)约束委派与非约束委派
1.原理
委派是Kerberos中的功能,允许一个账号模拟另一个账号来访问资源,也就是将域账号的权限委派给服务账号,使服务账号能模拟域账号的权限开展域内活动。委派分为非约束委派,约束委派,基于资源的约束委派,比如图中设置了非约束委派。
而这个图中设置了约束委派,他们两个的区别就是一个可以访问任意服务,一个只能访问特定服务,而且非约束委派仅支持Kerberos,约束委派还支持ntlm认证服务的场景。
微软为了支持委派场景,加入了S4U协议,包含S4U2Self和S4U2Proxy两个子协议,self用于访问自身服务,proxy访问其他服务。当设置了约束委派后userAccountControl包含TrustedToAuthenticationForDelegation字段,msDS-AllowedToDelegateTo被设置了哪些协议可以被委派。这时候我们可以想象一个场景,假如一个服务A的userAccountControl被设置了约束委派,msDS-AllowedToDelegateTo也被设置了可以被委派的协议,那么服务a可以先通过Self协议获取管理员访问它自身的TGS,然后服务A使用Proxy协议获取管理员访问msDS-AllowedToDelegateTo中设置的服务B的TGS票据。
使用工具先请求TGT,然后用TGT请求S4U协议的TGS,可见同时获取了S4U2Self和S4U2Self的TGS。
tgt::ask /user:test1 /domain:test.local /password:1qaz2WSX3edc /ticket:test1.kirbi
tgs::s4u /tgt:- /user:[email protected] /service:cifs/WIN-47FOF3S663D.test.local
之后将proxy的票据注入到会话中,也获取到了目标权限。这里设置的是cifs的委派,所以可以使用dir到域控。
kerberos::ptt 票据名(s4u2proxy协议请求的票据非s4uself协议)
7)基于资源的约束委派
1.原理
还有一种委派叫做基于资源的约束委派,属于约束委派的一种,他们之间的不同是约束委派需要在同一域中进行,而基于资源的约束委派可以在前端WEB和后端SQL之前等都能进行工作,不过他们最关键的区别是就像左图中一样,约束委派是被设置在前端服务上,服务a的委派目标设置为后端资源服务b,表示在前端服务a上打开了到后端资源服务b的约束委派,而基于资源的约束委派是后端资源服务B的委派指向了服务a,表示在后端资源服务B上打开了到前端服务A的约束委派。
这里会造成一个常用的攻击手法,攻击者在打下公司专门用来加域的账户后,同时把这个账户加过域的机器全部拿下了。原理是,加域账户有权限修改它加过域的机器的资源约束委派指向的值,攻击者将这些机器属性全部设置为服务a,也就是允许服务a利用S4U协议模拟域管身份来访问这些机器,从而实现了权限提升。
8)黄金票据
1.原理
黄金票据是一种权限维持手法,当拥有了黄金票据就可以持续拥有域管理员权限,或者其他任意用户权限。,在Kerberos认证中,客户端通过as认证后,会给客户端一个个Logon Session Key和TGT,,Logon Session Key并不会保存在kdc中,krbtgt的NTLM哈希又是固定的,所以只要得到krbtgt的NTLM哈希,就可以伪造TGT和Logon Session Key来进行tgs的交互,当伪造了金票之后,就可以跳过as认证,不需要验证账号和密码了,所以也不担心域管改密等情况。如果已经知道krbtgt账号的ntlm哈希值,只需清楚TGT票据的样式,就能构造任意账号的TGT票据。TGS不验证TGT票据中账号身份的合法性,只要在TGT票据未超时的情况下,我们可以随意伪造账号身份,包括禁用和不存在的账号。下面是伪造需要的的参数。
1.域名称
2.域的SID值
3.域的KRBTGT账号的HASH
4.伪造任意用户名
使用mimikatz获取需要的信息
lsadump::lsa /patch #获取krbtgt用户hash
然后将我们收集的信息,按照mimikatz的格式填入,就能成功伪造票据,这个过程是离线进行的,这里注意需要需要使用域名而不是IP,因为域名默认使用Kerberos认证,而IP是ntlm认证,因此IP不能用来制作金票。
Kerberos::golden/user:administrator /domain:test19.local /sid:S-1-5-21-2018703852-1585738866-2258721264 /krbtgt:6084e1bdfeb7b787c9c19e9f34cfb7e3 /ptt
注入并查看票据,已经实现了权限维持。
9)白银票据
1.原理
与黄金票据相对的是白银票据,之所以叫白银票据,是因为这种票据的攻击方式和威力不及黄金票据。
在Kerberos协议中,用户使用TGT向KDC请求服务的TGS,TGS使用服务的哈希加密,当用户将TGS发送给服务后,服务用自己的哈希验证TGS合法性,验证之后不会再到KDC验证TGS的合法性,所以当我们拿到了服务账户的哈希,就能伪造访问这个服务的TGS,这就是和黄金票据不同的地方,前者只能访问特定服务,后者可以访问任意服务,我们用Kerberosting破解出服务账户密码的时候,就可以伪造白银票据进行权限维持了,下面是伪造白银票据需要的参数,可以看到和黄金票据略有不同,主要需要目标服务器FQDN和服务账户hash等,域名,域 SID,和黄金票据中一样的方法获取,选择服务的时候可以选cifs,方便检测攻击成果,这里查到了 服务账户的 NTLM 哈希,并填写伪造的用户名和目标服务器。
lsadump::lsa /patch或sekurlsa::logonpasswords
kerberos::golden /domain:test.local /sid:S-1-5-21-384343099-1350869772-3476002129 /target: WIN-47F0F3S663D.test.local /service:cifs /rc4:13cf74746302253838e2f9bd312690c4 /user:administrator /ptt
成功伪造了白银票据后,查看票据,同时因为伪造了cifs服务,所以我们可以dir域控,可见同样是成功的。
三、Kerberos Relay
中继攻击也叫中间人攻击和relay,攻击者利用中间人的身份,将信息转发给另一个目标,从而欺骗系统或用户进行非法操作,从客户端的角度看,攻击者的机器就是它想要验证的服务器,而从服务器的的角度来看,攻击者是就是想要进行验证的客户端。
Kerberos Relay是一种不太常见的新攻击手法,在之前的讲解中,我们熟悉了Kerberos 认证过程,在这个过程中,tgs会使用SPN为身份验证生成的Kerberos 服务票据选择共享加密密钥。刚刚说过,SPN是唯一标识符,所以由SMB和HTTP服务的SPN生成的st肯定不一样,因此拿SMB的票据relay到HTTP服务器,就没办法解密票据。所以一直以来认为Kerberos 不能被relay的。但是如果攻击者可以控制SPN的值,Kerberos relay也是可行的。理论下面这六个协议可以指定SPN,熟悉NTLM relay的朋友都知道,NTLM relay中有一种打印机漏洞和PetitPotam漏洞用来强制目标机器向其他指定机器进行认证,Kerberos relay也需要这么一个机制,这里可以选择DNS欺骗,主动干预客户端和KDC的流量,阻止合法身份验证到达服务,让我们的流量优先被处理。
1.IPSec and AuthIP
2.MSRPC
3.DCOM
4.HTTP
5.LLMNR
6.MDNS
AD域中也支持DNS进行Kerberos认证。用来更新DNS记录和保持IP同步,所以选择DNS来进行强制认证是合适的。
用于使具有动态地址的网络客户端的 DNS 记录与其当前 IP 地址保持同步。下图显示了动态更新过程中涉及的步骤:
在强制认证发生后,攻击者位于客户端和KDC中间,客户端收到ST后,将ST发送给攻击者,攻击者需要选择合适的协议来中继。熟悉NTLM relay的朋友还会知道一个概念SMB Relay 和 LDAP Relay 往往会受到签名的限制。签名是一种安全特性,可以在数据包中对SMB和LDAP等进行数字签名,使数据包的接收者确定其来源和真实性。同时我们知道SMB签名默认只有域控开启,而LDAP签名默认不开启。符合不强制签名的协议有 LDAP/LDAPS HTTP SMB。最后选择选用DNS欺骗中继Kerberos到AD CS的HTTP协议,因为ADCS使用了弱认证
1.LDAP/LDAPS
2.HTTP
3.SMB
选择mitm6作为DNS欺骗工具,这个工具可以拦截加密和非加密协议,如 HTTP、HTTPS、DNS、FTP 等,非常适合劫持网络流量并对数据进行篡改和重定向。
查看这个工具的源代码,它使用了setupfakedns函数来建立一个伪造的DNS服务器,可以拦截所有经过53端口的DNS查询和回应,这是实现DNS中间人攻击的核心。
而send_dns_reply函數是用来处理接收到的DNS请求并进行回复,攻击过程中,攻击者会修改DNS回复中的IP地址,将流量导向自己的服务器上。
具体攻击过程如图,同时开启mitm6和krbrelayx作为中继工具,启动这两个工具进行监听,更新ipv6记录的时候会产生SOAP查询,我们需要等待目标客户端更新ipv6记录,默认域内机器每隔一段时间就会进行一次SOAP查询,实验中也可以重启客户端来加快这一步骤,此时可以看到发生了sent SOA relay和 update,表明发生了SOA查询,告诉客户端ADCS服务器是他要去请求的地方。同时截获客户端的认证数据包并进行重放,最终获得一个证书。
查看TKEY数据包,其中包含完整的 GSSAPI 和 Kerberos AP-REQ 的 SPNEGO 结构。这本质上是对服务的正常 Kerberos 身份验证流程。在之后的应答中也会返回一个 GSSAPI 和 SPNEGO 结构,其中包含了 Kerberos AP-REP,表示认证成功, AP-REP 包含一个 TSIG 会话密钥,客户端可以使用这个密钥进一步签署 DNS 更新查询。
之后,我们查看下面的TCP流,发现攻击者提取ST并将其发送给AD CS,与AD CS建立连接。
最后成功申请到的证书就是我们刚刚终端展示的一样,使用这个证书配合Rubeus和PKINITtools等工具进行身份验证来获得目标机器最高权限。
关于强制认证的思考
之前爆出过一个CVE-2022-33647漏洞,AS-REQ包中etype字段不受保护可以随意修改,可以强制加密降级到RC4,33647的场景是一种中间人攻击, 攻击者可以劫持进出KDC的流量,Kerberos不同于NTLM,在relay的用法中没办法使用打印机漏洞这种强制认证方式,只能使用之前提到的DNS欺骗,ARP投毒这种类似的方法,对于这种类型的Kerberos中间人漏洞,可以配合刚刚讲到的DNS欺骗进行强制认证。当然,也会不可避免的遇到需要等待DNS更新或者需要其他手段让目标机器重启等方式来触发攻击,所以利用难度也要比NTLM relay难很多,但这种方式也证明Kerberos不能被relay的结论是错误的。