深刻理解windows安全认证机制 [ntlm & Kerberos]


0x01 为什么要理解windows 安全认证机制:

1
加深对后续各种漏洞利用的理解深度,还是那句话,要知其然,更要知其所以然,不废话,咱们直接开始

0x02 windows认证协议主要有以下两种:

1
2
基于ntlm的认证方式,主要用在早期的windows工作组环境中,认证的过程也相对比较简单
另一种是基于Kerberos的认证方式,主要用在域环境中,下面就这两种不同的认证方式做些简要的通信流程说明

0x03 关于ntlm认证流程简要说明,如下:
''

0x04 从图中我们可以清晰的看到,ntlm在域中的认证过程主要分为以下几步:

1
2
3
4
5
6
7
第一步,首先在client输入username,password和domain,然后client会把password hash后的值先缓存到本地
第二步,之后,client把username的明文发送给server(DC)
第三步,DC会生成一个16字节的随机数,即challenge(挑战码),再传回给client
第四步,当client收到challenge以后,会先复制一份出来,然后和缓存中的密码hash再一同混合hash一次,混合后的值称为response,之后client再将challenge,response及username一并都传给server
第五步,server端在收到client传过来的这三个值以后会把它们都转发给DC
第六步,当DC接到过来的这三个值的以后,会根据username到域控的账号数据库(ntds.dit)里面找到该username对应的hash,然后把这个hash拿出来和传过来的challenge值再混合hash
第七步,将(6)中混合后的hash值跟传来的response进行比较,相同则认证成功,反之,则失败,当然,如果是本地登录,所有验证肯定也全部都直接在本地进行了

0x05 关于ntlm的一点小结:
    它是一种基于挑战(challenge)/响应(response)消息交互模式的认证过程,从整个认证过程来看,安全确实不怎么到位,也就是说入侵者只需要拿到一个系统管理员的hash,直接给dc认证就好了,反正账户名和域名都知道,早期的pass the hash (psexec)确实就是通过这种方式来进行的,如果本地管理员的账号密码相同,其实不用密码一样可以被认证,我们所要做的就是不断通过这种方式来尝试拓展内网的其他机器,直到控制整个域,但后来的kb2871997,似乎改变了一些现状,但也可能只是似乎

0x06 关于kerberos的一些概述:
    相对于ntlm而言,kerberos的认证方式就要复杂的多,因为它提供了一个集中式的认证方式,在整个认证过程中总共要涉及到三方:客户端,服务端和KDC [Key Distribution Center 密钥分发中心], 在Windows域环境中,KDC的角色由DC(Domain Controller[域控])来担任,Kerberos是一种基于票据的认证方式,票据(Ticket)是用来安全的在认证服务器和用户请求的服务之间传递用户的身份,同时也会传递一些附加信息,用来保证使用Ticket的用户必须是Ticket中指定的用户,Ticket一旦生成,在生存时间内可以被Client多次使用来申请同一个Server的服务(票据窃取问题)

0x07 kerberos的大致工作流程:
    说到这里,我们大概也能明白,域中的客户端要想访问同域中的某个服务器资源时,需要首先购买该服务端认可的票据,也就是说,客户端在访问服务器之前需要预先买好票,等待服务验票之后才能入场,但是这张票不能直接购买,还需要一张认购权证,也就是说客户端在买票之前需要预先获得一张认购权证,这张认购权证和进入服务器的入场券均有KDC发售,下面就以下图来做简要说明:
''

1
2
3
4
5
6
7
8
9
10
11
1)首先,客户端(client)将域用户的密码hash一次并保存,然后,以此hash来作为客户端和KDC之间的长期共享密钥[kc](当然,在DC上也保存着同样的一条hash)
2)之后,客户端(client)开始利用(1)中的域用户密码hash再把时间戳,clientid,TGS id等信息混合hash一次,然后向as(认证服务器 [Authentication Server])服务器进行请求
3)as接到该请求后,利用长期共享密钥(kc)进行解密,解密成功后,会返回给客户端两个票据
(1)加密的K(c,tgs)(用于客户端后续向KDC发起请求),TGS Name/ID,时间戳等,该票据由Kc加密
(2)票据授予票据(Ticket Granting Ticket,简称TGT),该票据是给TGS的,票据的内容包括K(c,tgs),Client身份信息,域名,时间戳等,该票据由TGS的秘钥加密,只有TGS能够解密
4)然后,客户端会利用长期共享密钥解密k(c,tgs),并利用该秘钥加密生成一个Authenticator,内容包括:lifetime,时间戳,Client身份信息等,连同从AS获取的TGT一并发送给TGS
5)TGS利用自身的秘钥解密TGT,获取K(c,tgs),并用K(c,tgs)解密客户端发送的Authenticator,对Client进行认证,如果Client通过了认证,TGS随机生成一个Session Key K(c,s),并产生两个票据
(1)服务票据(Ts):这是给服务器的服务票据,由Server秘钥Ks加密,内容包括:K(c,s),Client身份信息,Service ID,时间戳,lifetime等
(2)客户端票据(Tc):该票据由K(c,tgs)加密,内容包括:K(c,s),Server身份信息等
6)客户端收到tgs的回应后,利用K(c,tgs)解密Tc,获取K(c,s),Server身份信息等,并利用K(c,s)加密生成一个Authenticator发送给Server,内容包括:时间戳,Client ID等信息,连同Ts一并发送给Server
7)Server端在收到Client的请求后,利用自身秘钥Ks解密Ts,得到K(c,s),再利用K(c,s)解密Authenticator,对Client进行认证,如果认证通过,则表示KDC已经允许了此次通信,此时Sever无需与KDC通信,因为Ks为KDC和Sever之间的长期共享秘钥,如果在有效时间内,则此次请求有效

0x08 关于kerberos利用方法:

1) 黄金票据(Golden Ticket)
    先假设这么一种情况,原先已拿到的域内所有的账户hash,包括krbtgt这个账户,由于有些原因导致域管权限丢失,但好在你还有一个普通域用户权限,碰巧管理员在域内加固时忘记重置krbtgt密码,基于此条件,我们还能利用该票据重新获得域管理员权限,利用krbtgt的HASH值可以伪造生成任意的TGT(mimikatz),能够绕过对任意用户的账号策略,让用户成为任意组的成员,可用于Kerberos认证的任何服务

2) 白银票据(Silver Ticket)
    通过观察Kerberos协议的认证过程不难发现,如果我们获取了Server秘钥Ks(服务器口令散列值),就可以跳过KDC的认证,直接伪造票据和目标Server通信

0x09 关于黄金票据和白银票据的一些区别:
1)访问权限不同

1
2
Golden Ticket: 伪造TGT,可以获取任何Kerberos服务权限
Silver Ticket: 伪造TGS,只能访问指定的服务

2)加密方式不同

1
2
Golden Ticket 由Kerberos的Hash加密
Silver Ticket 由服务账号(通常为计算机账户)Hash加密

3)认证流程不同

1
Golden Ticket 的利用过程需要访问域控,而Silver Ticket不需要

小结:
    这些其实都是域内渗透最基础的知识,所以觉得大家还是非常有必要多花点儿时间,好好深刻体会一下,另外,微软给我们的建议是,尽量们不要直接使用NTLM,而使用negotiate,如果使用的是negotiate,windows则会先判断kerberos是否可用,如果可用就优先使用kerberos,否则才会使用NTLM,kerberos的安全性确实要比NTLM要高很多