重新总结和理解一下kerberos
协议,同时为接下来的kerberos
多种攻击方式做一下铺垫。
kerberos
名字是古希腊神话中地狱看门犬刻耳柏洛斯(Cerberus)的变种,在很多影视剧中都能看到他的身影。(图源网络)
kerberos
协议与三这个数字有着不解之缘,除了名字含义是三头犬之外,具体请看下面的分析。此外它是由MIT(麻省理工学院)开发的一种认证协议。采用C/S 客户端/服务器结构,应用了对称秘钥体制进行密钥管理的系统。
仔细回想一下,为了保证信息安全传输,不可避免的就是要保证这些特性:机密性,完整性,身份的不可否认性。这些被称为PKI公钥基础设施。
这里简单解释一下:
1、机密性很好理解,信息传输从古至今都有加密这一说,就是为了防止被坏人破解,机密性有效地保证了信息不被泄露;
2、仅有机密性还不够,攻击者看不懂,但是能够截获,篡改,所以要保证信息完整性;
3、身份的不可否认性,也就是不能让坏人假冒信息交互的双方,也就是要保证身份认证,你就是你,我就是我。
那么Kerberos
既然是认证协议,就是为了保证身份的不可否认性而制作的,但是里面也涉及了机密性与完整性的内容,例如使用对称加密等。所以可以说kerberos
中融入了PKI
,所以在大多数技术中都有PKI的身影,还有SSL
、IPsec VPN
等。
首先我们要知道,工作组环境下计算机之间的网络认证是使用的NTLM
协议;
那么在域环境下就是使用Kerberos
协议,由客户端、服务端和KDC
组成。
这里的客户端和服务端是一个抽象泛指的概念,客户端可以是zhangsan
,可以是lisi
,可以是任意用户,这里用client
表示;
服务端可以是WEB
服务、SQL-Server
服务,可以是ICMP
服务等等。这里客户端用client
表示,服务端用AP(Application Server)来表示。
域环境,本身就是内网的集权控制体系,一人之下万人之上,谁是那个一人?就是域控,所以客户端和服务端相互交流就要听域控的。域控就是这三者中的KDC。也就是说密钥分发中心KDC(Key Distribution Center)
是Kerberos
的核心组件,默认安装在域控。KDC
包括AS
、TGS
。
认证服务,用来认证客户的身份,保证你就是你,不会被别人冒充。
负责用户信息认证,给客户端提供TGT(Ticket Granting Tickets,即黄金票据)。
票据分发服务。向客户端提供ST
(Service Ticket
,即白银票据)和Session Key
(服务会话密钥)。
上述我们说了服务端包含了各种各样的服务,这些服务可不是你想来就能来滴,必须通过TGS给你分发相应的门票才能进去。通俗理解TGS就是个发放门票的。
1、Kerberos 使用 UDP 或 TCP 作为传输协议,以明文形式发送数据。因此Kerberos用于提供各种加密。
2、Kerberos 使用的端口是 UDP/88 和 TCP/88,在 KDC 中监听。
这是一个概念性的,代表一个用户的唯一身份,三部分组成:
Linux
加入域的时候,有一个工具就是realm
,也就是域。
虽然个人感觉Linux加入域没有实质性的意义,毕竟内网中windows运维或者统一管理有自己的域体系,Linux自己又何必融入这个体系中呢,这个先不多说,以后慢慢尝试一下。
krbtgt
用户是在创建域时系统自动创建的账号,其作用是密钥发行中心KDC的服务账号,其密码是系统随机生成的,无法正常登陆主机。在域控中可以看到:
1、如果只是说概念性的内容会十分枯燥,来搭建一个简单的域环境,通过wireshark
抓包分析会直观地多。域环境搭建省略,我这里配置了windows2012为域控,windows10为域成员,如下图所示:
2、windows2012上安装wireshark并输入对应ip进行抓包,随后过滤条件输入kerberos
即可。
完整的认证流程,有客户端与AS, TGS, AP的3次交互,每次交互,响应包都会包含两条信息,一条可以用本地密钥解密,另一条需要转发。
分六个过程,按照顺序分别是1-6。REQ
即Request
,请求包;REP
即Reply
,返回包。
下面以【域用户Lucky向kerberos服务请求,希望获取登录Win7的权限】为例,Client
就是lucky
,AP
就是win7主机(host服务)。
此例大致流程为:
1、域用户lucky
请求发出后,kerberos
得到了这个消息,首先得判断Lucky
是否是可信赖的, 也就是白名单黑名单的说法。这就是AS服务完成的工作,通过在AD
中存储黑名单和白名单来区分lucky
。成功后,返回AS
返回TGT
票据给Lucky
。
2、lucky
得到了TGT
后,继续向Kerberos
请求。kerberos
再一次得到这个消息后,会通过lucky
消息中的TGT
,判断出lucky
拥有此权限,就给了lucky
登录win7
的权限Service ticket(ST)
。
3、lucky
得到了ST
后,成功登录win7
。
当然,这个ST
只是仅仅登录Win7(Host服务)
的。如果还需要访问其他的服务要再次向TGS申请。
接下来来看wireshark抓包内容,我会挑一些重点来详细查看,对我们认知kerberos
足够了,其它的数据包字段以后用到了例如IPS规则检测时可以用再参考这篇文章,https://zhuanlan.zhihu.com/p/473625225写的十分详细。
如图所示,wireshark
数据包已经帮我们标出来了KRB5
以及AS-REQ
。在TCP层上方,有一个Kerberos
。
1、AS_REQ
阶段主要是按照etype
的加密类型使用用户hash
加密时间戳,作为value
发送给AS
服务器,同时还有用户名、主机名或IP地址、随机数等信息也会发送给AS
,如下图所示。
2、内网渗透中常用的神器有mimikatz
、kekeo
、Rubeus
,这三个的默认随机数分别为:12381973
、12381973
、1818848256
。所以nonce字段可以用来做特征检测。
3、加密时间戳只有用户不开启Do not preauthentication
这个选项才会有,如果用户勾选了此选项,就不会加密时间戳。
同时会有一个DONT_REQ_PREAUTH
的flag
标识。这里就涉及到了一个域攻击方式:AS_REP Roasting
攻击,具体可以参考下文以及我这篇文章:
有AS_REQ请求包,就有响应包,可以看到分四个部分:as-rep
,cname
,ticket
,enc-part
这一段的数据内容和上述AS_REQ差不多,不多解释了。
本质这个就是KDC返回来的一张TGT票据。
1、AS服务器查询域控的ntds.dit
请求用户的hash
,使用用户hash
进行解密,获得时间戳,如果能解密,且时间戳在一定的范围(5分钟)内,则证明认证通过
2、返回TGT
票据和enc_part
,其中TGT
票据是用krbtgt
用户hash
进行加密的数据,用户无法破解如下图红框部分。而enc_part
中用户使用自身的hash
解密出来,就会得到Login Session Key
。
1、经过上面的步骤,客户端获得了 TGT
票据 和 enc_part
。
2、用自己的密码NTLM Hash
解密enc_part
得到原始的Logon Session Key
。
3、它会在本地缓存此 TGT
票据和 原始的Login Session Key
。如果现在它需要访问某台服务器的某个服务,它就需要凭借这张TGT
票据向KDC
申请相应的ST
服务票据(Service Ticket)
。
4、ST
服务票据是通过KDC
的另一个服务TGS颁发的。
5、在这个阶段,微软引入了一个扩展协议:大名鼎鼎的S4U协议,旗下包含两个子协议S4u2self 和S4u2Proxy(当委派的时候,才用的到)
我们来看一下TGS_REQ的数据包内容,也是有大概的两个子项:tgs-req
和req-body
。这里的req-body
和先前的AS_REQ差不多,重点分析一下tgs-req
里面的内容。
这里面的主要内容其实就是ticket+authenticator,票据+验证
客户端拿着AS_REP阶段派发的TGT票据、随机数以及使用session key加密的用户名和时间戳向KDC申请相应的服务的票据,如果能请求成功,它将获得相应服务的ST票据。
注意,当TGS接收到请求后,会先进行检测,如果检测成功,生成对应服务的ST票据以及Service Session key如图:
那么它做了什么检测呢?
1、TGS接收到请求之后,首先会检查自身是否存在客户端所请求的服务(就是查询SPN)
2、如果服务存在,通过 krbtgt
用户的NTLM Hash
解密TGT
并得到Login Session Key
,然后通过Login Session Key
解密Authenticator
。
3、如果解密成功,则验证了对方的真实身份,同时还会验证时间戳是否在范围内。并且还会检查TGT中的时间戳是否过期,且原始地址是否和TGT中保存的地址相同。
1、TGS接收到请求后使用krbtgt NTLM-hash
进行解密TGT,验证对方真实身份成功后,返回相应服务的ST票据
2、ST票据是用对应的服务hash进行加密的。
前面的4步,在数据包中都有体现如下图:
紧接着,就要进入到KRB_AP_REQ
阶段
1、从TGS_REP
拿到了ST
票据和Service Session Key
,我们需要去访问AP
的服务内容。
2、使用从上面拿到的ST票据,还有用户名、时间戳、Service Session Key
一起发送给AP
。
3、AP
收到后会去KDC
确认信息和PAC
权限。
而现在这个KRB_AP_REQ
和KRB_AP_REP
这两步在数据包的哪里呢?没有标识啊?其实大家应该已经猜到了,其实就是下面的这个。
AP_REQ
的数据包,它不会像TGS、AS
一样在Wireshark中显示,一般是通过服务的协议也就是DCERPC(Distributed Computing Environment / Remote Procedure Calls)
,也称作分散式运算环境/远端呼叫系统。关于DCERPC
协议这里不多赘述,主要看下文我摘抄自赵武大佬写的文章片段就行了。膜拜:https://zhuanlan.zhihu.com/p/359608347
这是一个另一个非常非常基础的Windows系统的通信协议,它比rdp协议更普遍,默认开启。由于内容丰富,接口众多,早期的安全人员基于它写了很多蠕虫病毒,一度让微软和运营商非常头疼。dcerpc的默认端口是135,上面承载了包含wmi,有认证就有ntlmssp,还有epmapper等一系列丰富的系统信息,甚至还能获取网卡IP地址列表。
用人话说就是,可以:
- 获取操作系统版本信息
- 获取系统的IP地址列表(是的,你没看错,包含ipv6地址)
- 获取系统的软件服务信息
- 获取系统服务开放的动态端口
- 获取系统的芯片架构(32位/64位) - 账号的暴力破解(wmi)
那么回到这里的kerberos
协议上,它会把kerberos
的认证信息封装起来一起发送,也就是下图中的Bind: call_id
这个数据包,如下图:
说白了,DCERPC Bind: call_id中包含两个东西:
那么上图中的ticket就是从TGS_REP
获取到的ST(TGS)
票据,下面还有使用Service Session Key
加密的authenticator
KRB_AP_REQ
包含以下内容
同时这些数据会被DCERPC
协议封装起来发送给目标服务器,同时DCERPC
会帮我们请求基础网络信息。
AP
接收到请求后,用自己的密钥(Service Session Key)
解密TGS
中的ticket->enc-part
获取Service Session Key
Service Session Key
解密新的Authentication
,对TGS
和authenticator
进行验证,验证通过则返回新的时间戳(通过Service Session Key
进行加密)Service Session Key
解密AP-REP
返回的时间戳,并验证其是否正确。验证通过则证明客户端可以信赖服务器,并向服务器AP发送服务请求。结合现实,kerberos
认证过程,很像我们做完核酸检测拿到阴性证明后才能坐公交地铁高铁一样,不过这个例子只是为了辅助理解,不要生搬硬套,毕竟协议是死的,现实是活的。
先前我们说了忽略PAC
的kerberos
协议,现在引入它讲解一下。
上述忽略PAC
的kerberos
认证过程大致为:
1、客户端向KDC
发起AS_REQ
,请求凭据是客户端hash加密时间戳,随后KDC根据用户名找到hash
解密,成功后返回TGT
2、客户端带着TGT向KDC发起TGS_REQ
,KDC使用krbtgt
的hash解密TGT,正确的话就返回用服务hash加密的TGS票据
3、客户端带着TGS向KDC去请求相应服务,服务用自己的hash解密,成功后允许客户端访问。
上述这个过程看似没啥问题,但是忽略了一个重要因素:用户有无权限访问对应服务。
仔细梳理一下过程,用户只要自己的hash正确,就可以拿到TGT,而TGT又可以访问所有的服务,这不就是相当于只要自己的hash正确,所有的服务就可以访问了么?说白了kerberos仅仅是解决了我就是我,你就是你的问题,并没有具体解决你能不能访问具体服务的问题。
针对这个问题,微软就引进了PAC这个概念:PAC
即Privilege Attribute Certificate
特权属性证书,PAC包含Client的相关权限信息,比如SID以及所在组,简单讲PAC就是用于验证用户权限的。需要注意的是:PAC并不在原生的kerberos里面,是微软引进的扩展。所以我们要清楚kerberos不是Windows上才有的,Linux也可以用这个协议做认证。
1、AS_REQ:客户端向KDC发起AS_REQ,请求凭据是用客户端hash加密的时间戳等
2、AS_REP:随后KDC根据用户名找到hash解密,成功后返回TGT。TGT里面包含PAC,PAC包含用户的sid,用户所在的组。
3、TGS_REQ:客户端带着TGT向KDC发起TGS_REQ。
4、TGS_REP:KDC使用krbtgt的hash解密TGT,正确的话就返回用服务hash加密的TGS票据。
5、AP_REQ:客户端带着TGS向KDC去请求相应服务。
6、VERIFY_PAC_REQ:服务用自己的hash解密TGS,成功后,服务会拿着PAC向KDC询问客户有无权限访问它。
7、VERIFY_PAC_REP:KDC收到后会解密PAC,获取到客户端的SID,所在组以及访问权限,开始判断有无权限,并将结果返回给AP。
8、AP_REP:有权限的话告诉用户可以访问,反之不可。
特别说明的是,PAC对于用户和服务全程都是不可见的。只有KDC能制作和查看PAC。
1、kerberos协议与三有着不解之缘,名字为三头犬;需要客户端,服务端和KDC三者参与;客户端需要请求三次;KDC和服务端需要发送返回包三次;kerberos包含了信息安全三要素等等,正所谓一生二,二生三,三生万物。。。
2、缺点
Kerberos身份认证采用的是对称加密机制,加密和解密使用相同的秘钥,安全性有所降低。
TGT
(krbtgt hash加密)service session key
解密认证,成功后可访问服务。Kerberos中身份认证服务和票据授权服务是集中式管理的,容易形成瓶颈,系统的性能和安全性也过分依赖于这两个服务的性能和安全
渗透过程,某种意义上就是对协议的一些漏洞进行攻击,常见的rdp
、http
、ssh
、smb
等,kerberos
协议也不例外。
我们还是按照先前设置的,从KRB_AS_REQ
到KRB_AP_REP
截止,共6个阶段来编号解释。
一旦攻击者获取到了任意域用户用户名和hash
,就可以模拟出这个用户去请求AS
进行认证,直接通过AS
的校验,不需要明文密码。
有时候我们没有一台域用户的权限,只能在域外对域内进行信息收集。(如果在域内直接net user /domain
就搞定了)
这时候就可以在第一阶段不断遍历发送请求,根据返回包的信息特征不同来判断用户是否存在。三种情况,用户名和密码正确我就不说了。
如图,用户名出错后,数据的返回包特征值就是KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN
可以参考下面这个表格:
用户状态 | Kerberos 错误信息 |
---|---|
需要额外的预认证(用户存在) | KDC_ERR_PREAUTH_REQUIRED |
客户端凭证已被吊销(用户存在但禁用) | KDC_ERR_CLIENT_REVOKED |
在Kerberos数据库中找不到客户端(不存在) | KDC_ERR_C_PRINCIPAL_UNKNOWN |
密码错误(用户存在) | KDC_ERR_PREAUTH_FAILED |
密码喷洒攻击是一个比较泛泛的定义,在这里指的是:常规爆破中,我们是用很多密码去尝试一个账号,很容易将用户锁定或者引发机制;**而密码喷洒是用一个密码去碰撞多个账号,一般来讲密码喷洒攻击和域用户枚举同时使用。**
原理就是上述:在确认用户存在后,客户端又会发送一个AS-REQ
请求,如果密码正确,则返回AS-REP
;否则返回KRB5KDC_ERP_PREAUTH_FAILED
这个前面提到过,就是因为勾选了Do not require kerberos pre-authentication
才会导致漏洞产生。此漏洞可以破解出勾选了此选项的域用户密码,如果此域用户是域管理员用户那就十分危险了。
一旦勾选了此选项,数据包中就不会有用User hash加密时间戳这一内容:
那么攻击者就可以通过先前域用户枚举出来的用户名,构造KRB_AS_REQ
发送给AS
,AS
就会去直接将User key(User hash)
返回给攻击者,攻击者拿到的就是此用户的hash
。随后就可以用hashcat
或者john_the_ripper
等工具来破解用户的hash获取明文密码了。
不过此漏洞比较鸡肋,因为默认域环境的所有用户都是没有勾选此选项,即启用了kerberos身份预认证,简单理解就是防止了爆破,要求用户使用自己的hash加密时间戳。
发生在第二阶段即KRB_AP_REP
阶段。著名的黄金票据攻击,常用来做权限维持,因为它所获取的是TGT,而TGT我们之前分析出,它是由域中krbtgt用户的hash进行加密的,客户端都无法解出此TGT。而我们想要获取到krbtgt用户的hash,需要获取到域控权限才可以。同时获取到krbtgt用户的hash后,攻击者可以任意伪造TGT,从而请求任何AP。
就算域控自身hash更改了,只要krbtgt用户hash不更改,就能一直获取域控权限。
先前通过身份验证的域用户,可以拿着TGT去请求TGS。在KRB_TGS_REP
阶段,TGS根据TGT验证成功后,会返回域用户要请求的服务的ST票据,此ST票据是通过对应服务账户hash来加密的。
也就是说,任何一个用户向KDC
发起TGS_REQ
请求,只要hash正确,不管用户对服务有无访问权限,只要TGT正确,那么肯定会返回TGS票据。那么随后我们就可以通过本地暴力破解来破解相应服务账户的hash,从而获取明文密码。
在TGS-REP阶段,TGS_REP里面的ticket的enc-part(内层enc-part)是使用服务账号的ntlm hash进行加密的(也就是ST票据)。
如果我们拥有服务账号的ntlm hash,就可以给我们自己签发该服务的ST票据,这个票据也被称为白银票据。相较于黄金票据,白银票据的使用需要对应服务的hash,而不是krbtgt的hash,且不需要跟域控打交道,而是有且仅能和访问特定服务打交道去访问。
但是要注意的一点是,伪造的白银票据没有带有有效KDC签名的PAC。如果将目标主机配置为验证KDC PAC签名,则银票将不起作用。
目标服务机器上开启PAC功能:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControl\SetControl\LsaKerberos\Parameters中的ValidateKdcPacSignature设置为1。
关于白银票据关键的两个利用条件:
无论用户有无访问权限,只要TGT正确,就会返回TGS票据。
PAC不能由用户端来制作,如果有些服务涉及到验证PAC,白银票据也就利用不成功。
涉及到了非约束委派、约束委派、基于资源的约束委派。这一块以后出文章会详细解释。
这里不多介绍,篇幅原因后续会有文章解释。
有些服务不需要向KDC验证用户发来的TGT中所包含的PAC,这是白银票据利用的重要前提,上述有提到。
漏洞位于 kdcsvc.dll ,允许经过身份验证的用户在其获得的 TGT 中插入任意的 PAC。
2021年12月和log4j2同一周曝出POC和EXP细节的漏洞。
CVE-2021-42278是一个安全绕过漏洞,该漏洞允许攻击者使用计算机帐户sAMAccountName
欺骗来冒充域控制器(SAM名称模拟)。
CVE-2021-42287是影响Kerberos特权属性证书(PAC)的安全绕过漏洞,允许攻击者冒充域控制器(KDC欺骗)。
https://www.tarlogic.com/blog/how-kerberos-works/
https://zhuanlan.zhihu.com/p/473625225
https://zhuanlan.zhihu.com/p/359608347
https://www.ietf.org/rfc/rfc4120.txt