返回
顶部

references:

0x1 前言

Kerberos本意为希腊神话中看守冥界之门的拥有三只头的恶犬,如下:

1640774470076

Kerberos协议在Windows AD安全领域中占据着举足轻重的地位,因此对Kerberos协议有一个相对透彻的理解还是很有必要的

这篇文章会通过Wireshark对Windows AD中Kerberos的一般通信过程进行详细的分析

0x2 概述

约定:

  • c-d-skey表示client与dc(kdc)TGS阶段用于加密通信的session key
  • c-s-skey表示client与应用服务器(Application Server)在AP阶段用于加密通信的session key

0x2.1 AS阶段

AS意为Authentication Service(认证服务)

  • client向kdc发送AS-REQ(不包含pre-auth)
  • kdc返回KRB-ERR,要求客户端发送pre-auth
  • client向kdc发送包含pre-auth(使用client密码hash加密的时间戳)的AS-REQ
  • kdc验证用户身份(解密时间戳,验证时间是否为最近的时间)
  • kdc向client返回AS-REP,其中包含tgt票据以及session key(c-d-skey)
  • tgt票据加密部分使用krbtgt账户hash进行加密,enc-part字段使用client密码hash进行加密,其中包含有c-d-skey
  • client使用自己的密码hash解密enc-part获得c-d-skey,然后将c-d-skey和tgt票据缓存起来,以备后用

0x2.2 TGS阶段

TGS意为Ticket Grant Service(票据颁发服务)

  • client使用c-d-skey生成加密的authentictor字段并和tgt一起提交给KDC,该数据包为TGS-REQ,其中req-body字段中包含目标服务的spn
  • kdc解密tgt,获取c-d-skey,使用c-d-skey解密authenticator,验证client身份
  • 根据client的请求颁发相应的服务票据,生成TGS-REP数据包返回给client
  • TGS-REP中包含服务票据以及enc-part,enc-part由c-d-skey进行加密,里面包含c-s-skey,票据的enc-part使用应用服务器的服务账户hash进行加密
  • client解密TGS-REP后将服务票据和c-s-skey缓存起来,以备后用

0x2.3 AP阶段

AP意为Application Service(应用服务)

  • client向目标服务器server发送AP-REQ数据包,其中包含服务票据以及一个用于验证自己身份的authenticator
  • 此authenticator字段使用c-s-skey进行加密
  • server收到AP-REQ之后,使用自己的服务账户hash解密票据,从中获得c-s-skey,使用c-s-skey解密authenticator从而验证客户端身份

至此,kerberos完成,client和server开始加密通信

0x3 抓包分析

下面是具体的抓包分析,里面的字段可能和上面的概述有出入,但不影响理解Kerbero协议通信过程

我们这里以Rubeussmbclient.py为例,请求目标服务器的cifs服务,示例用户为MOTHER.FUCKER\Administrator

首先生成keytab文件,并应用到wireshark的KRB5协议中

ktpass -out Administrator.keytab -princ Administrator@MOTHER.FUCKER -mapUser Administrator@MOTHER.FUCKER -pass qwe123... -crypto all -ptype KRB5_NT_PRINCIPAL

image-20220205185741295

0x3.1 AS阶段

这里我们使用Rubeus直接请求TGT票据

Rubeus.exe asktgt /user:Administrator /password:qwe123... /domain:MOTHER.FUCKER /dc:192.168.216.131  /outfile:123.kirbi /opsec /force

0x3.1.1 AS-REQ (no pre-auth)

image-20220205220120888

可以看到,在这个AS-REQ数据包中,并没有提供任何认证相关的信息,只是提供了client支持的所有加密类型,用户名MOTHER.FUCKER\Administrator以及client的地址信息(hostname)

0x3.1.2 KRB-ERROR

image-20220205220426395

error-code字段显示错误类型为eRR-PREAUTH-REQUIRED,即要求client提供pre-auth数据

在e-data字段中,第一个PA-DATA——PA-ENCTYPE-INFO2中,kdc提供了自己支持的加密类型

分别是AES256和RC4,其中前者需要盐(MOTHER.FUCKERAdministrator),普通账户的盐值计算方式和计算机账户的盐值计算方式有细微的差别

0x3.1.3 AS-REQ (with pre-auth)

image-20220205222415704

client选定加密类型23(RC4),将当前时间戳加密封装到PA-ENC-TIMESTAMP结构中

在req-body中指定票据申请者(MOTHER.FUCKER\Administrator)和要申请的票据([email protected]

0x3.1.4 AS-REP

image-20220205222842701

ticket字段自不必说,就是TGT票据

enc-part由client的密码哈希加密,解密后的内容中最重要的就是key字段,也就是c-d-skey,其中包含密钥类型和密钥值

有了c-d-skey之后,就能进行下一阶段的通信了

0x3.2 TGS阶段

使用Rubeus利用AS阶段获取到的TGT票据缓存请求CIFS服务票据

Rubeus.exe asktgs /ticket:123.kirbi /service:CIFS/WIN-37U50GQO8KT.MOTHER.FUCKER /dc:192.168.216.131 /outfile:321.kirbi

0x3.2.1 TGS-REQ

image-20220205194150266

TGT票据以及认证数据authenticator都在padata字段中——PA-TGS-REQ

TGT票据就是AS阶段返回的票据,原封不动放在这里

authenticator字段为使用c-d-skey加密的数据,解密如下:

image-20220205194406942

可以看到authenticator字段中包含了票据申请者MOTHER.FUCKER\Administrator,这个必须要和TGT票据中的用户是一致的,不然会导致认证失败,同时也是为了防止冒充用户

image-20220205195035675

req-body中主要的字段就是sname,指定了申请的票据的SPNCIFS/WIN-37U50GQO8KT.MOTHER.FUCKER

0x3.2.2 TGS-REP

image-20220205195227046

返回一个CIFS票据和enc-part

enc-part字段由c-d-skey加密,解密后内容如下:

image-20220205195354709

最重要的字段依然是key(c-s-skey),有了这个key,就可以构造AP-REP数据包,向Server进行认证

0x3.3 AP阶段

python smbclient.py MOTHER.FUCKER/Administrator@WIN-37U50GQO8KT.MOTHER.FUCKER -k -no-pass -target-ip 192.168.216.131 -dc-ip 192.168.216.131

对impacket的文件进行了修改,将impacket\smbconnection.py的第314行修改为:

ccache = CCache.loadFile(r"C:\Users\x\1.ccache")

其中C:\Users\x\1.ccache是经过ticketConvert.py转换过的ccache格式的票据缓存

0x3.3.1 AP-REQ

image-20220205202629036

这个数据包是在445端口捕获的,kerberos协议的ap-req被封装在SPNEGO数据包中

你可以将SPNEGO理解为一个用于将应用协议和认证协议分离开来的一种协议

在本例中,SPNEGO将smb协议和kerberos协议分离开来

在ap-req中,ticket字段为TGS阶段获取的票据,原封不动放在这里

authenticator中包含客户端身份信息,使用c-s-skey加密

0x3.3.2 AP-REP

image-20220205203228979

在本例中,并不存在AP-REP数据包,只是在SPNEGO中返回了accept-completed代码,表示smb会话建立成功

在实际应用中,AP-REP只有在client在AP-REQ的authenticator字段提供了sub-key时候才会被返回,表明是否采用client提供的sub-key,或者向client返回自己选择的sub-key,用于后续的通信加密

0x4 结语

如果有不对的地方,希望能指出来,谢谢

今天是大年初五——破五,你们都吃饺子了吗?