域渗透学习(一)Windows身份认证

Kerberos认证协议

上一篇提到了域内身份认证是采用的Kerberos协议,那么具体的认证流程是怎样的?

需要了解的几个概念

  • KDC(Key Distribution Center):密钥分发中心,里面包含两个服务:AS和TGS
  • AS(Authentication Server):身份认证服务
  • TGS(Ticket Granting Server):票据授予服务,该服务提供的票据也称为 TGS 或者叫白银票据
  • TGT(Ticket Granting Ticket):由身份认证服务授予的票据(黄金票据),用于身份认证,存储在内存,默认有效期为10小时

关于下文需要记住的一些点

Client 密钥 TGS密钥 和 Service 密钥 均为对应用户的NTLM Hash

TGS密钥 == KDC Hash == krbtgt用户的NTLM Hash,这几个可能有时候叫法不一样但是是一个东西

Server 和 Service 也可以当作一个东西,就是Client想要访问的服务器或者服务

Client/(TGS/Server) Sessionkey 可以看作客户端与TGS服务和尝试登陆的Server之间会话时用来加密的密钥,而(Client/TGS/Service)密钥(上面提到的三个实际为NTLM Hash的密钥)是用来加密会话密钥的密钥,为了保证会话密钥的传输安全,这些加密方式均为对称加密

也就是说,参与认证的三个角色的NTLM Hash是三个密钥,这三个NTLM Hash的唯一作用是确保会话密钥Sessionkey的安全传输

后面的描述可以看完具体认证流程再回来看

然后Service 和 TGS 通过对TGT 和 Ticket (TGT 和 Ticket中包含会话密钥Sessionkey和客户端的身份信息)使用自己的NTLM Hash进行解密获取到会话密钥,再使用这个会话密钥解密客户端通过这个会话密钥加密发来的验证信息

通过解密客户端发来的验证信息,可以得到客户端的身份验证信息,再与使用自己的NTLM Hash进行解密TGT或者Ticket得到的客户端身份信息进行比较来完成对客户端身份的验证

TGT或Ticket 是由KDC使用TGS密钥和Service密钥进行加密的(上文讲到KDC可以从AD数据库中提取这三个东西),但是Client因为没有这两个密钥所以无法解密与修改。KDC将一份会话密钥通过Client的密钥加密发送给Client,另一份放在TGT中和客户端身份信息一起通过TGS的密钥进行加密也发送给Client

Client可以使用自己的密钥解密第一份会话密钥,然后用这个会话密钥来加密一份自己的身份信息,再把加密的身份信息和TGT一起发送给KDC,KDC此时如果能使用自己的TGS密钥来成功解密TGT,说明这个TGT是可信任的,因为Client无法修改TGT,然后再用这个TGT中的会话密钥来解密客户端发来的身份信息,与解密TGT得到的身份信息进行比对,如果能成功解密并且比对成功,说明这个Client是可信任的

Server端认证跟上面是一样的

再说个更简单易懂的例子(编个故事):戏说地狱三头犬

1.用户登陆

  • 用户输入 [用户名][密码] 信息
  • 在客户端,用户输入的 [密码] 通过计算生成NTLM哈希作做为 [Client密钥]

2.请求身份认证

2.1 客户端向AS(身份认证服务)发送认证请求

  • 客户端向AS发送认证请求,请求中带有明文的 [用户名] 信息

此时并未发送[密码]或[密钥]信息

2.2 AS确认Client端登录者用户身份

  1. AS收到用户认证请求之后,根据请求中的 用户名 信息,从数据库中查找该用户名是否存在。

  2. 如果 用户名 存在,则根据该用户名提取NTLM Hash做为AS生成的Client 密钥,如果第1步中用户提供的 密码 信息正确,该秘钥与用户登录中的 Client密钥 是相等的。

  3. AS为Client响应如下消息:

    • Msg A 使用 KDC生成的Client密钥 加密的Client/TGS SessionKey
    • Msg B 使用 TGS密钥 加密的**TGT(Ticket-Granting-Ticket)**,客户端没有KDC NTLM Hash因此Client无法解密TGT。
      TGT中包含如下信息:
      • [Client/TGS SessionKey]
      • Client ID
      • Ticket有效时间
      • CLient 地址
  4. Client收到AS的响应消息以后,利用自身的 Client密钥 可以对Msg A进行解密,这样可以获取到 Client/TGS SessionKey 。但由于Msg B是使用 TGS密钥 加密的,Client无法对其解密。

  • AS响应的消息中有一条是属于Client的,但另外一条却属于TGS。
  • Client/TGS SessionKey出现了两个Copy,一个给Client端,一个给TGS端。
  • 认证过程中的加密除哈希外均采用的是对称加密算法。

3. 请求服务授权

3.1 客户端向TGS发送请求服务授权请求

客户端发送的请求中包含如下两个消息:

  • Msg C
    • 要请求的服务ID, 即[Service ID]
    • 上一步2.2中由AS为Client提供的TGT。
  • Msg D
    • 使用 Client/TGS SessionKey 加密的Authenticator 1 {Client ID, Timestamp}。

KDC接收到TGT与其他内容后,会首先使用KDC 的NTLM Hash解密TGT,只有KDC可以解密TGT,从TGT中提取到 Client/TGS SessionKey ,再使用 Client/TGS SessionKey 解密Authenticator 1,获取到{Client ID, Timestamp} 并与通过解密TGT获取到的{Client ID, 有效时间}进行对比

3.2 TGS为Client响应服务授权票据

TGS为Client响应的消息包括:

  • Msg E 使用 Service密钥(服务器的NTLMHash) 加密的 Client-To-Server Ticket , 该Ticket中包含了如下信息:

    • [Client/Server SessionKey]
    • Client网络地址
    • Ticket有效时间
    • Client ID
  • Msg F 使用 Client/TGS SessionKey 加密的 Client/Server SessionKey

Msg F使用了 Client/TGS SessionKey 加密,因此,该消息对Client可见。Client对其解密以后可获取到 Client/Server SessionKey
而Msg E使用了 [Service密钥] 加密,该消息可视作是TGS给Service Server的消息,只不过由Client一起携带发送给Service Server

4.发送服务请求

4.1 Client向Service Server发送服务请求

发送的消息中包括:

  • Msg E 上一步3.2中,TGS为Client响应的消息Msg E。该消息可以理解为由Client携带的消息。
  • Msg G 由[Client/Server SessionKey]加密的Authenticator 2,包含{Client ID, Timestamp}信息。
  1. Client/Server SessionKey 并非直接传输,而是被包含在使用[Service密钥]加密的Msg E中。
  2. 既然 [Client/Server SessionKey] 并不直接明文传输, Client需要向Service Server证明自己拥有正确的 Client/Server SessionKey ,所以,Authenticator 2使用了 Client/Server SessionKey 加密。

4.2 SS响应Client

SS收到客户端的服务请求之后,先利用自身的 [Service密钥] 对Msg E进行解密,提取出Client-To-Server Ticket, 在3.2步骤中,提到了该Ticket中包含了 Client/Server SessionKey 以及Client ID信息。

SS使用 Client/Server SessionKey 解密Msg G,提取Client ID信息,而后将该Client ID与Client-To-Server Ticket中的Client ID进行比对,如果匹配则说明Client拥有正确的 Client/Server SessionKey

而后,SS向Client响应Msg H(包含使用 Client/Server SessionKey 加密的Timestamp信息)。

Client收到SS的响应消息Msg H之后,再使用 Client/Server SessionKey 对其解密,提取Timestamp信息,然后确认该信息与Client发送的Authenticator 2中的Timestamp信息一致。

如上信息可以看出来,该交互过程起到了Client与SS之间的“双向认证”作用。

认证流程中需要关注的点,票据伪造的原理

  • 2.2 AS确认Client端登录者用户身份

    • KDC返回的Msg B:使用 TGS密钥(KDCHash/krbtgt用户NTLMHash) 加密的TGT(Ticket-Granting-Ticket),当我们获取到krbtgt用户的NTLM哈希后,便可主动使用krbtgt用户的NTLM哈希做为TGS密钥来生成TGT发送给KDC,这样KDC如果通过解密伪造TGT获取到伪造的 [Client/TGS SessionKey] 可以成功解密 Authenticator 1 并完成与TGT中的数据进行比对,便成功骗过了KDC,也就是成功伪造了黄金票据
  • 4.1 Client向SS(Service Server)发送服务请求

    • 客户端向服务器发送的为使用 Service密钥(服务器的NTLMHash) 加密的 Client-To-Server Ticket Ticket中包含用来供服务器解密Authenticator 2的 Client/Server SessionKey 。如果获取到了Service Server的NTLM Hash,便可伪造Ticket,和Authenticator 2 ,Service Server在接收到Ticket和Authenticator 2后可以使用自己的NTLM Hash正常解密完成比对,也就是成功伪造了白银票据

关于Service Hash,Service Hash其实是目标中一个用户名与hostname相同的用户的Hash
如hostname为PC-WIN7的服务器,对应的Hash就是Username : PC-WIN7$的哈希

参考:http://www.nosqlnotes.com/technotes/kerberos-protocol/

⬆︎TOP