数据包下载位置: 链接
在 Kerberos 的连接中,我们可以大致简单的分为: AS_REQ&AS_REP、TGS_REQ&TGS_REP
AS_REQ&AS_REP
1. AS_REQ

Pvno kerberos协议版本号:05(Hex)
5MSG-TYPE 类型 AS_REQ对应(krb-as-req)0a(Hex)
PA-DATA 预认证信息数据 一个列表,包含若干个认证消息用于认证,每个认证消息有type和value。
AS_REQ 阶段主要用到的有两个
1.ENC_TIMESTAMP
这个是预认证,就是用用户hash加密时间戳,作为value 发送给AS服务器。然后AS服务器那边有用户hash,使用用户hash进行解密,获得时间戳,如果能解密,且时间戳在一定的范围内,则证明认证通过。
2.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
1.cname
PrincipalName 类型。PrincipalName包含type和value。
KRB_NT_PRINCIPAL = 1 means just the name of the principal 如daizhibin
KRB_NT_SRV_INST = 2 service and other unique instance (krbtgt) 如krbtgt,cifs
KRB_NT_ENTERPRISE_PRINCIPAL = 10 如 user@domain.com
在AS_REQ里面cname 是请求的用户,这个用户名存在和不存在,返回的包有差异,可以用于枚举域内用户名。
2.sname
PrincipalName 类型,在AS_REQ里面sname是krbtgt,类型是KRB_NT_SRV_INST
每个域控制器DC都有一个kebtgt的用户账户,此账户是KDC的服务账户用来创建票据授予服务(TGS)加密的密钥
3.realm 域名
4.from 发送时间
5.till 到期时间
原文中的到期时间说可以作为流量监测,但是我在本地抓包时发现,win2008r2默认的到期时间即为文章中说的值,所以无法作为流量监测判定依据
6.nonce
随机生成的一个数kekeo/mimikatz nonce是12381973,rubeus nonce是1818848256,这个也可以用来作为特征检测工具。
这里是原文说的,https://www.anquanke.com/post/id/190261
但是我在本地测试时候发现,mimikatz并不会直接触发kerberos认证,pth也是注入到内存,触发的时候nonce还是走的本地,并不会涉及到mimikatz的nonce,而rubeus的nonce已经修复https://github.com/GhostPack/Rubeus/issues/34
7.etype
加密类型
这个地方要注意的是如果在配置里面选择用hash(不是plaintext)的话,hash的加密类型,要跟etype一样。因为KDC是按照etype类型选择用户对应加密方式的hash,如果是选择明文(plaintext),那么client 会按照etype里面的加密方式将明文加密成hash
AS获取用户名之后,获取对应的ntlm
值,通过加密的方法加密数据信息,并且验证时间戳,之后生成随机字符串Session Key
,使用用户的ntlm值加密Session Key
,使用krbtgt
用户的ntlm
加密Session Key
和客户端信息,一起返回客户端
Send=user_NTML_Hash(Session Key)+krbtgt_NTML_Hash(Session Key+client_info1)[TGT]
关于 AS_REQ 抓包还存在一种情况:不存在pA-ENC-TIMESTAMP
字段的
2. AS-REP
1. 用户名和密码正确
2. 用户名不正确 (第一个包)
3. 用户名正确 (第二个包)
4. 密码不正确 (只有第一个包,没有第二个包)
这里可以看到首先发送一个不带密码的AS-REQ,判断用户名是否正确,之后再发送一个带密码的AS-REQ,来判断是否通过认证
我们可以通过第一步判断用户名的包进行一个用户枚举,通过返回值的不同来进行爆破
客户端在收到AS-REP
之后使用ntlm
解密获得Session Key
,使用Session Key
加密客户端信息和时间戳,连同TGT
发送给TGS
Send=Session Key(time+client_info2)+krbtgt_NTML_Hash(Session Key+client_info1)[TGT]
TGS_REQ&TGS_REP
1. TGS_REQ
TGS
接受到数据后,使用krbtgt
的ntlm
解密tgt
,获得Session Key
,使用Session Key
解密获得client_info2
和time
,对比tgt
当中的clinet_info1
和time
,通过验证之后,TGS
发送票据给客户端
Send=Server_Hash(Server Session Key+Client_info+time)[Trick]+Session key(Server Session Key)
这里有个问题,为什么要来回发送这个tgt,反正AS和TGS都在域控内,
- 因为服务器少于客户端,如果每个tgt都存在服务器内,需要进行一个映射表,产生开销
- 在AS和TGS内部传输可能存在一些问题
- req-body
padding:0
kdc-options:用于与KDC约定一些选项设置
realm:域名
sname:这里是要请求的服务
till:到期时间
(参考的文章说到期时间为20370913024805Z为mimikatz的特征,)这里抓包验证一下,win2008默认也是这个特征,这是个伪命题
nonce:随机生成数
etype:加密类型
2. TGS_REP
客户端使用Session key
解密Server Session Key
,向服务端提交请求,并提供Ticket
和Server Session key
加密的客户端信息与时间戳 ,与服务器进行通信。通过认证后Ticket会一致在客户端内存中。
Send=Server_Hash(Server Session Key+Client_info+time)[Trick]+Server Session Key(Client_info2+time)
1. S4U2SELF
S4U2self 使得服务可以代表用户获得针对服务自身的kerberos服务票据。这使得服务可以获得用户的授权( 可转发 的用户TGS票据),然后将其用于后期的认证(主要是后期的s4u2proxy),这是为了在用户以不使用 Kerberos 的方式对服务进行身份验证的情况下使用。这里面很重要的一点是服务代表用户获得针对服务自身的kerberos票据这个过程,服务是不需要用户的凭据的,其中转发这部分主要是委派使用,
2. S4U2PROXY
s4u2proxy 使得服务1可以使用来自用户的授权( 在S4U2SELF阶段获得),然后用该TGS(放在AddtionTicket里面)向KDC请求访问服务2的TGS,并且代表用户访问服务2,而且只能访问服务2。