zoukankan      html  css  js  c++  java
  • Kerbors与PAC

    简介

    在Kerberos认证中的客户端与server中,仅向server证明了客户端就是客户端,但server并不知道客户端到底能够访问哪些资源。
    
    域环境中若要知道某个用户具备哪些权限,需要提供相关sid及组sid,server仅信任KDC提供的用户具备哪些权限,KDC必须告知server关于用户的权限,这样经过验证后server才可划分正确的资源提供给目标用户,因此,在TGT中增加的用户的PAC(特权属性证书),也就是用户的权限的说明,包括其sid及组sid,如下图,PAC应放在TGT内。
    

    PAC对用用户与server应该都是看不到的,全程只有KDC可进行查看与制作,此处引用网络上的图片,如下图,为了防止KDC被篡改,在PAC的尾部增加了server signature与KDC signature进行签名校验
    

    微软中将PAC放在TGT中加密后从AS经过用户中转给TGS,再由TGS返回的ticket加密后经过用户返回给server
    

    关注点:
    在KRB_TGS_REQ阶段,携带PAC的TGT被TGS服务接收后,认证A的合法性后(解密Authenticator符合要求)会将PAC解密出来,验证尾部两个签名的合法性,如果合法则认为PAC没有被篡改,于是重新在PAC的尾部更换了另外两个签名,一个是Server Signature,这次是以Server-B的密码副本生成的签名(因为对于Client-A和Server-B,这次的第三方机构是TGS服务),另外一个是KDC Signature,这次不再使用KDC的长期有效的Key,而是使用在AS阶段生成的短期有效的SessionKeya-b,(网上说的是第二个签名仍旧是KDC Key,但如果用KDC中krgtgt账号密码生成签名,最后转发给Server-B后,由于没有krbtgt的密码而无法验证第二个签名的正确性,所以这里用SessionKeya-b生成签名才是合理的,或许这里理解错了,敬请指出)最终成为New Signed PAC被拷贝在ServericeTicket中被加密起来
    

    MS14068

    该漏洞是密钥分发中心(KDC)服务中的Windows漏洞。它允许经过身份验证的用户在其Kerberos票证(TGT)中插入任意PAC(表示所有用户权限的结构)。该漏洞位于kdcsvc.dll域控制器的密钥分发中心(KDC)中。用户可以通过呈现具有改变的PAC的Kerberos TGT来获得票证,说白点可以提到管理权限进一步连接域控资源。
    

    漏洞利用

    本地域用户登录域成员机器,确认无法获得域控资源:
    

    获得域sid:
    

    本地管理员登录机器,确认无法获得域控资源:
    

    exe打一遍并当前确认没有票据,票据文件已生成在左下角:
    

    票据文件放入mimikatz同目录,mimikatz注入票据:
    

    此时无需输入账户密码即可连接域控,访问资源:
    

    深入分析相关细节

    使用工具攻击时的数据包:
    

    cname信息如下:
    

    mimikatz注入票据后,连接域控的数据包,这里可以发现两种情况,1.缺少AP-REQ、AP-REP,2.出现两次的TGS-REQ及TGS-REP:
    

    关注点一

    翻了会数据包发现了SMB的第一个request包内包含了AP-REQ:
    

    同理SMB的包内拥有kerberos的AP-REQ:
    

    关注点二

    查看工具源码,使用current_time与key构造了用于提交给AS的Authenticator,另外增加了一个false的include-PAC:
    

    数据包内同样可以看得到,设置为了false,那么AS-REP返回的TGT中将不会包含PAC:
    

    根据Kerberos,KDC返回的数据包应含有用krbtgt用户hash加密后的TGT票据及用户hash加密的 login session key,代码中如下:
    

    构造PAC放入TGS-REQ内:
    

    构造PAC时,截取域用户SID:
    

    通过sid构造高权限的用户:
    

    关于后门两个chksum的构造:
    

    对于这里的chksum构造,不需要key的md5构造前面,意味着只要先前的data(user&group sid),接着对数据进行md5,生成一个32位MD5即可
    
    针对server对于md5前面进行验证,server只需将data进行md5运算,若md5值与后边签名一直,则认为该签名可以通过
    
    微软对PAC尾部的签名原理上需要带有server key与kdc key才可通过,但实现上却允许只要客户端指定算法那么kdc就会使用指定算法进行签名
    
    所以该脚本不需要key的md5签名,只要构造的user&group sid信息在传输过程中不改变,那么服务端则能够通过校验
    
    针对PAC应放在TGT内,但include-PAC为false后,AS-REP得到的TGT是不带PAC信息的,这里PAC放在了TGS-REQ内,同样KDC能够解析没有放在正确位置的PAC信息
    
    构造TGS-REQ:
    

    查看数据包:
    

    确认PAC信息在req-body内,TGT在前面的padata内,说明TGT未携带PAC信息,且标志位false:
    

    查看源码继续看subkey,确认为生成的随机数,此处脚本为了使得KDC能够解密PAC信息,将生成的随机数放如TGS-REQ的authenticator一同发送给KDC,KDC能够识别用户算法,并正确解密,确认通过PAC信息:
    

    构造TGS-REP:
    

    根据Kerberos协议得login session key加密的service session key与ST,此处利用过程中KDC从authenticator提取了subkey解密了PAC信息,利用客户端设定的签名算法验证了签名,同时将另外的 TGT 进行解密得到 session key。验证成功后,KDC 在解密的 PAC 信息的尾部,重新采用自己的 server Hash 和 KDC Hash 生成一个带 Hash 的签名,把 server session key 用 subkey 加密,组成一个新的 TGT 返回给 client
    
    最终,这个TGT和server session key制作成了ccache票据
    
    最可疑点
    在 KDC 对 PAC 进行验证时,根据协议规定必须是带有 server Hash、KDC Hash 的签名算法才可以(原本的设计是 HMAC 系列的 checksum 算法),但微软在实现上,却允许任意签名算法。只要客户端指定任意签名算法,KDC 就会使用指定的算法进行签名验证。
    
    PAC 没有被放在 TGT 中,而是放在了 TGS_REQ 数据包的其他地方,根据协议规定 KDC 无法解析,但这里它却很神奇地解析了:说明 KDC 能够正确解析出没有被放在正确位置的 PAC。
    
    按照 pykek 的方法构造 TGS_REQ 数据包然后发送,KDC 会从 Authenticator 里提取出 subkey(客户端生成的随机数)来解密 PAC,然后利用客户端设定的签名算法来验证签名,同时将 TGT 进行解密得到 session key。验证成功后,在 PAC 信息的尾部重新采用自身的 server Hash 和 KDC Hash 生成一个带 Hash 的签名,把 server session key 用 subkey 加密,组合成新的 TGT 返回给 client,而不是 Ticket。
    
    参考
    https://www.freebuf.com/vuls/56081.html
    
  • 相关阅读:
    Ping
    boost::python开发环境搭建
    mingw和libcurl
    ssh远程执行命令使用明文密码
    netty源码阅读之UnpooledByteBufAllocator
    Direct ByteBuffer学习
    clions的使用
    netty中的PlatformDependent
    STL之priority_queue(优先队列)
    c++线程调用python
  • 原文地址:https://www.cnblogs.com/Yang34/p/14248766.html
Copyright © 2011-2022 走看看