Windows内网协议学习Kerberos篇之PAC( 二 )

0x0000000A PACCLIENTINFO
客户端Id(8个字节):

  • 包含在Kerberos初始TGT的authtime
NameLength(2字节)
  • 用于指定Name 字段的长度(以字节为单位) 。
Name
  • 包含客户帐户名的16位Unicode字符数组,格式为低端字节序 。
0x00000006和0x00000007
0x00000006 对应的是服务检验和,0x00000007 对应的是KDC校验和 。分别由server密码和KDC密码加密,是为了防止PAC内容被篡改 。
存在签名的原因有两个:
首先,存在带有服务器密钥的签名,以防止客户端生成自己的PAC并将其作为加密授权数据发送到KDC,以包含在票证中 。
其次,提供具有KDC密钥的签名,以防止不受信任的服务伪造带有无效PAC的票证 。
两个都是PACSIGNATUREDATA结构,他包括以下结构 。
  1. SignatureType(4个字节)
类型含义签名长度0xFFFFFF76KERBCHECKSUMHmac_MD5160x0000000FHMACSHA196_AES128120x00000010HMACSHA196_AES25612
  1. Signature
包含校验和 。签名的长度由SignatureType字段的值确定
  1. RODCIdentifier(2个字节):
当KDC为RODC时,包含密钥版本号的前16位 。
当KDC不是RODC时,此字段不存在 。
 
三.相关安全问题1. MS14068
补丁编号是KB3011780,域里面最严重的漏洞之一,它允许任意用户提升到域管权限 。下面简要分析下该漏洞 。
该漏洞最本质的地方在于Microsoft Windows Kerberos KDC无法正确检查Kerberos票证请求随附的特权属性证书(PAC)中的有效签名,这里面的签名就是上面提到的服务检验和以及KDC校验和 。
导致用户可以自己构造一张PAC 。
 
签名原本的设计是要用到HMAC系列的checksum算法,也就是必须要有key的参与,我们没有krbtgt的hash以及服务的hash,就没有办法生成有效的签名,但是问题就出在,实现的时候允许所有的checksum算法都可以,包括MD5 。
那我们只需要把PAC 进行md5,就生成新的校验和 。
 
这也就意味着我们可以随意更改PAC的内容,完了之后再用md5 给他生成一个服务检验和以及KDC校验和 。
在MS14-068修补程序之后,Microsoft添加了一个附加的验证步骤,以确保校验和类型为KRBCHECKSUMHMAC_MD5 。
在KERBVALIDATIONINFO结构里面,我们看到有这两个字段 。
Windows内网协议学习Kerberos篇之PAC

文章插图
 
其中GroupId是用户所在所在的组,那只要我们把重要组(比如域管组)的sid加进GroupId 。
那么服务拿这用户的TGS去询问域管用户是否有访问访问改服务的权限的时候,域控会解密PAC,提取里面用户的sid,以及所在的组(GroupId),我们已经把域管加进去了,是的域控把把这个用户当做域管组里面的成员 。
从而达到提升为域管的效果 。
pykek加入的是以下组,
  • 域用户(513)
  • 域管理员(512)
  • 架构管理员(518)
  • 企业管理员(519)
  • 组策略创建者所有者(520)
现在我们已经能够伪造pac,将我们放在域管的组里,然后伪造检验和 。但是即使用户可以伪造PAC 。
该漏洞的利用依旧还有一个棘手的问题 。
 
前面我们说过
PAC是包含在TGT里面的,而TGT是krbtgt的用户hash加密的,也就意味着即使我们可以伪造PAC,那我们有什么办法讲PAC放在票据里面传输给KDC呢 。
 
漏洞的作者用了一个很巧妙的方式!
通过查看pykek的源码发现,作者将PAC加密成密文放在enc-authorization-data里面,enc-authorization-data的结构如下
AuthorizationData::= SEQUENCE OF SEQUENCE {ad-type[0] Int32,ad-data[1] OCTET STRING}ad-type是加密算法 ad-data是pac加密后的内容 加密用的key是客户端生成的 。
 
KDC并不知道这个key
KDC会从PA-DATA里面的APREQ获取到这个key
从而对ad-data进行解密,然后拿到PAC,再检查校验和 。
可能很多人抓包,在APREQ里面并没有找到这个key 。
Windows内网协议学习Kerberos篇之PAC

文章插图
 
只是说了TGT票据就放在这个结构体里面
这里补充介绍下:
APREQ的type是PADATATYPE.AP_REQ(INTEGER 1)
Windows内网协议学习Kerberos篇之PAC

文章插图
 
value是如下结构体
AP-REQ ::= [APPLICATION 14] SEQUENCE {pvno [0] INTEGER (5),msg-type [1] INTEGER (14),ap-options [2] APOptions,ticket [3] Ticket,authenticator [4] EncryptedData -- Authenticator}


推荐阅读