references:
0x1 前言
Kerberos本意为希腊神话中看守冥界之门的拥有三只头的恶犬,如下:
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协议通信过程
我们这里以Rubeus
和smbclient.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
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)
可以看到,在这个AS-REQ数据包中,并没有提供任何认证相关的信息,只是提供了client支持的所有加密类型,用户名MOTHER.FUCKER\Administrator
以及client的地址信息(hostname)
0x3.1.2 KRB-ERROR
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)
client选定加密类型23(RC4),将当前时间戳加密封装到PA-ENC-TIMESTAMP
结构中
在req-body中指定票据申请者(MOTHER.FUCKER\Administrator
)和要申请的票据([email protected]
)
0x3.1.4 AS-REP
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
TGT票据以及认证数据authenticator都在padata字段中——PA-TGS-REQ
TGT票据就是AS阶段返回的票据,原封不动放在这里
authenticator字段为使用c-d-skey加密的数据,解密如下:
可以看到authenticator字段中包含了票据申请者MOTHER.FUCKER\Administrator
,这个必须要和TGT票据中的用户是一致的,不然会导致认证失败,同时也是为了防止冒充用户
req-body中主要的字段就是sname,指定了申请的票据的SPNCIFS/WIN-37U50GQO8KT.MOTHER.FUCKER
0x3.2.2 TGS-REP
返回一个CIFS票据和enc-part
enc-part字段由c-d-skey加密,解密后内容如下:
最重要的字段依然是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
这个数据包是在445端口捕获的,kerberos协议的ap-req被封装在SPNEGO数据包中
你可以将SPNEGO理解为一个用于将应用协议和认证协议分离开来的一种协议
在本例中,SPNEGO将smb协议和kerberos协议分离开来
在ap-req中,ticket字段为TGS阶段获取的票据,原封不动放在这里
authenticator中包含客户端身份信息,使用c-s-skey加密
0x3.3.2 AP-REP
在本例中,并不存在AP-REP数据包,只是在SPNEGO中返回了accept-completed
代码,表示smb会话建立成功
在实际应用中,AP-REP只有在client在AP-REQ的authenticator字段提供了sub-key时候才会被返回,表明是否采用client提供的sub-key,或者向client返回自己选择的sub-key,用于后续的通信加密
0x4 结语
如果有不对的地方,希望能指出来,谢谢
今天是大年初五——破五,你们都吃饺子了吗?