0%

windows认证协议之kerberos

windows认证协议之kerberos

kerberos协议概念

Kerberos是一种计算机网络认证协议,它允许某实体在非安全网络环境下通信,向另一个实体以一种安全的方式证明自己的身份。下面是对这个协议的一个简化描述,将使用以下缩写:

  • AS(Authentication Server)= 认证服务器
  • KDC(Key Distribution Center)= 密钥分发中心
  • TGT(Ticket Granting Ticket)= 票据授权票据,包含客户端ID、客户端网络地址、票据有效期以及client/TGS会话密钥
  • TGS(Ticket Granting Server)= 票据授权服务器
  • SS(Service Server)= 特定服务提供端
  • Ticket 票据,一条包含客户端标识信息、会话密钥和时间戳的记录,客户端用它来向目标服务器认证自己

TGT类似于护照,Ticket则是签证,而访问特定的服务则好比出游某个国家。与护照一样,TGT可标识你的身份并允许你获得多个Ticket(签证),每个Ticket对应一个特定的服务,TGT和Ticket同样具有有效期,过期后就需要重新认证。

整体通信逻辑图如下:

image-20201222165252859

具体认证过程如下:

  1. AS_REQ: Client向KDC发起AS_REQ请求获取TGT,请求凭据是Client hash加密的时间戳
  2. AS_REP: KDC使用Client hash进行解密,如果结果正确就返回用krbtgt hash加密的TGT票据,PAC包含Client的sid,Client所在的组。
  3. TGS_REQ: Client凭借TGT票据向KDC发起针对特定服务的TGS_REQ请求
  4. TGS_REP: KDC使用krbtgt hash进行解密,如果结果正确,就返回用服务hash 加密的TGS票据(这一步不管用户有没有访问服务的权限,只要TGT正确,就返回TGS票据)
  5. AP_REQ: Client拿着TGS票据去请求服务
  6. AP_REP: 服务使用自己的hash解密TGS票据。如果解密正确,就拿着PAC去KDC那边问Client有没有访问权限,域控解密PAC。获取Client的sid,以及所在的组,再根据该服务的ACL,判断Client是否有访问服务的权限。

注:

krb就是指kerberos, tgt就是指Ticket Granting Ticket,这个密钥会被用到加密TGT,只有KDC拥有krbtgt的密钥,所以TGT才不能被伪造

kerberos协议认证过程

接下来详细分析下上面提到的几个认证过程。

AS_REQ

某个域用户试图访问域中的某个服务,于是输入用户名和密码,本机Kerberos服务会向KDCAS认证服务发送一个AS-REQ认证请求。该请求包中包含:请求用户名客户端主机名加密类型Autherticator(用户NTLM Hash加密的时间戳)以及一些信息。本地也抓包试了下,但是里面有些敏感信息还得打码,所以直接贴先知大佬的图吧

image-20201223164200485

PA-DATA 预认证信息数据 一个列表,包含若干个认证消息用于认证,每个认证消息都有type和value。在上图中AS_REQ 阶段主要用到的是ENC_TIMESTAMP和PA_PAC_REQUEST。
  ENC_TIMESTAMP是预认证,就是用用户hash加密时间戳,加密方式为etype指定的加密类型,作为value 发送给AS服务器。然后AS服务器那边有用户hash,使用用户hash进行解密,获得时间戳,如果能解密,且时间戳在一定的范围内,则证明认证通过。

PA_PAC_REQUEST是启用PAC支持的扩展。PAC(Privilege Attribute Certificate)并不在原生的kerberos里面,是微软引进的扩展。PAC包含在AS_REQ的响应body(AS_REP)。这里的value对应的是include=true或者include=false(KDC根据include的值来判断返回的票据中是否携带PAC)。

在REQ_BODY 中则是客户端和服务端的一些信息,注意其中2个点:

  • 在AS_REQ里面cname 是请求的用户,这个用户名存在和不存在,返回的包有差异,可以用于枚举域内用户名。
  • till 表示到期时间,在大佬的文章中说rubeus和kekeo都是20370913024805Z,这个可以作为特征来检测工具,我实际测试发现本地用rdp发起请求的till也是20370913024805Z,所以这里待考究。

AS_REP

KDC使用用户 hash进行解密,如果解密成功,并且时间戳在五分钟之内,那么预认证通过。接着AS认证服务将会向Client发送响应包,响应包中包括krbtgt的NTML hash加密后的TGT票据以及用户NTML Hash加密的Login Session key和其他信息。Login Session key 是可以使用用户的NTML Hash解密出来的,其中最关键的就是session key,称呼其为session key1。

image-20201223193249632

ticket中的enc-part是由krbtgt的密码hash加密生成的。如果我们拥有krbtgt的hash,便可以自制ticket,发起黄金票据攻击。

最下面的 enc-part 与 ticket 是一个层级的,是使用client用户NTML Hash加密的 Login Session Key,作用是作为下一阶段的认证密钥,确保客户端和KDC下一阶段之间通信安全。

经过第一轮的交互之后,client 获取到了 TGT 票据和 Login Session Key 供后续使用。接下来就是与TGS通信拿ST票据了。

TGS_REQ

TGS_REQ 数据包中主要的内容为 Authenticator 、TGT以及访问的服务名

image-20201223201535331

TGT的内容在padata-value–>ap-req–>ticket,其内容与AS_REP返回的基本一致。

Authenticator 在ticket下面,是利用前面获取到的Login Session Key 加密时间戳得到的密文。

在下面紧跟着的就是 req-body 部分,其中sname为请求的服务,其余的参数与前面AS_REQ类似:

image-20201223202151635

当TGS收到请求后,将会检查自身是否存在客户端所请求的服务,如果服务存在,则进行解密。TGS利用krbtgt的NTML hash解密TGT,通过用户NTML hash生成的Login Session Key对应解密Authenticator,解密成功之后则验证客户端身份与时间戳,验证完成之后TGS生成一个ST票据

TGS_REP

TGS_REP中返回的ticket就是ST票据,这个ticket用于AP_REQ的认证,使用要请求的服务的NTLM hash加密的。

而ticket标签外的另一个enc-part使用AS_REP中的session key1 解密之后可以得到下一个session key2,用来下一步ST票据的加密使用。

image-20201223203215510

AP_REQ

经过上面的步骤,现在client已经拿到了TGS票据和加密在enc-part中的session key2。接下来就使用session key2来加密时间戳和用户名,带上ST票据送给 Server 。此外还包含一个 Flag 用于表示 Client 是否需要进行双向验证。

AP_REP

SS收到客户端的服务请求之后,利用krbtgt的hash对ST票据进行解密,从中获取session key2来解密消息,核对用户身份是否合法,同时解密PAC来查看用户是否有访问权限,如果验证通过则提供相应服务给Client。(PAC后续补充)

参考图

最后放一张图,来自于斯托林斯《密码编码学与网络安全:原理与实践》,其中对于kerberos的讲述十分详细可以参考下:

image-20201228184957555

1
2
3
4
5
ID是某个用户标识
Nonce为挑战值,确保请求未被重放或篡改
Realm标识用户所处的域
AD是标识服务器身份,防止票据在与申请票据时不同的环境使用
options是票据标志,是5版本新增的字段

PAC

pac认证是微软为了解决用户身份权限的问题引入,在AS_REP返回的TGT中增加了PAC字段返回给客户端。当用户与KDC之间完成了认证过程之后, Client需要访问Server所提供的某项服务时, Server为了判断用户是否具有合法的权限需要将Client的User SID等信息传递给KDC, KDC通过SID判断用户的用户组信息, 用户权限等, 进而将结果返回给Server, Server再将此信息与用户所索取的资源的ACL进行比较, 最后决定是否给用户提供相应的服务。

相当于KDC知道用户与他的权限,server在实际提供服务的时候需要跟KDC确定用户是否有权限。

相关利用姿势

pass the ticket

MS16-048

MS14-068是密钥分发中心(KDC)服务中的Windows漏洞。它允许经过身份验证的用户在其Kerberos票证(TGT)中插入任意PAC,造成的危害是允许域内任何一个普通用户,将自己提升至域管权限。微软给出的补丁是kb3011780

该漏洞最本质的地方在于 KDC无法正确检查Kerberos票证请求随附的PAC中的有效签名,导致用户可以自己构造一张PAC。 签名原本的设计是要用到HMAC系列的checksum算法,也就是必须要有key的参与,但是实现的时候却允许所有的checksum算法,包括MD5。那我们只需要把PAC 进行md5,就生成新的校验和。这也就意味着我们可以随意更改PAC的内容,完了之后再用md5 见checksum和计算KDC校验和。在MS14-068修补程序之后,Microsoft添加了一个附加的验证步骤,以确保校验和类型为KRB_CHECKSUM_HMAC_MD5。

具体利用:https://www.cnblogs.com/bmjoker/p/10355979.html#hid-Pa3EAh

黄金票据

在AS_REP里面的ticket的encpart是使用krbtgt的hash进行加密的,如果我们拥有krbtgt的hash,就可以给我们自己签发任意用户的TGT票据,这个票据也被称为黄金票据。伪造黄金凭据需要具备下面条件:

  • krbtgt用户的hash(就意味着你已经有域控制器权限了)
  • 域名称
  • 域的SID值
  • 要伪造的用户名

白银票据

在TGS_REP里面的ticket的encpart是使用服务的hash进行加密的,如果我们拥有服务的hash,就可以给我们自己签发任意用户的TGS票据,这个票据也被称为白银票据。相较于黄金票据,白银票据使用要访问服务的hash,而不是krbtgt的hash,由于生成的是ST票据,不需要跟域控打交道,但是白银票票据只能访问特定服务。但是要注意的一点是,伪造的白银票据没有带有效KDC签名的PAC。如果将目标主机配置为验证KDC PAC签名,则白银票据将不起作用。

pass the key

一般是mimikatz使用时通过 sekurlsa::ekeys 获取用户aes key 进行

AS-REPRoasting

当域用户设置了选项”Do not require Kerberos preauthentication”,此时向域控制器的88端口发送AS_REQ请求,对收到的AS_REP内容重新组合,能够拼接成”Kerberos 5 AS-REP etype 23”(18200)的格式,接下来可以使用hashcat对其破解,最终获得该用户的明文口令

kerberosting

还记得TGS_REP返回的ST票据是使用服务实例的NTLM hash加密生成的,加密算法为RC4-HMAC。当获得这个ST票据后,我们可以尝试穷举口令,模拟加密过程,生成ST票据进行比较。如果ST票据相同,代表口令正确,代表已获得目标服务实例的明文口令。可以使用kerberoast进行爆破操作,参考

https://3gstudent.github.io/%E5%9F%9F%E6%B8%97%E9%80%8F-Kerberoasting/

总结

kerberos的一部分基础先学习到这里了,相关的还有委派和相关利用的深入学习等后续再进行啦~~

参考链接

https://daiker.gitbook.io/windows-protocol/kerberos/

https://www.anquanke.com/post/id/172900

https://www.cnblogs.com/bmjoker/p/10355979.html

https://xz.aliyun.com/t/8187