kerberos认证原理
Windows密码存储形式
了解kerberos协议前我们得先了解Windows系统的密码是保存在%SystemRoot%\system32\config\sam
这个路径下的,当我们登录系统时,系统会自动读取SAM文件内的NTLM哈希值与我们输入密码的哈希值进行比对,相同则认证成功。
什么是NTLM
Windows NT LAN Manager(NTLM)是一种质询-响应身份验证协议,用于对Active Directory域上的资源的客户端进行身份验证。当客户端请求访问与该域关联的服务时,该服务会向客户端发送质询,要求客户端使用其身份验证令牌执行数学运算,然后将该操作的结果返回给服务。该服务可以验证结果或将其发送到域控制器(DC)进行验证。如果服务或DC确认客户端的响应正确,则该服务允许访问客户端。
NTLM(NT LAN Manager) hash
NTLM Hash是支持Net NTLM认证协议及本地认证过程中的一个重要参与物,其长度为32位,由数字和字母组成。现在的Windows基本上都使用的是NTLMv2这个版本的协议。
本地认证流程
Windows Logon Process是Windows NT用户登录程序,用于管理用户登录和退出。LSASS用于微软Windows系统的安全机制。它用于本地安全和登录策略。以下为本地认证的流程图
挑战(Challenge)/响应(Response)
第一步是两台操作系统之间先进行协商,因为有一些旧版本的系统如Windows Server2003和xp等是只支持LM协议的,并不支持NTLM协议,因此第一步要做的事是确认服务器的协议版本是v1还是v2。
第二步是质询。客户端向服务端发送用户信息请求,服务端接收到请求后,生成一个16位的随机字符,被称为Challenge
,使用登录用户名对应的NTLM Hash加密Challenge,生成Challenge1。同时生成Challenge1后,将Challenge发送给客户端。总的来说Net NTLM Hash = NTLM Hash(Challenge)
。
接着客户端接收到Challenge后,使用将要登录到账户对应的NTLM Hash加密Challenge生成的Response,然后将Response发送给服务端。服务端接收到客户端发来的Response后,比对Challenge1与Response是否相等,若相等则通过认证。
NTLM挑战/响应验证机制
我们可以根据下图演示NTLM的认证过程
- Server接收到Client发送的用户名后,判断本地账户列表是否有用户名share_user,如果没有,返回认证失败。
- 如果有,生成Challenge,并且从本地查找share_user对应的NTLM Hash,使用NTLM Hash加密Challenge,生成一个Net-NTLM Hash存在内存中,并将Challenge发送给Client。
- Client接收到Challenge后,将自己提供的share_user的密码转换为NTLM Hash,使用NTLM Hash加密Challenge,这个结果叫Response,表现形式是Net-NTLM Hash,最后将Response发送给Server。
- Server接收到Client发送的Response,将Response与之前的Net-NTLM Hash进行比较,如果相等,则认证通过。
- 注意:Challenge是Server产生的一个16字节的随机数,每次认证都不相同。Response的表现形式是Net-NTLM Hash,它是由客户端提供的密码Hash加密Server返回的Challenge产生的结果。
NTLM协议版本区别
NTLM v1与NTLM v2最显著的区别就是Challenge与加密算法不同,共同点就是加密的原料都是NTLM Hash。
Challenge: NTLM v1的Challenge有8位,NTLM v2的Challenge为16位。
Net-NTLM Hash: NTLM v1的主要加密算法是DES,NTLM v2的主要加密算法是HMAC-MD5
Pass The Hash及必要条件
Pass The Hash
在内网渗透中,我们经常会需要抓取管理员的密码、NTLM Hash,通过搜集这些信息有助于我们扩大战果,尤其是在域环境下。
哈希传递是能够在不需要账户明文密码的情况下完成认证的一个技术。
哈希传递解决了我们渗透中获取不到明文密码、破解不了NTLM Hash而又向扩大战果的问题。
必要条件
- 哈希传递需要被认证的主机能够访问到服务器
- 哈希传递需要被传递认证的用户名
- 哈希传递需要被传递认证用户的NTLM Hash
Kerberos所参与的角色
- Client
- Server
- KDC(Key Distribution Center) = DC
什么是KDC
- DC(account database):存储所有client的白名单,只有存在于白名单的client才能顺利申请到TGT票据。
- Authentication Service:为client生成TGT的服务。
- Ticket Granting Service:为client生成某个服务的ticket。
- KDC:KDC其实是一种服务框架,框架中包含一个 KRBTGT 账户,它是在创建域时系统自动创建的一个账号,你可以暂时理解为他就是一个无法登陆的账号,在发放票据时会使用到它的密码 HASH 值。
- AD:AD其实是一个类似于本机SAM的一个数据库,全称叫account database。
域认证粗略流程
- client向kerberos服务请求,希望获取访问server的权限。kerberos得到这个消息,首先判断client是否是可信赖的,也就是白名单黑名单的说法。这就是AS服务器完成的工作,通过在AD中存储黑名单和白名单来区分client。
- 成功后,返回AS,返回TGT给client。
- client得到了TGT后,继续向kerberos请求,希望获取访问server的权限。
- kerberos又得到这个消息,这时候通过client消息中的TGT,判断出了client拥有了这个权限,给了client访问server的权限,也就是ticket票据。
- client得到ticket后,终于可以成功访问server。这个ticket只是针对这个server,其它server需要向TGS申请。
Kerberos域认证体系
kerberos是一种网络认证协议,其设计目标是通过密钥系统为客户机 / 服务器应用程序提供强大的认证服务。该认证过程的实现不依赖于主机操作系统的认证,无需基于主机地址的信任,不要求网络上所有主机的物理安全,并假定网络上传送的数据包可以被任意地读取、修改和插入数据。在以上情况下,kerberos作为一种可信任的第三方认证服务,是通过传统的密码技术(共享密钥)执行认证服务的。
域认证详细流程
第一步:Session Key与Ticket Granting Ticket
- 首先我们的客户端先向KDC域控发送我们的身份信息,里面包含着账户名和计算机名。
- 然后发送过去之后,KDC要验证发送的用户名和计算机名是否在自己的AD里。
- 倘若认证通过,KDC就会返回两个hash值,一个是客户端登陆username的NTLM Hash加密一个session key(KDC 随机生成的字符),另一个是TGT(KDC的hash加密一个客户端和session key的信息),KDC Hash是AD某个特殊的用户(krbtgt)对应的hash。
详细剖析包含内容
首先客户端会向KDC发送一个KRB_AS_REQ这样一个请求,这个请求中就包含了三个内容。第一个是被客户端哈希加密的一个时间戳,用于KDC验证客户端身份的;第二个是客户端的一些基本信息,如用户名、计算机名、地址之类的信息,KDC以此来查找客户端的hash值;第三个是请求服务端的TGS相关的信息。最后打包好一并发送给KDC进行验证。
下面我们来看看回应的过程
在验证后,KDC会返回一个KRB_AS_REP回应,里面包含了两个内容,一个是Client Hash,是被Client Hash加密的Session Key,用于后续与TGS服务通信,这个是由AS返回的;另一个是我们的TGT(用于向TGS申请票据的凭证)。TGT包含了Session Key、客户端名(域名、域客户端)、到期时间(时间戳)。当这个KRB_AS_REP发送到客户端时,客户端能够解密Client Hash,但是没有KDC的hash,所以不能解密TGT,但是它依然能和TGS通信,那将进入域认证的第二步。
第二步:Session Key与Ticket
在第一步中客户端自己解密出来的Session Key加密客户端的信息和时间戳信息,还有部分的服务端信息,然后发送给KDC,接着KDC的TGS进行认证,然后TGS根据KDC的hash解密TGT。这里解释下为什么首先解密TGT,因为KDC里没有session Key,而TGT里有session key,它通过自己的TGT Hash解密出来session key,然后通过session key解密客户端包装的信息,解密出来时间戳,比对这个时间戳是否跟当时时间相差太久,若是,则认为不安全并且重新认证,因为kerberos认为如时间相差太久,这个数据包就有可能是攻击者伪造出来的。当TGS解密出来的session key里的客户端信息与前面第一步中的session key里的客户端信息进行比对,若相等,则认证通过。与此同时TGS还要判断客户端是否具有权限访问服务端对应的某个服务。
认证通过后又会返回一个数据包给客户端,首先它会返回一个一直在使用的session key去加密某个server session key,这个server session key是KDC又生成了一个随机字符,这个随机字符和session key在表现形式上一样,但是生成的结果不同,因为是在不同的时间生成的随机数,这个server session key是客户端和服务端用于通信的重要的一个session key,若没有,则无法进行下面的认证。接着KDC会提取server info的信息,里面包含了服务器的计算机名,KDC根据计算机名去提取对应的hash值去加密这个ticket。
以下为Ticket的结构内容
其实这个过程中和我们刚才AS返回的TGT的结构是相同的,唯一不同的是Ticket里面的是Server Session Key而TGT里面的是Session Key。当客户端获得这个数据包后,因为客户端有Session Key,所以它能够解密出Server Session Key,但是不能解密出Ticket。
第三步:Server Session Key与Ticket
最后客户端要发送一个KRB_AP_REQ数据包和Server进行通信,客户端无法解密Ticket,但是有Session Key,能够解密出Server Session Key,因此开启构造数据包,使用Server Session Key加密客户端信息和时间戳发送给服务端。那么当数据包到达服务端后,服务端有自己的hash,所以首先解密Ticket,而Ticket里包含了我们的Server Session Key,然后再通过Server Session Key能够解密出客户端和时间戳,然后进行校验来源的客户端和Ticket的客户端是否相等。同时它还要判断时间戳是否大于阈值,还有要判断Ticket的到期时间。
总结
其实整个Kerberos认证的流程中,TGT和Ticket的结构是相同的,只是Server Session Key和Session Key是不同的,而Session Key是AS给客户端的,Server Session Key是TGS给客户端的。整个认证流程的本质是不停地交换密钥,然后采用对称加密算法,不停地校验时间戳和身份来完成的一个安全认证。
参考文章
https://blog.csdn.net/sky_jiangcheng/article/details/81070240